IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 16, 2006, 3:50:43 PM (20 years ago)
Author:
magnier
Message:

updates from day when MHPCC CVS was down

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/pmFPAConstruct.c

    r7526 r7589  
    200200
    201201
    202 // Looks up the particular content based on the header
    203 static const char *getContent(psMetadata *fileInfo, // The FILE from the camera format configuration
    204                               psMetadata *contents, // The CONTENTS from the camera format configuration
    205                               psMetadata *header // The (primary) header
     202// Looks up the particular content, based on the chip and cell
     203static const char *getContent(const psMetadata *fileInfo, // The FILE from the camera format configuration
     204                              const psMetadata *contents, // The CONTENTS from the camera format configuration
     205                              const pmChip *chip, // The chip of interest
     206                              const pmCell *cell // The cell of interest
    206207                             )
    207208{
    208209    assert(fileInfo);
    209210    assert(contents);
    210     assert(header);
     211    assert(chip);
    211212
    212213    bool mdok = true;                   // Status of MD lookup
    213     const char *contentHeaders = psMetadataLookupStr(&mdok, fileInfo, "CONTENT"); // Headers for content
    214     if (!mdok || !contentHeaders || strlen(contentHeaders) == 0) {
     214    char *contentKey = psMetadataLookupStr(&mdok, fileInfo, "CONTENT"); // Key for CONTENTS
     215    if (!mdok || !contentKey || strlen(contentKey) == 0) {
    215216        psError(PS_ERR_IO, true, "Unable to find CONTENT in FILE within camera format configuration.\n");
    216217        return NULL;
    217218    }
    218219
    219     psList *keywords = psStringSplit(contentHeaders, " ,;", true); // List of keywords
    220     psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false); // Iterator
    221     psString keyword = NULL;        // Keyword, from iteration
    222     psString contentsKey = NULL;    // Key to the CONTENTS menu
    223     bool first = true;              // Is it the first value?
    224     while ((keyword = psListGetAndIncrement(keywordsIter))) {
    225         const char *value = psMetadataLookupStr(&mdok, header, keyword);
    226         if (first) {
    227             psStringAppend(&contentsKey, "%s", value);
    228             first = false;
    229         } else {
    230             psStringAppend(&contentsKey, "_%s", value);
    231         }
    232     }
    233     psFree(keywordsIter);
    234     psFree(keywords);
    235     psTrace(__func__, 5, "Looking up %s in the CONTENTS.\n", contentsKey);
    236     const char *content = psMetadataLookupStr(&mdok, contents, contentsKey);
     220    contentKey = psStringCopy(contentKey); // So that we're not altering something someone else might use...
     221
     222    // Replace some concept names
     223    if (strstr(contentKey, "{CHIP.NAME}")) {
     224        if (!chip) {
     225            psError(PS_ERR_IO, true, "CONTENT in FILE refers to CHIP.NAME, but no chip was provided.\n");
     226            psFree(contentKey);
     227            return NULL;
     228        }
     229        const char *name = psMetadataLookupStr(&mdok, chip->concepts, "CHIP.NAME");
     230        if (mdok && name && strlen(name) > 0) {
     231            contentKey = psStringSubstitute(contentKey, name, "{CHIP.NAME}");
     232        }
     233    }
     234
     235    if (strstr(contentKey, "{CELL.NAME}")) {
     236        if (!chip) {
     237            psError(PS_ERR_IO, true, "CONTENT in FILE refers to CELL.NAME, but no chip was provided.\n");
     238            psFree(contentKey);
     239            return NULL;
     240        }
     241        const char *name = psMetadataLookupStr(&mdok, cell->concepts, "CELL.NAME");
     242        if (mdok && name && strlen(name) > 0) {
     243            contentKey = psStringSubstitute(contentKey, name, "{CELL.NAME}");
     244        }
     245    }
     246
     247    psTrace(__func__, 5, "Looking up %s in the CONTENTS.\n", contentKey);
     248    const char *content = psMetadataLookupStr(&mdok, contents, contentKey);
    237249    if (!mdok || !content || strlen(content) == 0) {
    238         psError(PS_ERR_IO, true, "Unable to find %s in the CONTENTS.\n", contentsKey);
    239         return NULL;
    240     }
    241     psFree(contentsKey);
     250        psFree(contentKey);
     251        psError(PS_ERR_IO, true, "Unable to find %s in the CONTENTS.\n", contentKey);
     252        return NULL;
     253    }
     254
     255    psFree(contentKey);
    242256
    243257    return content;
     
    253267                           pmFPALevel level, // The level at which to add the HDU
    254268                           const char *contents, // The contents line, consisting of a list of chip:cell
    255                            psMetadata *format // Camera format configuration
     269                           const psMetadata *format // Camera format configuration
    256270                          )
    257271{
     
    364378}
    365379
    366 static pmFPALevel hduLevel(psMetadata *format // The camera format configuration
     380static pmFPALevel hduLevel(const psMetadata *format // The camera format configuration
    367381                          )
    368382{
     
    442456}
    443457
    444 bool pmFPAAddSourceFromView(pmFPA *fpa,   // The FPA
    445                             const pmFPAview *phuView, // The view, corresponding to the PHU
    446                             psMetadata *format // Format of file
     458
     459// This is the engine for the pmFPAAddSourceFrom{Header,View} functions
     460// It returns a view corresponding to the PHU
     461static pmFPAview *addSource(pmFPA *fpa,       // The FPA
     462                            const pmFPAview *phuView, // The view corresponding to the PHU, or NULL
     463                            const psMetadata *header, // The PHU header, or NULL
     464                            const psMetadata *format // Format of file
    447465                           )
    448466{
    449     PS_ASSERT_PTR_NON_NULL(fpa, false);
    450     PS_ASSERT_PTR_NON_NULL(phuView, false);
    451     PS_ASSERT_PTR_NON_NULL(format, false);
    452 
    453     // Where does the PHU go?
    454     bool mdok = true;                   // Status of MD lookup
    455     psMetadata *fileInfo = psMetadataLookupMD(&mdok, format, "FILE"); // File information from the format
    456     if (!mdok || !fileInfo) {
    457         psError(PS_ERR_IO, false, "Unable to find FILE information in the camera format configuration.\n");
    458         return false;
    459     }
    460     const char *phuType = psMetadataLookupStr(&mdok, fileInfo, "PHU"); // What is the PHU?
    461     if (!mdok || strlen(phuType) == 0) {
    462         psError(PS_ERR_IO, false, "Unable to find PHU in the FILE information of the camera format.\n");
    463         return false;
    464     }
    465 
    466     // Generate the PHU
    467     pmHDU *phdu = pmHDUAlloc("PHU");    // The primary header data unit
    468     phdu->format = psMemIncrRefCounter(format);
    469 
    470     // Put in the PHU
    471     pmChip *chip = NULL;                // The chip that corresponds to the PHU
    472     pmCell *cell = NULL;                // The cell that corresponds to the PHU
    473     if (strcasecmp(phuType, "FPA") == 0) {
    474         addHDUtoFPA(fpa, phdu);
    475         psFree(phdu);
    476     } else {
    477         psArray *chips = fpa->chips;    // Array of chips
    478         if (phuView->chip < 0 || phuView->chip > chips->n) {
    479             psError(PS_ERR_IO, true, "PHU specified by the camera format requires specification of a "
    480                     "particular chip, which cannot be determined from the view (%d).\n", phuView->chip);
    481             psFree(phdu);
    482             return false;
    483         }
    484         chip = chips->data[phuView->chip];
    485         if (strcasecmp(phuType, "CHIP") == 0) {
    486             addHDUtoChip(chip, phdu);
    487             psFree(phdu);
    488         } else if (strcasecmp(phuType, "CELL") == 0) {
    489             psArray *cells = chip->cells; // Array of cells
    490             if (phuView->cell < 0 || phuView->cell > cells->n) {
    491                 psError(PS_ERR_IO, true, "PHU specified by the camera format requires specification of a "
    492                         "particular cell, which cannot be determined from the view (%d).\n", phuView->cell);
    493                 psFree(phdu);
    494                 return false;
    495             }
    496             addHDUtoCell(cell, phdu);
    497             psFree(phdu);
    498         } else {
    499             psError(PS_ERR_IO, true, "PHU in the camera configuration format is not FPA, CHIP or CELL.\n");
    500             psFree(phdu);
    501             return false;
    502         }
    503     }
    504 
    505     // Put in the extensions
    506     pmFPALevel level = hduLevel(format);// The level for the HDUs to go
    507     if (level == PM_FPA_LEVEL_NONE) {
    508         // No extensions.  We're done unless PHU == FPA, in which case we need to process the contents
    509         if (strcasecmp(phuType, "FPA") == 0) {
    510             const char *content = psMetadataLookupStr(&mdok, format, "CONTENTS"); // Contents of the FITS file
    511             if (!mdok || !content || strlen(content) == 0) {
    512                 psError(PS_ERR_IO, true, "Unable to find CONTENTS of type STR in the camera "
    513                         "format configuration.\n");
    514                 return false;
    515             }
    516             if (processContents(fpa, chip, cell, phdu, level, content, format) < 0) {
    517                 psError(PS_ERR_IO, false, "Error setting contents.\n");
    518                 return false;
    519             }
    520         }
    521         return true;
    522     }
    523     psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
    524     if (!mdok || !contents) {
    525         psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n");
    526         return false;
    527     }
    528 
    529     psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL); // Iterator
    530     psMetadataItem *contentsItem = NULL;// Item from the contents iteration
    531     while ((contentsItem = psMetadataGetAndIncrement(contentsIter))) {
    532         if (contentsItem->type != PS_DATA_STRING) {
    533             psLogMsg(__func__, PS_LOG_WARN, "Content item %s is not of type STR --- ignored.\n",
    534                      contentsItem->name);
    535             continue;
    536         }
    537         pmHDU *hdu = pmHDUAlloc(contentsItem->name); // HDU to add
    538         hdu->format = psMemIncrRefCounter(format);
    539         const char *content = contentsItem->data.V; // The content data
    540         if (processContents(fpa, chip, cell, hdu, level, content, format) < 0) {
    541             psError(PS_ERR_IO, false, "Error setting contents for %s", contentsItem->name);
    542             psFree(hdu);
    543             psFree(contentsIter);
    544 
    545             return false;
    546         }
    547         psFree(hdu);
    548     }
    549     psFree(contentsIter);
    550 
    551     return true;
    552 }
    553 
    554 
    555 
    556 // Add an input file to the FPA
    557 pmFPAview *pmFPAAddSourceFromHeader(pmFPA *fpa, // The FPA
    558                                     psMetadata *phu, // Primary header of file
    559                                     psMetadata *format // Format of file
    560                                    )
    561 {
    562     PS_ASSERT_PTR_NON_NULL(fpa, NULL);
    563     PS_ASSERT_PTR_NON_NULL(phu, NULL);
    564     PS_ASSERT_PTR_NON_NULL(format, NULL);
     467    assert(fpa);
     468    assert(phuView || header);
     469    assert(format);
    565470
    566471    bool mdok = true;                   // Status from metadata lookups
     
    571476    }
    572477
    573     // Check the name of the FPA
    574     psString newFPAname = phuNameFromHeader("FPA.NAME", fileInfo, phu); // New name for the FPA
    575     if (!newFPAname) {
    576         psError(PS_ERR_IO, true, "Unable to determine FPA.NAME");
    577         return NULL;
    578     }
    579 
    580     // is FPAname already defined, new name must match it
    581     // XXX if not, is it an error?
    582     const char *currentFPAname = psMetadataLookupStr(&mdok, fpa->concepts, "FPA.NAME"); // Current name
    583     if (mdok && currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) {
    584         psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current "
    585                  "fpa (%s).\n", newFPAname, currentFPAname);
    586     }
    587     psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.NAME", PS_META_REPLACE, "Name of FPA", newFPAname);
    588     psFree(newFPAname);                 // Drop reference
    589 
    590     // Where does the PHU go?
     478    // At what level does the PHU go?
    591479    const char *phuType = psMetadataLookupStr(&mdok, fileInfo, "PHU"); // What is the PHU?
    592480    if (!mdok || strlen(phuType) == 0) {
     
    594482        return NULL;
    595483    }
     484
     485    // Prepare the PHU to be placed in the camera hierarchy
    596486    pmHDU *phdu = pmHDUAlloc("PHU");    // The primary header data unit
    597     phdu->header = psMemIncrRefCounter(phu);
    598     phdu->format = psMemIncrRefCounter(format);
    599     // Generate the view
    600     pmFPAview *view = pmFPAviewAlloc(0); // The FPA view corresponding to the PHU, to be returned
    601     view->chip = -1;
    602     view->cell = -1;
    603     view->readout = -1;
    604 
    605     // And what are the individual extensions?
     487    // Casting to psPtr to avoide "warning: passing arg 1 of `p_psMemIncrRefCounter' discards qualifiers from
     488    // pointer target type"
     489    phdu->header = psMemIncrRefCounter((const psPtr)header);
     490    phdu->format = psMemIncrRefCounter((const psPtr)format);
     491    pmFPAview *view = pmFPAviewAlloc(0); // View, to be returned
     492    if (phuView) {
     493        // Copy the view, for the case where we're given a header.
     494        *view = *phuView;
     495    }
     496
     497    // And at what level do the individual extensions go?
    606498    const char *extType = psMetadataLookupStr(&mdok, fileInfo, "EXTENSIONS"); // What's in the extns?
    607499    if (!mdok || strlen(extType) == 0) {
     
    611503    }
    612504
    613 
    614     // This is a special case: PHU=FPA and EXTENSIONS=NONE.  The only reason to do this is in the case of
    615     // single CCD imagers, where the entire FPA is in the PHU image.  In this case, the CONTENTS is of type
    616     // STR (rather than METADATA), and has the usual chip:cell.
     505    // Now, there are a few cases:
     506
     507    // 1. PHU=FPA and EXTENSIONS=NONE.  This is a single CCD imager, where the entire FPA is in the PHU image.
     508    // In this case, the CONTENTS is of type STR (rather than METADATA), and has the usual chip:cell:cellType.
     509    //
     510    // 2. PHU=CHIP or PHU=CELL, and EXTENSIONS=NONE.  This is a single chip or cell from a mosaic camera in
     511    // its own file (e.g., Megacam split).  In this case, the CONTENTS is of type METADATA, and consists of a
     512    // menu of choices for the contents of the file.  This is because we need to work out which chip and/or
     513    // cell it comes from.
     514    //
     515    // 3. EXTENSIONS=CHIP or EXTENSIONS=CELL.  This is a mosaic camera, with multiple extensions.  In this
     516    // case, the CONTENTS is of type METADATA, and consists of a list of contents of the file.
     517    //
     518    // In all of the above cases, the contents are specified by chip:cell:cellType triples.  It's just how the
     519    // contents as a *whole* are collected that changes, and what that collection means.
     520    //
     521    // We deal with each of these cases in turn.
     522
     523    // Case 1: PHU=FPA and EXTENSIONS=NONE.  We need to parse the single list of chip:cell:cellType entries.
    617524    if (strcasecmp(phuType, "FPA") == 0 && strcasecmp(extType, "NONE") == 0) {
    618525        const char *contents = psMetadataLookupStr(&mdok, format, "CONTENTS"); // The contents of the file
     
    628535            psFree(phdu);
    629536            psFree(view);
    630 
    631537            return NULL;
    632538        }
    633 
    634539        psFree(phdu);
     540
    635541        return view;
    636542    }
    637543
    638     // In all other cases, the CONTENTS is of type METADATA, and is either a menu if EXTENSIONS=NONE, or
    639     // a list of extensions otherwise.
     544    // In cases 2 and 3, the CONTENTS is of type METADATA, and is either a menu (if EXTENSIONS=NONE), or a
     545    // list of extensions otherwise.
    640546    psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
    641547    if (!mdok || !contents) {
     
    649555            }
    650556        }
    651 
     557        psFree(phdu);
    652558        psFree(view);
    653559        return NULL;
    654560    }
    655561
    656     // No extensions --- only have the PHU.  In this case, the CONTENTS is a menu, with CONTENT indicating
    657     // header keywords that provides a key to the CONTENTS menu.
     562    // Case 2: EXTENSIONS=NONE.  We only have the PHU.  The value of CONTENT tells us a header keyword, which
     563    // gives us the key to the CONTENTS menu.  Or, if we've got the view specifying the PHU, we can get the
     564    // chip/cell directly from that.
    658565    if (strcasecmp(extType, "NONE") == 0) {
    659         // We have already dealt with the case PHU=FPA, in a special case, above.
    660         const char *content = getContent(fileInfo, contents, phu); // The content: string of chip:cell pairs
    661 
    662         // Need to look up what chip we have.
    663         psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, phu);
    664         psTrace(__func__, 5, "This is chip %s\n", chipName);
     566        pmChip *chip = NULL;        // The chip of interest
     567        pmCell *cell = NULL;        // The cell of interest
     568        pmFPALevel level = PM_FPA_LEVEL_NONE; // Level for HDU to be added
     569
     570        if (phuView) {
     571            // We can get the chip/cell from the view
     572            if (phuView->chip != -1 && phuView->chip < fpa->chips->n) {
     573                chip = fpa->chips->data[phuView->chip];
     574                level = PM_FPA_LEVEL_CHIP;
     575                if (phuView->cell != -1) {
     576                    if (phuView->cell < chip->cells->n) {
     577                        cell = chip->cells->data[phuView->cell];
     578                        level = PM_FPA_LEVEL_CELL;
     579                    } else {
     580                        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "PHU view for cell (%d) does not "
     581                                "correspond to camera format.\n", phuView->cell);
     582                        psFree(phdu);
     583                        return NULL;
     584                    }
     585                }
     586            } else {
     587                psError(PS_ERR_BAD_PARAMETER_VALUE, true, "PHU view for chip (%d) does not correspond to "
     588                        "camera format.\n", phuView->chip);
     589                psFree(phdu);
     590                return NULL;
     591            }
     592        } else {
     593            // Need to look up what chip we have.
     594            psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, header);
     595            psTrace(__func__, 5, "This is chip %s\n", chipName);
     596            int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
     597            if (chipNum == -1) {
     598                psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", chipName);
     599                psFree(phdu);
     600                psFree(view);
     601                return NULL;
     602            }
     603            pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest
     604            view->chip = chipNum;
     605
     606            if (strcasecmp(phuType, "CHIP") == 0) {
     607                level = PM_FPA_LEVEL_CHIP;
     608            } else if (strcasecmp(phuType, "CELL") == 0) {
     609                level = PM_FPA_LEVEL_CELL;
     610                // Need to look up what cell we have.
     611                psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, header);
     612                int cellNum = pmChipFindCell(chip, cellName); // Cell number
     613                if (cellNum == -1) {
     614                    psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", cellName, chipName);
     615                    psFree(view);
     616                    psFree(phdu);
     617                    return NULL;
     618                }
     619                cell = chip->cells->data[cellNum];
     620                view->cell = cellNum;
     621                psFree(cellName);
     622            } else {
     623                // We have already dealt with the case PHU=FPA, in a special case above, so if we get here
     624                // it's an error.
     625                psError(PS_ERR_IO, true, "PHU is not FPA, CHIP or CELL.\n");
     626                psFree(phdu);
     627                psFree(view);
     628                return NULL;
     629            }
     630            psFree(chipName);
     631        }
     632
     633        const char *content = getContent(fileInfo, contents, chip, cell); // The chip:cell:cellType triples
     634        if (!content || strlen(content) == 0) {
     635            psError(PS_ERR_IO, false, "Unable to get CONTENTS.\n");
     636            psFree(phdu);
     637            psFree(view);
     638            return NULL;
     639        }
     640        if (processContents(fpa, chip, cell, phdu, level, content, format) < 0) {
     641            psError(PS_ERR_IO, false, "Error setting CONTENTS");
     642            psFree(phdu);
     643            psFree(view);
     644            return NULL;
     645        }
     646        psFree(phdu);
     647
     648        return view;
     649    }
     650
     651    // Case 3: EXTENSIONS=CHIP or EXTENSIONS=CELL.  We have extensions that we iterate through.  The CONTENTS
     652    // is a list of extensions.
     653    pmChip *chip = NULL;                // The chip of interest
     654    pmCell *cell = NULL;                // The cell of interest
     655
     656    // First, put in the PHU
     657    if (strcasecmp(phuType, "FPA") == 0) {
     658        addHDUtoFPA(fpa, phdu);
     659    } else {
     660        // Get the chip
     661        psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, header); // Name of the chip
    665662        int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
    666663        if (chipNum == -1) {
     
    669666            return NULL;
    670667        }
    671         pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest
    672         view->chip = chipNum;
    673 
    674         pmCell *cell = NULL;            // Cell of interest
    675 
    676         pmFPALevel level = PM_FPA_LEVEL_NONE; // Level for HDU to be added
    677         if (strcasecmp(phuType, "CHIP") == 0) {
    678             level = PM_FPA_LEVEL_CHIP;
    679         } else if (strcasecmp(phuType, "CELL") == 0) {
    680             level = PM_FPA_LEVEL_CELL;
    681             // Need to look up what cell we have.
    682             psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, phu);
    683             int cellNum = pmChipFindCell(chip, cellName); // Cell number
    684             if (cellNum == -1) {
    685                 psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", cellName, chipName);
    686                 psFree(view);
    687                 return NULL;
    688             }
    689             cell = chip->cells->data[cellNum];
    690             view->cell = cellNum;
    691             psFree(cellName);
    692         } else {
    693             psError(PS_ERR_IO, true, "PHU is not FPA, CHIP or CELL.\n");
    694             psFree(view);
    695             return NULL;
    696         }
    697         psFree(chipName);
    698 
    699         if (processContents(fpa, chip, cell, phdu, level, content, format) < 0) {
    700             psError(PS_ERR_IO, false, "Error setting CONTENTS");
    701             psFree(phdu);
    702             psFree(view);
    703             return NULL;
    704         }
    705         psFree(phdu);
    706         return view;
    707     }
    708 
    709 
    710     // From here on, we have extensions that we iterate through.  The CONTENTS is a list of extensions.
    711     pmChip *chip = NULL;                // The chip of interest
    712     pmCell *cell = NULL;                // The cell of interest
    713 
    714     // First, put in the PHU
    715     if (strcasecmp(phuType, "FPA") == 0) {
    716         addHDUtoFPA(fpa, phdu);
    717     } else {
    718         // Get the chip
    719         psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, phu); // Name of the chip
    720         int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
    721         if (chipNum == -1) {
    722             psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", chipName);
    723             psFree(view);
    724             return NULL;
    725         }
    726668        chip = fpa->chips->data[chipNum]; // The specified chip
    727669        view->chip = chipNum;
     
    730672            addHDUtoChip(chip, phdu);
    731673        } else if (strcasecmp(phuType, "CELL") == 0) {
    732             psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, phu); // Name of the cell
     674            psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, header); // Name of the cell
    733675            int cellNum = pmChipFindCell(chip, cellName); // Cell number
    734676            if (cellNum == -1) {
     
    764706
    765707        pmHDU *hdu = pmHDUAlloc(extName); // The extension
    766         hdu->format = psMemIncrRefCounter(format);
     708        // Casting to avoid "warning: passing arg 1 of `p_psMemIncrRefCounter' discards qualifiers from
     709        // pointer target type"
     710        hdu->format = psMemIncrRefCounter((const psPtr)format);
    767711
    768712        if (processContents(fpa, chip, cell, hdu, level, contentsItem->data.V, format) < 0) {
     
    778722
    779723    if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_DEFAULTS, true, NULL)) {
    780         psError(PS_ERR_UNKNOWN, false, "Unable to read concepts from defaults for FPA %s.  Attempting to "
    781                 "proceed anyway.\n", currentFPAname);
     724        psLogMsg(__func__, PS_LOG_WARN, "Unable to read concepts from defaults for FPA.  Attempting to "
     725                 "proceed anyway.\n");
    782726    }
    783727
    784728    return view;
     729
     730}
     731
     732
     733bool pmFPAAddSourceFromView(pmFPA *fpa,   // The FPA
     734                            const pmFPAview *phuView, // The view, corresponding to the PHU
     735                            const psMetadata *format // Format of file
     736                           )
     737{
     738    PS_ASSERT_PTR_NON_NULL(fpa, false);
     739    PS_ASSERT_PTR_NON_NULL(phuView, false);
     740    PS_ASSERT_PTR_NON_NULL(format, false);
     741
     742    return addSource(fpa, phuView, NULL, format) ? true : false;
     743}
     744
     745
     746
     747// Add an input file to the FPA
     748pmFPAview *pmFPAAddSourceFromHeader(pmFPA *fpa, // The FPA
     749                                    psMetadata *phu, // Primary header of file
     750                                    const psMetadata *format // Format of file
     751                                   )
     752{
     753    PS_ASSERT_PTR_NON_NULL(fpa, NULL);
     754    PS_ASSERT_PTR_NON_NULL(phu, NULL);
     755    PS_ASSERT_PTR_NON_NULL(format, NULL);
     756
     757    bool mdok = true;                   // Status from metadata lookups
     758    psMetadata *fileInfo = psMetadataLookupMD(&mdok, format, "FILE"); // The file information
     759    if (!mdok || !fileInfo) {
     760        psError(PS_ERR_IO, false, "Unable to find FILE in the camera format configuration.\n");
     761        return NULL;
     762    }
     763
     764    // Check the name of the FPA
     765    psString newFPAname = phuNameFromHeader("FPA.NAME", fileInfo, phu); // New name for the FPA
     766    if (!newFPAname) {
     767        psError(PS_ERR_IO, true, "Unable to determine FPA.NAME");
     768        return NULL;
     769    }
     770
     771    // is FPAname already defined, new name must match it; otherwise, warn the user that something potentially
     772    // bad is happening.
     773    const char *currentFPAname = psMetadataLookupStr(&mdok, fpa->concepts, "FPA.NAME"); // Current name
     774    if (mdok && currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) {
     775        psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current "
     776                 "fpa (%s).\n", newFPAname, currentFPAname);
     777    }
     778    psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.NAME", PS_META_REPLACE, "Name of FPA", newFPAname);
     779    psFree(newFPAname);                 // Drop reference
     780
     781    return addSource(fpa, NULL, phu, format);
    785782}
    786783
Note: See TracChangeset for help on using the changeset viewer.