IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 23268


Ignore:
Timestamp:
Mar 11, 2009, 10:54:22 AM (17 years ago)
Author:
Paul Price
Message:

Adding functionality of reading input files from the configuration dump. This is principally used for ensuring we apply the same detrend images with ppImage that we used originally. Applying this framework to ppImage. Will soon apply to other products. Reworked the pmFPAfileDefineFrom* functions to use common code; I think it still works.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppImage/src/ppImageArguments.c

    r23242 r23268  
    108108
    109109    // the input file is a required argument; if not found, we will exit
    110     bool status = pmConfigFileSetsMD (config->arguments, &argc, argv, "INPUT", "-file", "-list");
    111     if (!status) {
    112         usage ();
    113     }
     110    pmConfigFileSetsMD (config->arguments, &argc, argv, "INPUT", "-file", "-list");
    114111
    115112    // if these command-line options are supplied, load the file name lists into config->arguments
     
    142139        psArgumentRemove(argnum, &argc, argv);
    143140
    144         unsigned int nFail = 0;
    145         psMetadata *normlist = psMetadataConfigRead (NULL, &nFail, argv[argnum], false);
    146         // XXX allow this file to be in nebulous?
     141        unsigned int nFail = 0;
     142        psMetadata *normlist = psMetadataConfigRead (NULL, &nFail, argv[argnum], false);
     143        // XXX allow this file to be in nebulous?
    147144
    148145        psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "NORMALIZATION.TABLE", 0, "Normalization to apply", normlist);
    149         psFree (normlist);
     146        psFree (normlist);
    150147        psArgumentRemove(argnum, &argc, argv);
    151148    }
  • trunk/ppImage/src/ppImageDefineFile.c

    r13562 r23268  
    55# include "ppImage.h"
    66
    7 bool ppImageDefineFile (pmConfig *config, pmFPA *input, char *filerule, char *argname, pmFPAfileType fileType, pmDetrendType detrendType) {
     7bool ppImageDefineFile(pmConfig *config, pmFPA *input, char *filerule, char *argname,
     8                       pmFPAfileType fileType, pmDetrendType detrendType)
     9{
     10    bool status;
     11    pmFPAfile *file = NULL;             // File to be defined
    812
    9     bool status;
    10     pmFPAfile *file;
    11 
    12     // look for the file on the argument list
    13     file = pmFPAfileDefineFromArgs  (&status, config, filerule, argname);
    14     if (!status) {
    15         psError (PS_ERR_UNKNOWN, false, "failed to load find definition");
    16         return false;
     13    if (!file) {
     14        // look for the file on the RUN metadata
     15        file = pmFPAfileDefineFromRun(&status, config, filerule);
     16        if (!status) {
     17            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     18            return false;
     19        }
    1720    }
    18     if (file) {
    19         if (file->type != fileType) {
    20             psError(PS_ERR_IO, true, "%s is not of type %s", filerule, pmFPAfileStringFromType (fileType));
    21             return false;
    22         }
    23         return true;
     21    if (!file) {
     22        // look for the file on the argument list
     23        file = pmFPAfileDefineFromArgs(&status, config, filerule, argname);
     24        if (!status) {
     25            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     26            return false;
     27        }
     28    }
     29    if (!file) {
     30        // look for the file in the camera config table
     31        file = pmFPAfileDefineFromConf(&status, config, filerule);
     32        if (!status) {
     33            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     34            return false;
     35        }
     36    }
     37    if (!file) {
     38        // look for the file to be loaded from the detrend database
     39        file = pmFPAfileDefineFromDetDB(&status, config, filerule, input, detrendType);
     40        if (!status) {
     41            psError(PS_ERR_UNKNOWN, false, "failed to load file definition");
     42            return false;
     43        }
    2444    }
    2545
    26     // look for the file in the camera config table
    27     file = pmFPAfileDefineFromConf  (&status, config, filerule);
    28     if (!status) {
    29         psError (PS_ERR_UNKNOWN, false, "failed to load find definition");
    30         return false;
    31     }
    32     if (file) {
    33         if (file->type != fileType) {
    34             psError(PS_ERR_IO, true, "%s is not of type %s", filerule, pmFPAfileStringFromType (fileType));
    35             return false;
    36         }
    37         return true;
     46    if (!file) {
     47        return false;
    3848    }
    3949
    40     // look for the file to be loaded from the detrend database
    41     file = pmFPAfileDefineFromDetDB (&status, config, filerule, input, detrendType);
    42     if (!status) {
    43         psError (PS_ERR_UNKNOWN, false, "failed to load file definition");
    44         return false;
     50    if (file->type != fileType) {
     51        psError(PS_ERR_IO, true, "%s is not of type %s", filerule, pmFPAfileStringFromType(fileType));
     52        return false;
    4553    }
    46     if (file) {
    47         if (file->type != fileType) {
    48             psError(PS_ERR_IO, true, "%s is not of type %s", filerule, pmFPAfileStringFromType (fileType));
    49             return false;
    50         }
    51         return true;
    52     }
    53     return false;
     54    return true;
    5455}
    5556
  • trunk/ppImage/src/ppImageParseCamera.c

    r21364 r23268  
    99    bool status = false;
    1010
    11     // the input image defines the camera, and all recipes and options the follow
    12     pmFPAfile *input = pmFPAfileDefineFromArgs (&status, config, "PPIMAGE.INPUT", "INPUT");
    13     if (!status || !input) {
    14         psError(PS_ERR_IO, false, "Failed to build FPA from PPIMAGE.INPUT");
    15         return NULL;
    16     }
    17     if (input->type != PM_FPA_FILE_IMAGE) {
    18         psError(PS_ERR_IO, true, "PPIMAGE.INPUT is not of type IMAGE");
    19         return NULL;
    20     }
    21 
    22     // if MASK or VARIANCE was supplied on command line, bind files to 'input'.
    23     // the mask and variance will be mosaicked with the image
    24     pmFPAfile *inputMask = pmFPAfileBindFromArgs(&status, input, config, "PPIMAGE.INPUT.MASK", "PPIMAGE.INPUT.MASK");
    25     if (!status) {
    26         psError (PS_ERR_UNKNOWN, false, "failed to load find definition");
    27         return NULL;
    28     }
    29     if (inputMask) {
    30       if (inputMask->type != PM_FPA_FILE_MASK) {
    31         psError(PS_ERR_IO, true, "PPIMAGE.INPUT.MASK is not of type MASK");
    32         return NULL;
    33       }
    34     }
    35 
    36     pmFPAfile *inputVariance = pmFPAfileBindFromArgs(&status, input, config, "PPIMAGE.INPUT.VARIANCE", "PPIMAGE.INPUT.VARIANCE");
    37     if (!status) {
    38         psError (PS_ERR_UNKNOWN, false, "failed to load find definition");
    39         return NULL;
    40     }
    41     if (inputVariance && inputVariance->type != PM_FPA_FILE_VARIANCE) {
    42         psError(PS_ERR_IO, true, "PPIMAGE.INPUT.VARIANCE is not of type VARIANCE");
    43         return NULL;
    44     }
     11    if (!ppImageDefineFile(config, NULL, "PPIMAGE.INPUT", "INPUT", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_NONE)) {
     12        psError(PS_ERR_IO, false, "Can't find an input image source");
     13        return NULL;
     14    }
     15    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.INPUT"); // Input file
     16    psAssert(input, "We just put it there!");
    4517
    4618    // add recipe options supplied on command line
    47     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, RECIPE_NAME);
     19    psMetadata *recipe  = psMetadataLookupPtr(&status, config->recipes, RECIPE_NAME);
    4820
    4921    // parse the options from the metadata format to the ppImageOptions structure
    50     ppImageOptions *options = ppImageOptionsParse (config);
     22    ppImageOptions *options = ppImageOptionsParse(config);
    5123
    5224    // the following are defined from the argument list, if given,
     
    5426    // not all input or output images are used in a given recipe
    5527    if (options->doBias) {
    56         if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.BIAS", "BIAS", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_BIAS)) {
    57             psError (PS_ERR_IO, false, "Can't find a bias image source");
    58             psFree (options);
     28        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.BIAS", "BIAS",
     29                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_BIAS)) {
     30            psError(PS_ERR_IO, false, "Can't find a bias image source");
     31            psFree(options);
    5932            return NULL;
    6033        }
    6134    }
    6235    if (options->doDark) {
    63         if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.DARK", "DARK", PM_FPA_FILE_DARK, PM_DETREND_TYPE_DARK)) {
    64             psError (PS_ERR_IO, false, "Can't find a dark image source");
    65             psFree (options);
     36        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.DARK", "DARK",
     37                               PM_FPA_FILE_DARK, PM_DETREND_TYPE_DARK)) {
     38            psError(PS_ERR_IO, false, "Can't find a dark image source");
     39            psFree(options);
    6640            return NULL;
    6741        }
    6842    }
    6943    if (options->doMask) {
    70 
    71         if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.MASK", "MASK", PM_FPA_FILE_MASK, PM_DETREND_TYPE_MASK)) {
    72             psError (PS_ERR_IO, false, "Can't find a mask image source");
    73             psFree (options);
    74             return NULL;
    75         }
     44        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.MASK", "MASK",
     45                               PM_FPA_FILE_MASK, PM_DETREND_TYPE_MASK)) {
     46            psError(PS_ERR_IO, false, "Can't find a mask image source");
     47            psFree(options);
     48            return NULL;
     49        }
     50
     51#if 0
     52        // I think this is now done automatically in the pmFPAfileDefine and pmFPAfileIOChecks -- PAP.
     53
    7654        // XXX have ppImageDefineFile return the pmFPAfile?
    7755        pmFPAfile *mask = psMetadataLookupPtr(&status, config->files, "PPIMAGE.MASK");
    78         psAssert (mask, "mask not defined?  not possible!");
     56        psAssert(mask, "Just defined the mask!");
    7957
    8058        // Need to read the names of bit masks from the mask header and set them in the
     
    8462            // XXX need to load the mask bit names from one of the headers
    8563            // this grabs the first available hdu : no guarantee that it will be valid, though
    86             pmHDU *hdu = pmHDUGetFirst (mask->fpa);
     64            pmHDU *hdu = pmHDUGetFirst(mask->fpa);
    8765            if (!hdu) {
    8866                psError(PS_ERR_IO, true, "no valid HDU for PPIMAGE.INPUT.MASK");
     
    9068            }
    9169            // XXX is this consistent with the pmConfigMaskReadHeader call above?
    92             if (!pmConfigMaskReadHeader (config, hdu->header)) {
     70            if (!pmConfigMaskReadHeader(config, hdu->header)) {
    9371                psError(PS_ERR_IO, false, "error in mask bits");
    9472                return NULL;
    9573            }
    9674        }
     75#endif
    9776    }
    9877    if (options->doShutter) {
    99         if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.SHUTTER", "SHUTTER", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_SHUTTER)) {
    100             psError (PS_ERR_IO, false, "Can't find a shutter image source");
    101             psFree (options);
     78        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.SHUTTER", "SHUTTER",
     79                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_SHUTTER)) {
     80            psError(PS_ERR_IO, false, "Can't find a shutter image source");
     81            psFree(options);
    10282            return NULL;
    10383        }
     
    10585
    10686    if (options->doFlat) {
    107         if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.FLAT", "FLAT", PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_FLAT)) {
    108             psError (PS_ERR_IO, false, "Can't find a flat image source");
    109             psFree (options);
    110             return NULL;
    111         }
    112     }
    113 
    114     int nThreads = psMetadataLookupS32 (&status, config->arguments, "NTHREADS");
     87        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.FLAT", "FLAT",
     88                               PM_FPA_FILE_IMAGE, PM_DETREND_TYPE_FLAT)) {
     89            psError(PS_ERR_IO, false, "Can't find a flat image source");
     90            psFree(options);
     91            return NULL;
     92        }
     93    }
     94
     95    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS");
    11596    if (nThreads > 0) {
    116         int nScanRows = psMetadataLookupS32 (&status, recipe, "SCAN.ROWS");
    117         pmDetrendSetThreadTasks (nScanRows);
     97        int nScanRows = psMetadataLookupS32(&status, recipe, "SCAN.ROWS");
     98        pmDetrendSetThreadTasks(nScanRows);
    11899    }
    119100
     
    166147skip_fringe:
    167148    if (options->doFringe) {
    168         if (!ppImageDefineFile (config, input->fpa, "PPIMAGE.FRINGE", "FRINGE", PM_FPA_FILE_FRINGE, PM_DETREND_TYPE_FRINGE)) {
     149        if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.FRINGE", "FRINGE",
     150                               PM_FPA_FILE_FRINGE, PM_DETREND_TYPE_FRINGE)) {
    169151            psError (PS_ERR_IO, false, "Can't find a fringe image source");
    170152            return NULL;
     
    283265        // define associated psphot input/output files
    284266        if (!psphotDefineFiles (config, psphotInput)) {
    285             psError(PSPHOT_ERR_CONFIG, false, "Trouble defining the additional input/output files for psphot");
     267            psError(PSPHOT_ERR_CONFIG, false,
     268                    "Trouble defining the additional input/output files for psphot");
    286269            return false;
    287270        }
     
    291274    if (options->doAstromChip || options->doAstromMosaic) {
    292275        if (!options->doPhotom) {
    293             psError (PSASTRO_ERR_CONFIG, false, "photometry mode is not selected; it is required for astrometry");
     276            psError(PSASTRO_ERR_CONFIG, false,
     277                    "Photometry mode is not selected; it is required for astrometry");
    294278            return false;
    295279        }
    296280
    297         pmFPAfile *psphotOutput = psMetadataLookupPtr (&status, config->files, "PSPHOT.OUTPUT");
    298         PS_ASSERT (psphotOutput, false);
    299 
    300         pmFPAfile *psastroInput = pmFPAfileDefineInput (config, psphotOutput->fpa, NULL, "PSASTRO.INPUT");
    301         PS_ASSERT (psastroInput, false);
     281        pmFPAfile *psphotOutput = psMetadataLookupPtr(&status, config->files, "PSPHOT.OUTPUT");
     282        PS_ASSERT(psphotOutput, false);
     283
     284        pmFPAfile *psastroInput = pmFPAfileDefineInput(config, psphotOutput->fpa, NULL, "PSASTRO.INPUT");
     285        PS_ASSERT(psastroInput, false);
    302286        psastroInput->mode = PM_FPA_MODE_REFERENCE;
    303287
    304288        // define associated psphot input/output files
    305         if (!psastroDefineFiles (config, psastroInput)) {
    306             psError(PSPHOT_ERR_CONFIG, false, "Trouble defining the additional input/output files for psastro");
     289        if (!psastroDefineFiles(config, psastroInput)) {
     290            psError(PSPHOT_ERR_CONFIG, false,
     291                    "Trouble defining the additional input/output files for psastro");
    307292            return false;
    308293        }
    309294
    310295        // deactivate the psastro files, reactive when needed
    311         pmFPAfileActivate (config->files, false, "PSASTRO.OUTPUT");
     296        pmFPAfileActivate(config->files, false, "PSASTRO.OUTPUT");
    312297    }
    313298
     
    325310
    326311    // outImage is used as a carrier: input to chipImage -> require the data to remain at the CHIP level
    327     outImage->freeLevel = PS_MIN (outImage->freeLevel, PM_FPA_LEVEL_CHIP);
     312    outImage->freeLevel = PS_MIN(outImage->freeLevel, PM_FPA_LEVEL_CHIP);
    328313    outImage->dataLevel = outImage->freeLevel;
    329     outImage->fileLevel = PS_MIN (outImage->fileLevel, outImage->dataLevel);
     314    outImage->fileLevel = PS_MIN(outImage->fileLevel, outImage->dataLevel);
    330315
    331316    // outMask and outVariance must be freed at the same level as outImage (all freed by pmFPAFreeData)
     
    342327
    343328    // the input data is the same as the outImage data : force the free levels to match
    344     input->freeLevel = PS_MIN (outImage->freeLevel, input->freeLevel);
     329    input->freeLevel = PS_MIN(outImage->freeLevel, input->freeLevel);
    345330
    346331    // define the binned target files (which may just be carriers for some camera configurations)
    347     pmFPAfile *bin1 = pmFPAfileDefineFromFPA (config, chipImage->fpa, options->xBin1, options->yBin1, "PPIMAGE.BIN1");
     332    pmFPAfile *bin1 = pmFPAfileDefineFromFPA(config, chipImage->fpa, options->xBin1, options->yBin1,
     333                                             "PPIMAGE.BIN1");
    348334    if (!bin1) {
    349335        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.BIN1"));
     
    357343    }
    358344
    359     pmFPAfile *bin2 = pmFPAfileDefineFromFPA (config, chipImage->fpa, options->xBin2, options->yBin2, "PPIMAGE.BIN2");
     345    pmFPAfile *bin2 = pmFPAfileDefineFromFPA(config, chipImage->fpa, options->xBin2, options->yBin2,
     346                                             "PPIMAGE.BIN2");
    360347    if (!bin2) {
    361348        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.BIN2"));
     
    373360    bin2->freeLevel = PM_FPA_LEVEL_FPA;
    374361
    375     pmFPAfile *jpg1 = pmFPAfileDefineOutput (config, byFPA1->fpa, "PPIMAGE.JPEG1");
     362    pmFPAfile *jpg1 = pmFPAfileDefineOutput(config, byFPA1->fpa, "PPIMAGE.JPEG1");
    376363    if (!jpg1) {
    377364        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.JPEG1"));
     
    384371        return NULL;
    385372    }
    386     pmFPAfile *jpg2 = pmFPAfileDefineOutput (config, byFPA2->fpa, "PPIMAGE.JPEG2");
     373    pmFPAfile *jpg2 = pmFPAfileDefineOutput(config, byFPA2->fpa, "PPIMAGE.JPEG2");
    387374    if (!jpg2) {
    388375        psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.JPEG2"));
     
    404391    // Chip selection: turn on only the chips specified (pass status to suppress missing-key log msg)
    405392    char *chipLine = psMetadataLookupStr(&status, config->arguments, "CHIP_SELECTIONS");
    406     psArray *chips = psStringSplitArray (chipLine, ",", false);
     393    psArray *chips = psStringSplitArray(chipLine, ",", false);
    407394    if (chips->n > 0) {
    408395        pmFPASelectChip (input->fpa, -1, true); // deselect all chips
     
    454441    if (psTraceGetLevel("ppImage.config") > 0) {
    455442        // Get a look inside all the files.
    456         psMetadataIterator *filesIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, NULL); // Iterator
     443        psMetadataIterator *filesIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, NULL);
    457444        psMetadataItem *item;               // Item from iteration
    458445        fprintf(stderr, "Files:\n");
  • trunk/psModules/src/camera/pmFPAfileDefine.c

    r22699 r23268  
    1111#include "pmConfig.h"
    1212#include "pmConfigMask.h"
     13#include "pmConfigRun.h"
    1314#include "pmDetrendDB.h"
    1415
     
    216217        file->imageId = config->imageId;
    217218    }
    218 
    219     // XXX this seems a bit of a hack: use the cameraName to determine the mosaic level...
    220     # if (0)
    221     if (cameraName) {
    222         if (!strcmp(cameraName + strlen(cameraName) - 5, "-CHIP")) {
    223             file->mosaicLevel = PM_FPA_LEVEL_CHIP;
    224         }
    225         if (!strcmp(cameraName + strlen(cameraName) - 5, "-FPA")) {
    226             file->mosaicLevel = PM_FPA_LEVEL_FPA;
    227         }
    228     }
    229     # endif
    230219
    231220    // Use the format we were told to, the format specified in the file rule, or default to the default format
     
    383372    }
    384373
    385     psTrace ("psModules.camera", 5, "file: %s, format: %s, fileLevel: %s, extLevel: %s, dataLevel: %s, freeLevel: %s\n",
    386              file->name, file->formatName, pmFPALevelToName (file->fileLevel), pmFPALevelToName(extLevel), pmFPALevelToName (file->dataLevel), pmFPALevelToName (file->freeLevel));
     374    psTrace("psModules.camera", 5,
     375            "file: %s, format: %s, fileLevel: %s, extLevel: %s, dataLevel: %s, freeLevel: %s\n",
     376            file->name, file->formatName, pmFPALevelToName(file->fileLevel), pmFPALevelToName(extLevel),
     377            pmFPALevelToName(file->dataLevel), pmFPALevelToName(file->freeLevel));
    387378
    388379    // add argument-supplied OUTPUT name to this file
    389380    char *outname = psMetadataLookupStr(&status, config->arguments, "OUTPUT");
    390     psMetadataAddStr(file->names, PS_LIST_TAIL, "OUTPUT", PS_META_NO_REPLACE, "", outname);
     381    psMetadataAddStr(file->names, PS_LIST_TAIL, "OUTPUT", PS_META_NO_REPLACE, "Output file name", outname);
    391382
    392383    // place the resulting file in the config system
    393     psMetadataAddPtr (config->files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN, "", file);
     384    psMetadataAddPtr(config->files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN, "Output file", file);
    394385    psFree(file);                       // we free this copy of file, but 'files' still has a copy
    395386    return file;                        // the returned value is a view into the version on 'files'
     
    426417}
    427418
    428 // search for argname on the config->argument list
    429 // construct an FPA based on the files in this list (must represent a single FPA)
    430 // built the association between the FPA elements (CHIP/CELL) and the files
    431 // define the pmFPAfile filename and bind it to this FPA
    432 // save the pmFPAfile on config->files
    433 // return the pmFPAfile (a view to the one saved on config->files)
    434 pmFPAfile *pmFPAfileDefineFromArgs(bool *success, pmConfig *config, const char *filename, const char *argname)
     419
     420/// Define a file from an array of filenames
     421static pmFPAfile *fpaFileDefineFromArray(pmConfig *config, // Configuration
     422                                         pmFPAfile *bind, // File to bind to, or NULL
     423                                         const char *name, // Name of file
     424                                         const psArray *filenames // Array of file names
     425    )
     426{
     427    PS_ASSERT_PTR_NON_NULL(config, NULL);
     428    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
     429
     430    pmFPA *fpa = NULL;                  // FPA for file
     431    psMetadata *format = NULL;          // Camera format configuration
     432    psString formatName = NULL;         // Name of camera format
     433    psString cameraName = NULL;         // Name of camera
     434    pmFPALevel fileLevel = PM_FPA_LEVEL_NONE; // Level for files
     435    psMetadata *phu = NULL;             // Primary header
     436    if (bind) {
     437        // Use the FPA we're binding to
     438        fpa = psMemIncrRefCounter(bind->fpa);
     439        fileLevel = bind->fileLevel;
     440    } else {
     441        // Need to generate an FPA
     442        psString realName = pmConfigConvertFilename(filenames->data[0], config, false, false);
     443        if (!realName) {
     444            psError(PS_ERR_IO, false, "Failed to convert file name %s", (char *)filenames->data[0]);
     445            return NULL;
     446        }
     447
     448        // load the header of the first image
     449        // EXTWORD (fits->extword) is not relevant to the PHU
     450        psFits *fits = psFitsOpen(realName, "r"); // FITS file
     451        if (!fits) {
     452            psError(PS_ERR_IO, false, "Failed to open file %s", realName);
     453            psFree(realName);
     454            return NULL;
     455        }
     456        phu = psFitsReadHeader (NULL, fits); // Primary header
     457        if (!phu) {
     458            psError(PS_ERR_IO, false, "Failed to read file header %s", realName);
     459            psFree(realName);
     460            return NULL;
     461        }
     462        psFitsClose(fits);
     463
     464        // Determine the current format from the header; determine camera if not specified already.
     465        psMetadata *camera = NULL;      // Camera configuration
     466        format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
     467        if (!format) {
     468            psError(PS_ERR_IO, false, "Failed to determine camera format for %s", realName);
     469            psFree(camera);
     470            psFree(formatName);
     471            psFree(realName);
     472            psFree(phu);
     473            psFree(phu);
     474            return NULL;
     475        }
     476
     477        fileLevel = pmFPAPHULevel(format);
     478        if (fileLevel == PM_FPA_LEVEL_NONE) {
     479            psError(PS_ERR_IO, true, "Unable to determine file level for %s", realName);
     480            psFree(camera);
     481            psFree(formatName);
     482            psFree(realName);
     483            psFree(phu);
     484            return NULL;
     485        }
     486
     487        // build the template fpa, set up the basic view
     488        // XXX do we want this to be the baseCamera name or the metaCamera name?
     489        fpa = pmFPAConstruct(camera, cameraName);
     490        psFree(camera);
     491        if (!fpa) {
     492            psError(PS_ERR_IO, false, "Failed to construct FPA from %s", realName);
     493            psFree(formatName);
     494            psFree(realName);
     495            psFree(format);
     496            psFree(phu);
     497            return NULL;
     498        }
     499        psFree(realName);
     500    }
     501
     502    // load the given filerule (from config->camera) and bind it to the fpa
     503    // the returned file is just a view to the entry on config->files
     504    pmFPAfile *file = pmFPAfileDefineInput(config, fpa, cameraName, name); // File, to return
     505    if (!file) {
     506        psError(PS_ERR_IO, false, "File %s not defined", name);
     507        psFree(formatName);
     508        psFree(format);
     509        psFree(fpa);
     510        psFree(phu);
     511        return NULL;
     512    }
     513    psFree(cameraName);
     514    psFree(fpa);                        // Drop reference
     515
     516    file->format = format;
     517    file->formatName = formatName;
     518    file->fileLevel = fileLevel;
     519
     520    // We use the filerule and filesrc to identify the files in the file->names data
     521    psFree(file->filerule); // this is set in pmFPAfileDefineInput
     522    file->filerule = psStringCopy("@FILES");
     523    file->filesrc = psStringCopy("{CHIP.NAME}.{CELL.NAME}");
     524
     525    if (file->type == PM_FPA_FILE_MASK) {
     526        if (!pmConfigMaskReadHeader(config, phu)) {
     527            psError(PS_ERR_IO, false, "Error reading mask bits");
     528            psFree(phu);
     529            return NULL;
     530        }
     531    }
     532
     533    // Examine the list of input files and validate their cameras
     534    // Associate each filename with an element of the FPA
     535    // Save the association on file->names
     536    for (int i = 0; i < filenames->n; i++) {
     537        // Check that the file corresponds to the same camera and format
     538        if (!phu) {
     539            psString realName = pmConfigConvertFilename(filenames->data[i], config, false, false);
     540            if (!realName) {
     541                psError(PS_ERR_IO, false, "Failed to convert file name %s", (char*)filenames->data[i]);
     542                return NULL;
     543            }
     544            psFits *fits = psFitsOpen(realName, "r"); // FITS file
     545            if (!fits) {
     546                psError(PS_ERR_IO, false, "Failed to open file %s", realName);
     547                psFree(realName);
     548                return NULL;
     549            }
     550            phu = psFitsReadHeader(NULL, fits);
     551            psFitsClose(fits);
     552            if (!phu) {
     553                psError(PS_ERR_IO, false, "Failed to read file header %s", realName);
     554                psFree(realName);
     555                return NULL;
     556            }
     557            psFree(realName);
     558        }
     559
     560        if (bind || i > 0) {
     561            if (format) {
     562                bool valid = false;
     563                if (!pmConfigValidateCameraFormat(&valid, format, phu)) {
     564                    psError(PS_ERR_UNKNOWN, false, "Error in config scripts\n");
     565                    psFree(phu);
     566                    return NULL;
     567                }
     568                if (!valid) {
     569                    psError(PS_ERR_IO, false, "File %s is not from the required camera",
     570                            (char*)filenames->data[i]);
     571                    psFree(phu);
     572                    return NULL;
     573                }
     574            } else {
     575                format = pmConfigCameraFormatFromHeader(NULL, NULL, NULL, config, phu, true);
     576                if (!format) {
     577                    psError(PS_ERR_IO, false, "Failed to determine camera format from %s",
     578                            (char*)filenames->data[i]);
     579                    psFree(phu);
     580                    return NULL;
     581                }
     582            }
     583        }
     584
     585        // Set the view to the corresponding entry for this phu
     586        pmFPAview *view = NULL;         // View to PHU
     587        if (bind) {
     588            view = pmFPAIdentifySourceFromHeader(bind->fpa, phu, format);
     589        } else {
     590            view = pmFPAAddSourceFromHeader(fpa, phu, format);
     591        }
     592        psFree(phu);
     593        phu = NULL;
     594        if (!view) {
     595            psError(PS_ERR_IO, false, "Unable to determine source for %s", name);
     596            return NULL;
     597        }
     598
     599        // Associate the filename with the FPA element
     600        psString location = pmFPAfileNameFromRule(file->filesrc, file, view);
     601        psFree(view);
     602        psMetadataAddStr(file->names, PS_LIST_TAIL, location, 0, "Location of file", filenames->data[i]);
     603        psFree(location);
     604    }
     605
     606    return file;
     607}
     608
     609
     610pmFPAfile *pmFPAfileDefineFromArgs(bool *success, pmConfig *config,
     611                                   const char *filename, const char *argname)
    435612{
    436613    PS_ASSERT_PTR_NON_NULL(config, NULL);
     
    438615    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
    439616
    440     bool status;
    441     pmFPA *fpa = NULL;
    442     psFits *fits = NULL;
    443     pmFPAfile *file = NULL;
    444     psMetadata *phu = NULL;
    445     psMetadata *format = NULL;
    446     psMetadata *camera = NULL;
    447     psString formatName = NULL;
    448 
    449     // use success to identify valid exit conditions (as opposed to 'argument not supplied')
    450     if (success) {
    451         *success = false;
    452     }
    453 
    454     // we search the argument data for the named fileset (argname)
    455     psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
     617    // Search the argument data for the named fileset (argname)
     618    bool status;                        // Status of MD lookup
     619    psArray *filenames = psMetadataLookupPtr(&status, config->arguments, argname); // Filenames for file
    456620    if (!status) {
    457621        if (success) {
     
    460624        return NULL;
    461625    }
    462     if (infiles->n < 1) {
    463         psError(PS_ERR_IO, false, "Found n == %ld files in %s in arguments\n", infiles->n, argname);
    464         return NULL;
    465     }
    466 
    467     // this function is implicitly an INPUT operation: do not create the file
    468     psString realName = pmConfigConvertFilename (infiles->data[0], config, false, false);
    469     if (!realName) {
    470         psError(PS_ERR_IO, false, "Failed to convert file name %s\n", (char *) infiles->data[0]);
    471         return NULL;
    472     }
    473 
    474     // load the header of the first image
    475     // EXTWORD (fits->extword) is not relevant to the PHU
    476     fits = psFitsOpen (realName, "r");
    477     if (!fits) {
    478         psError(PS_ERR_IO, false, "Failed to open file %s\n", realName);
    479         psFree (realName);
    480         return NULL;
    481     }
    482     phu = psFitsReadHeader (NULL, fits);
    483 
    484     if (!phu) {
    485         psError(PS_ERR_IO, false, "Failed to read file header %s\n", realName);
    486         psFree (realName);
    487         return NULL;
    488     }
    489     psFitsClose(fits);
    490 
    491     // Determine the current format from the header; Determine camera if not specified already.
    492     // the returned pointers 'camera' and 'formatName' are allocated here
    493     psString cameraName = NULL;
    494     format = pmConfigCameraFormatFromHeader(&camera, &cameraName, &formatName, config, phu, true);
    495     if (!format) {
    496         psError(PS_ERR_IO, false, "Failed to read CCD format from %s\n", realName);
    497         psFree(phu);
    498         psFree(camera);
    499         psFree(formatName);
    500         psFree(realName);
    501         return NULL;
    502     }
    503 
    504     // build the template fpa, set up the basic view
    505     // XXX do we want this to be the baseCamera name or the metaCamera name?
    506     fpa = pmFPAConstruct(camera, cameraName);
    507     if (!fpa) {
    508         psError(PS_ERR_IO, false, "Failed to construct FPA from %s", realName);
    509         psFree(phu);
    510         psFree(camera);
    511         psFree(formatName);
    512         psFree(realName);
    513         psFree(format);
    514         return NULL;
    515     }
    516     psFree (realName);
    517     psFree (camera);
    518 
    519     // load the given filerule (from config->camera) and bind it to the fpa
    520     // the returned file is just a view to the entry on config->files
    521     file = pmFPAfileDefineInput(config, fpa, cameraName, filename);
    522     if (!file) {
    523         psError(PS_ERR_IO, false, "file %s not defined\n", filename);
    524         psFree(phu);
    525         psFree(formatName);
    526         psFree(format);
    527         psFree(fpa);
    528         return NULL;
    529     }
    530     psFree (cameraName);
    531     psFree (file->filerule); // this is set in pmFPAfileDefineInput
    532 
    533     file->format = format;
    534     file->formatName = formatName;
    535     file->filerule = psStringCopy("@FILES");
    536     file->filesrc = psStringCopy("{CHIP.NAME}.{CELL.NAME}");
    537     // we use the above rules to identify these files in the file->names data
    538 
    539     file->fileLevel = pmFPAPHULevel(format);
    540     if (file->fileLevel == PM_FPA_LEVEL_NONE) {
    541         psError(PS_ERR_IO, true, "Unable to determine file level for %s\n", file->name);
    542         psFree(phu);
    543         psFree(fpa);
    544         return NULL;
    545     }
    546 
    547     if (file->type == PM_FPA_FILE_MASK) {
    548         if (!pmConfigMaskReadHeader (config, phu)) {
    549             psError(PS_ERR_IO, false, "error in mask bits");
    550             return NULL;
    551         }
    552     }
    553 
    554     // examine the list of input files and validate their cameras
    555     // associated each filename with an element of the FPA
    556     // save the association on file->names
    557     for (int i = 0; i < infiles->n; i++) {
    558         if (i > 0) {
    559             // this function is implicitly an INPUT operation: do not create the file
    560             psString realName = pmConfigConvertFilename (infiles->data[i], config, false, false);
    561             if (!realName) {
    562                 psError(PS_ERR_IO, false, "Failed to convert file name %s", (char *) infiles->data[i]);
    563                 psFree(phu);
    564                 psFree(fpa);
    565                 return NULL;
    566             }
    567             // EXTWORD (fits->extword) is not relevant to the PHU
    568             fits = psFitsOpen (realName, "r");
    569             if (!fits) {
    570                 psError(PS_ERR_IO, false, "Failed to open file %s\n", realName);
    571                 psFree(realName);
    572                 psFree(phu);
    573                 psFree(fpa);
    574                 return NULL;
    575             }
    576             phu = psFitsReadHeader (NULL, fits);
    577             if (!phu) {
    578                 psError(PS_ERR_IO, false, "Failed to read file header %s", realName);
    579                 psFree(realName);
    580                 psFitsClose(fits);
    581                 psFree(phu);
    582                 psFree(fpa);
    583                 return NULL;
    584             }
    585             bool valid = false;
    586             if (!pmConfigValidateCameraFormat (&valid, format, phu)) {
    587                 psError(PS_ERR_UNKNOWN, false, "Error in config scripts\n");
    588                 psFree(realName);
    589                 psFitsClose(fits);
    590                 psFree(phu);
    591                 psFree(fpa);
    592                 return NULL;
    593             }
    594             if (!valid) {
    595                 psError(PS_ERR_IO, false, "file %s is not from the required camera", realName);
    596                 psFree(realName);
    597                 psFitsClose(fits);
    598                 psFree(phu);
    599                 psFree(fpa);
    600                 return NULL;
    601             }
    602             psFree(realName);
    603             psFitsClose(fits);
    604         }
    605 
    606         // set the view to the corresponding entry for this phu
    607         pmFPAview *view = pmFPAAddSourceFromHeader (fpa, phu, format);
    608         if (!view) {
    609             psError(PS_ERR_IO, false, "Unable to determine source for %s", file->name);
    610             psFree(phu);
    611             psFree(fpa);
    612             return NULL;
    613         }
    614 
    615         // associate the filename with the FPA element
    616         char *name = pmFPAfileNameFromRule(file->filesrc, file, view);
    617 
    618         // save the name association in the pmFPAfile structure
    619         psMetadataAddStr(file->names, PS_LIST_TAIL, name, 0, "", infiles->data[i]);
    620 
    621         psFree(view);
    622         psFree(name);
    623         psFree(phu);
    624     }
    625     psFree(fpa);
     626    if (filenames->n == 0) {
     627        psError(PS_ERR_IO, false, "No files in array in %s in arguments", argname);
     628        if (success) {
     629            *success = false;
     630        }
     631        return NULL;
     632    }
     633
     634    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, filenames); // File of interest
     635
    626636    if (success) {
    627         *success = true;
    628     }
    629 
    630     return file;
    631 }
    632 
    633 // search for argname on the config->argument list
    634 // construct an FPA based on the files in this list (must represent a single FPA)
    635 // built the association between the FPA elements (CHIP/CELL) and the files
    636 // define the pmFPAfile filename and bind it to this FPA
    637 // save the pmFPAfile on config->files
    638 // return the pmFPAfile (a view to the one saved on config->files)
    639 pmFPAfile *pmFPAfileBindFromArgs (bool *success, pmFPAfile *input, pmConfig *config, const char *filename, const char *argname)
     637        *success = file ? true : false;
     638    }
     639
     640    return file;
     641}
     642
     643pmFPAfile *pmFPAfileBindFromArgs(bool *success, pmFPAfile *input, pmConfig *config,
     644                                 const char *filename, const char *argname)
    640645{
    641646    PS_ASSERT_PTR_NON_NULL(input, NULL);
     
    644649    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
    645650
    646     bool status;
    647     psFits *fits = NULL;
    648     pmFPAfile *file = NULL;
    649     psMetadata *phu = NULL;
    650 
    651     // use success to identify valid exit conditions (as opposed to 'argument not supplied')
    652     if (success) {
    653         *success = false;
    654     }
    655 
    656     // we search the argument data for the named fileset (argname)
    657     psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
     651    // Search the argument data for the named fileset (argname)
     652    bool status;                        // Status of MD lookup
     653    psArray *filenames = psMetadataLookupPtr(&status, config->arguments, argname); // Filenames for file
    658654    if (!status) {
    659         // this is not an error: this just means no matching argument was supplied
    660655        if (success) {
    661656            *success = true;
     
    663658        return NULL;
    664659    }
    665     if (infiles->n < 1) {
    666         psError(PS_ERR_IO, false, "Found n == %ld files in %s in arguments\n", infiles->n, argname);
    667         return NULL;
    668     }
    669 
    670     // load the given filerule (from config->camera) and bind it to the fpa
    671     // the returned file is just a view to the entry on config->files
    672     file = pmFPAfileDefineInput (config, input->fpa, NULL, filename);
    673     if (!file) {
    674         psError(PS_ERR_IO, false, "file %s not defined\n", filename);
    675         psFree(phu);
    676         return NULL;
    677     }
    678 
    679     // set derived values
    680     file->fileLevel = input->fileLevel;
    681 
    682 
    683     // define the rule to identify these files in the file->names data
    684     psFree (file->filerule);
    685     psFree (file->filesrc);
    686     file->filerule = psStringCopy ("@FILES");
    687     file->filesrc = psStringCopy ("{CHIP.NAME}.{CELL.NAME}");
    688 
    689     // examine the list of input files and validate their cameras
    690     // associated each filename with an element of the FPA
    691     // save the association on file->names
    692     psMetadata *format = NULL;
    693     for (int i = 0; i < infiles->n; i++) {
    694         // this function is implicitly an INPUT operation: do not create the file
    695         psString realName = pmConfigConvertFilename (infiles->data[i], config, false, false);
    696         if (!realName) {
    697             psError(PS_ERR_IO, false, "Failed to convert file name %s", (char *) infiles->data[i]);
    698             return NULL;
    699         }
    700         // EXTWORD (fits->extword) is not relevant to the PHU
    701         fits = psFitsOpen (realName, "r");
    702         if (!fits) {
    703             psError(PS_ERR_IO, false, "Failed to open file %s\n", realName);
    704             psFree(realName);
    705             return NULL;
    706         }
    707         phu = psFitsReadHeader (NULL, fits);
    708         if (!phu) {
    709             psError(PS_ERR_IO, false, "Failed to read file header %s", realName);
    710             psFree(realName);
    711             psFitsClose(fits);
    712             return NULL;
    713         }
    714 
    715         if (!format) {
    716             format = pmConfigCameraFormatFromHeader(NULL, NULL, NULL, config, phu, true);
    717             if (!format) {
    718                 psError(PS_ERR_IO, false, "Failed to read CCD format from %s\n", realName);
    719                 psFree(phu);
    720                 psFree(realName);
    721                 psFitsClose(fits);
    722                 return NULL;
    723             }
    724         } else {
    725             bool valid = false;
    726             if (!pmConfigValidateCameraFormat(&valid, format, phu)) {
    727                 psError(PS_ERR_UNKNOWN, false, "Error in config scripts\n");
    728                 psFree(realName);
    729                 psFitsClose(fits);
    730                 return NULL;
    731             }
    732             if (!valid) {
    733                 psError(PS_ERR_IO, false, "specified data file %s does not match format of supplied INPUT\n",
    734                         realName);
    735                 psFree(realName);
    736                 psFitsClose(fits);
    737                 return NULL;
    738             }
    739         }
    740 
    741         psFree(realName);
    742         psFitsClose(fits);
    743 
    744         // set the view to the corresponding entry for this phu
    745         pmFPAview *view = pmFPAIdentifySourceFromHeader (input->fpa, phu, format);
    746         if (!view) {
    747             psError(PS_ERR_IO, false, "Unable to determine source for %s", file->name);
    748             psFree(phu);
    749             return NULL;
    750         }
    751 
    752         // associate the filename with the FPA element
    753         char *name = pmFPAfileNameFromRule(file->filesrc, file, view);
    754 
    755         // save the name association in the pmFPAfile structure
    756         psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", infiles->data[i]);
    757 
    758         if ((i == 0) && (file->type == PM_FPA_FILE_MASK)) {
    759             if (!pmConfigMaskReadHeader (config, phu)) {
    760                 psError(PS_ERR_IO, false, "error in mask bits");
    761                 return NULL;
    762             }
    763         }
    764 
    765         psFree(view);
    766         psFree(name);
    767         psFree(phu);
    768     }
    769     file->format = format;
    770     file->formatName = psStringCopy(config->formatName);
     660    if (filenames->n == 0) {
     661        psError(PS_ERR_IO, false, "No files in array in %s in arguments", argname);
     662        if (success) {
     663            *success = false;
     664        }
     665        return NULL;
     666    }
     667
     668    pmFPAfile *file = fpaFileDefineFromArray(config, input, filename, filenames); // File of interest
    771669
    772670    if (success) {
    773         *success = true;
    774     }
    775     return file;
    776 }
    777 
    778 // search for argname on the config->argument list
    779 // construct an FPA based on the files in this list (each represents the same FPA)
    780 // built the association between the FPA elements (CHIP/CELL) and the files
    781 // define the pmFPAfile filenames and bind them to the FPAs
    782 // save the pmFPAfiles on config->files
    783 // return the pmFPAfiles (a view to the one saved on config->files)
    784 pmFPAfile *pmFPAfileDefineSingleFromArgs (bool *success, pmConfig *config, const char *filename,
    785         const char *argname, int entry)
     671        *success = file ? true : false;
     672    }
     673
     674    return file;
     675}
     676
     677pmFPAfile *pmFPAfileDefineSingleFromArgs(bool *success, pmConfig *config, const char *filename,
     678                                         const char *argname, int entry)
    786679{
    787680    PS_ASSERT_PTR_NON_NULL(config, NULL);
     
    789682    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
    790683
    791     bool status;
    792     pmFPA *fpa = NULL;
    793     psFits *fits = NULL;
    794     pmFPAfile *file = NULL;
    795     psMetadata *phu = NULL;
    796     psMetadata *format = NULL;
    797 
    798     if (success) {
    799         *success = false;
    800     }
    801 
    802     // we search the argument data for the named fileset (argname)
    803     psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
     684    // Search the argument data for the named fileset (argname)
     685    bool status;                        // Status from MD lookup
     686    psArray *filenames = psMetadataLookupPtr(&status, config->arguments, argname); // Filenames for file
    804687    if (!status) {
    805         psTrace("psModules.camera", 5, "Failed to find %s in argument list", argname);
    806688        if (success) {
    807689            *success = true;
     
    809691        return NULL;
    810692    }
    811     if (infiles->n <= entry) {
    812         psError(PS_ERR_IO, false, "only %ld files in %s in argument, entry %d requested\n",
    813                 infiles->n, argname, entry);
    814         return NULL;
    815     }
    816 
    817     // examine the list of input files and validate their cameras
    818     // associated each filename with an element of the FPA
    819     // save the association on file->names
    820     // EXTWORD (fits->extword) is not relevant to the PHU
    821     fits = psFitsOpen (infiles->data[entry], "r");
    822     phu = psFitsReadHeader (NULL, fits);
    823     psFitsClose (fits);
    824 
    825     // on first call to this function, config->camera is not set.
    826     // later calls will give an error if the cameras do not match
    827     psMetadata *camera = NULL;
    828     psString formatName = NULL;
    829     psString cameraName = NULL;
    830     format = pmConfigCameraFormatFromHeader (&camera, &cameraName, &formatName, config, phu, true);
    831     if (!format) {
    832         psError(PS_ERR_IO, false, "Failed to read CCD format from %s\n", (char *)infiles->data[0]);
    833         psFree(phu);
    834         psFree(camera);
    835         psFree(formatName);
    836         return NULL;
    837     }
    838 
    839     // build the template fpa, set up the basic view
    840     fpa = pmFPAConstruct (camera, cameraName);
    841     if (!fpa) {
    842         psError(PS_ERR_IO, false, "Failed to construct FPA from %s", (char *)infiles->data[0]);
    843         psFree(phu);
    844         psFree(camera);
    845         psFree(formatName);
    846         psFree(format);
    847         return NULL;
    848     }
    849     psFree(camera);
    850 
    851     // load the given filerule (from config->camera) and bind it to the fpa
    852     // the returned file is just a view to the entry on config->files
    853     // we need a variable name here... (but in filerule)
    854     file = pmFPAfileDefineInput (config, fpa, cameraName, filename);
    855     if (!file) {
    856         psError(PS_ERR_IO, false, "file %s not defined\n", filename);
    857         psFree(phu);
    858         psFree(fpa);
    859         psFree(format);
    860         return NULL;
    861     }
    862     psFree(cameraName);
    863     FPA_TEST_ASSERT (file);
    864 
    865     file->format = format;
    866     file->formatName = formatName;
    867     file->filerule = psStringCopy ("@FILES");
    868     file->filesrc = psStringCopy ("{CHIP.NAME}.{CELL.NAME}");
    869     // adjust the above rules to identify these files in the file->names data
    870 
    871     file->fileLevel = pmFPAPHULevel(format);
    872     if (file->fileLevel == PM_FPA_LEVEL_NONE) {
    873         psError(PS_ERR_IO, true, "Unable to determine file level for %s\n", file->name);
    874         psFree(phu);
    875         psFree(fpa);
    876         return NULL;
    877     }
    878 
    879     if (file->type == PM_FPA_FILE_MASK) {
    880         if (!pmConfigMaskReadHeader (config, phu)) {
    881             psError(PS_ERR_IO, false, "error in mask bits");
    882             return NULL;
    883         }
    884     }
    885 
    886     // set the view to the corresponding entry for this phu
    887     pmFPAview *view = pmFPAAddSourceFromHeader (fpa, phu, format);
    888     if (!view) {
    889         psError(PS_ERR_IO, false, "Unable to determine source for %s", file->name);
    890         psFree(phu);
    891         psFree(fpa);
    892         return NULL;
    893     }
    894 
    895     // associate the filename with the FPA element
    896     char *name = pmFPAfileNameFromRule (file->filesrc, file, view);
    897 
    898     // save the name association in the pmFPAfile structure
    899     psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", infiles->data[entry]);
    900 
    901     psFree(phu);
    902     psFree(fpa);
    903     psFree(view);
    904     psFree(name);
     693    if (filenames->n <= entry) {
     694        psError(PS_ERR_IO, false, "Insufficient files (%ld) in array in %s in arguments",
     695                filenames->n, argname);
     696        if (success) {
     697            *success = false;
     698        }
     699        return NULL;
     700    }
     701
     702    psArray *single = psArrayAlloc(1);  // Array of single filename of interest
     703    single->data[0] = psMemIncrRefCounter(filenames->data[entry]);
     704    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, single); // File of interest
     705    psFree(single);
    905706
    906707    if (success) {
    907         *success = true;
    908     }
    909     return file;
    910 }
     708        *success = file ? true : false;
     709    }
     710
     711    return file;
     712}
     713
     714pmFPAfile *pmFPAfileDefineFromRun(bool *success, pmConfig *config, const char *filename)
     715{
     716    PS_ASSERT_PTR_NON_NULL(config, NULL);
     717    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
     718
     719    psArray *filenames = pmConfigRunFileGet(config, filename); // Filenames used, or NULL
     720    if (!filenames) {
     721        if (success) {
     722            *success = true;
     723        }
     724        return NULL;
     725    }
     726
     727    pmFPAfile *file = fpaFileDefineFromArray(config, NULL, filename, filenames); // File of interest
     728    psFree(filenames);
     729
     730    if (success) {
     731        *success = file ? true : false;
     732    }
     733
     734    return file;
     735}
     736
    911737
    912738// define the named pmFPAfile from the camera->config
    913739// only valid for pmFPAfile->mode = READ
    914 pmFPAfile *pmFPAfileDefineFromConf (bool *success, const pmConfig *config, const char *filename)
     740pmFPAfile *pmFPAfileDefineFromConf(bool *success, const pmConfig *config, const char *filename)
    915741{
    916742    PS_ASSERT_PTR_NON_NULL(config, false);
     
    991817    pmFPA *fpa = NULL;
    992818    pmFPAfile *file = NULL;
     819
     820    if (type == PM_DETREND_TYPE_NONE) {
     821        return NULL;
     822    }
    993823
    994824    if (success) {
  • trunk/psModules/src/camera/pmFPAfileDefine.h

    r20637 r23268  
    5353// Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
    5454// reference count is held by the config->files metadata.
    55 pmFPAfile *pmFPAfileDefineFromArgs (bool *found, pmConfig *config, const char *filename, const char *argname);
     55pmFPAfile *pmFPAfileDefineFromArgs(bool *found, pmConfig *config, const char *filename, const char *argname);
    5656
    5757// look for the given argname on the argument list; bind the associated files to the specified
     
    5959// Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
    6060// reference count is held by the config->files metadata.
    61 pmFPAfile *pmFPAfileBindFromArgs (bool *found, pmFPAfile *input, pmConfig *config, const char *filename, const char *argname);
     61pmFPAfile *pmFPAfileBindFromArgs(bool *found, pmFPAfile *input, pmConfig *config, const char *filename, const char *argname);
     62
     63/// Define a file based on the filenames in the RUN metadata in the configuration
     64///
     65/// Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
     66/// reference count is held by the config->files metadata.
     67pmFPAfile *pmFPAfileDefineFromRun(
     68    bool *found,                        ///< Found files?
     69    pmConfig *config,                   ///< Configuration
     70    const char *filename                ///< Name of file
     71    );
     72
    6273
    6374// look for the given argname on the argument list.  find the give filename from the file rules
  • trunk/psModules/src/config/pmConfigRun.c

    r23259 r23268  
    7171}
    7272
     73psArray *pmConfigRunFileGet(pmConfig *config, const char *name)
     74{
     75    PS_ASSERT_PTR_NON_NULL(config, false);
     76    PS_ASSERT_STRING_NON_EMPTY(name, false);
     77
     78    psMetadata *run = configRun(config);// RUN information
     79    psAssert(run, "Require run-time information");
     80    psMetadata *files = configElement(run, "FILES", "Filerules used during execution");
     81    psAssert(files, "Require list of files");
     82
     83    psList *list = psListAlloc(NULL);   // List of file names
     84
     85    psString regex = NULL;              // Regular expression for iteration
     86    psStringAppend(&regex, "^%s$", name);
     87    psMetadataIterator *iter = psMetadataIteratorAlloc(files, PS_LIST_HEAD, regex);
     88    psFree(regex);
     89    psMetadataItem *item;               // Item from iteration
     90    while ((item = psMetadataGetAndIncrement(iter))) {
     91        psAssert(item->type == PS_DATA_STRING, "We only put STRING types here.");
     92        psListAdd(list, PS_LIST_TAIL, item->data.str);
     93    }
     94    psFree(iter);
     95
     96    if (psListLength(list) == 0) {
     97        // Didn't find anything
     98        psFree(list);
     99        return NULL;
     100    }
     101
     102    psArray *array = psListToArray(list); // Array of file names, to return
     103    psFree(list);
     104
     105    return array;
     106}
     107
    73108
    74109bool pmConfigRunCommand(pmConfig *config, int argc, char **argv)
  • trunk/psModules/src/config/pmConfigRun.h

    r23259 r23268  
    1010    pmConfig *config,                   ///< Configuration
    1111    const pmFPAfile *file               ///< File to add
     12    );
     13
     14/// Retrieve file names for a symbolic file from the run-time information
     15psArray *pmConfigRunFileGet(
     16    pmConfig *config,                   ///< Configuration
     17    const char *name                    ///< Name of symbolic file (pmFPAfile)
    1218    );
    1319
  • trunk/psModules/src/detrend/pmDetrendDB.c

    r20401 r23268  
    2020
    2121//
    22 static void pmDetrendSelectOptionsFree (pmDetrendSelectOptions *options)
    23 {
    24 
    25     if (!options)
     22static void pmDetrendSelectOptionsFree(pmDetrendSelectOptions *options)
     23{
     24
     25    if (!options) {
    2626        return;
    27 
    28     psFree (options->camera);
    29     psFree (options->filter);
    30     psFree (options->dettype);
    31     psFree (options->version);
     27    }
     28
     29    psFree(options->camera);
     30    psFree(options->filter);
     31    psFree(options->dettype);
     32    psFree(options->version);
    3233
    3334    return;
     
    3738pmDetrendSelectOptions *pmDetrendSelectOptionsAlloc(const char *camera, psTime time, pmDetrendType type)
    3839{
    39 
    4040    pmDetrendSelectOptions *options = psAlloc(sizeof(pmDetrendSelectOptions));
    4141    psMemSetDeallocator(options, (psFreeFunc) pmDetrendSelectOptionsFree);
     
    6363}
    6464
    65 static void pmDetrendSelectResultsFree (pmDetrendSelectResults *results)
    66 {
    67 
    68     if (!results)
     65static void pmDetrendSelectResultsFree(pmDetrendSelectResults *results)
     66{
     67
     68    if (!results) {
    6969        return;
    70 
    71     psFree (results->detID);
     70    }
     71
     72    psFree(results->detID);
    7273    psFree(results->level);
    7374
     
    7576}
    7677
    77 pmDetrendSelectResults *pmDetrendSelectResultsAlloc ()
     78pmDetrendSelectResults *pmDetrendSelectResultsAlloc(void)
    7879{
    7980
     
    8788}
    8889
    89 psString pmDetrendTypeToString (pmDetrendType type)
    90 {
    91 
    92     # define DETREND_STRING_CASE(TTT) \
    93 case PM_DETREND_TYPE_##TTT: \
    94     return psStringCopy (#TTT);
     90psString pmDetrendTypeToString(pmDetrendType type)
     91{
     92
     93#define DETREND_STRING_CASE(TYPE) \
     94  case PM_DETREND_TYPE_##TYPE: \
     95    return psStringCopy(#TYPE);
    9596
    9697    switch (type) {
    97         DETREND_STRING_CASE (MASK);
    98         DETREND_STRING_CASE (BIAS);
    99         DETREND_STRING_CASE (DARK);
    100         DETREND_STRING_CASE (FLAT);
    101         DETREND_STRING_CASE (FLATCORR);
    102         DETREND_STRING_CASE (SHUTTER);
    103         DETREND_STRING_CASE (FRINGE);
    104         DETREND_STRING_CASE (ASTROM);
     98        DETREND_STRING_CASE(NONE);
     99        DETREND_STRING_CASE(MASK);
     100        DETREND_STRING_CASE(BIAS);
     101        DETREND_STRING_CASE(DARK);
     102        DETREND_STRING_CASE(FLAT);
     103        DETREND_STRING_CASE(FLATCORR);
     104        DETREND_STRING_CASE(SHUTTER);
     105        DETREND_STRING_CASE(FRINGE);
     106        DETREND_STRING_CASE(ASTROM);
    105107    default:
    106108        return NULL;
     
    111113// detselect -camera (camera) -time (time) -type (type) [others]
    112114// returns: (type) (class) (exp_flag) DONE
    113 pmDetrendSelectResults *pmDetrendSelect (const pmDetrendSelectOptions *options,
    114         const pmConfig *config)
     115pmDetrendSelectResults *pmDetrendSelect(const pmDetrendSelectOptions *options, const pmConfig *config)
    115116{
    116117    PS_ASSERT_PTR_NON_NULL(options, NULL);
  • trunk/psModules/src/detrend/pmDetrendDB.h

    r20401 r23268  
    2525
    2626typedef enum {
     27    PM_DETREND_TYPE_NONE,
    2728    PM_DETREND_TYPE_MASK,
    2829    PM_DETREND_TYPE_BIAS,
     
    5960} pmDetrendSelectResults;
    6061
    61 psString pmDetrendTypeToString (pmDetrendType type);
     62psString pmDetrendTypeToString(pmDetrendType type);
    6263
    6364pmDetrendSelectOptions *pmDetrendSelectOptionsAlloc(const char *camera, psTime time, pmDetrendType type);
Note: See TracChangeset for help on using the changeset viewer.