IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 15068


Ignore:
Timestamp:
Sep 28, 2007, 10:37:33 AM (19 years ago)
Author:
Paul Price
Message:

Needed to re-work the way PHU={CHIP,CELL} were being handled in the
CONTENTS. We can't assume that the FITS header carries the name that
we want to use for the chip (e.g., CFH12K, where the FITS header only
has a 'chipid' --- an integer), so we need to specify how to get the
chip name:

Case PHU EXTENSIONS Description

=== ========== =======

  1. FPA CHIP CONTENTS(METADATA) has a list of extensions, each with chipName:chipType

CHIPS(METADATA) has a list of chip types, each with cell:type

  1. FPA CELL CONTENTS(METADATA) has a list of extensions, each with chip:cell:type

No need for CHIPS.

  1. FPA NONE CONTENTS(STRING) has a list of extensions, chip:cell:type

No need for CHIPS

  1. CHIP CELL CONTENTS(METADATA) is a menu, each with a chipName:chipType

CHIPS(METADATA) has a list of chip types(METADATA), containg a list of
extensions.

  1. CHIP NONE CONTENTS(METADATA) is a menu, each with a chipName:chipType

CHIPS(METADATA) has a list of chip types(STRING) with cell:type

  1. CELL NONE CONTENTS(METADATA) is a menu, each with a chipName:cellName:cellType.

No need for CHIPS.

File:
1 edited

Legend:

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

    r14471 r15068  
    190190// Looks up the particular content, based on the chip and cell
    191191static const char *getContent(const psMetadata *fileInfo, // The FILE from the camera format configuration
    192                               const psMetadata *contents, // The CONTENTS from the camera format configuration
    193                               const pmChip *chip, // The chip of interest
    194                               const pmCell *cell // The cell of interest
     192                              const psMetadata *header, // The FITS header
     193                              const psMetadata *contents // The CONTENTS from the camera format configuration
    195194                             )
    196195{
    197196    assert(fileInfo);
    198197    assert(contents);
    199     assert(chip);
    200 
    201     bool mdok = true;                   // Status of MD lookup
    202     char *contentKey = psMetadataLookupStr(&mdok, fileInfo, "CONTENT"); // Key for CONTENTS
    203     if (!mdok || !contentKey || strlen(contentKey) == 0) {
    204         psError(PS_ERR_IO, true, "Unable to find CONTENT in FILE within camera format configuration.\n");
     198    assert(header);
     199
     200    const char *contentHeader = psMetadataLookupStr(NULL, fileInfo, "CONTENT"); // Keyword to get contents
     201    if (!contentHeader || strlen(contentHeader) == 0) {
     202        psError(PS_ERR_UNEXPECTED_NULL, false,
     203                "Unable to find CONTENT in FILE within camera format configuration.\n");
    205204        return NULL;
    206205    }
    207206
    208     contentKey = psStringCopy(contentKey); // So that we're not altering something someone else might use...
    209 
    210     // Replace some concept names
    211     if (strstr(contentKey, "{CHIP.NAME}")) {
    212         if (!chip) {
    213             psError(PS_ERR_IO, true, "CONTENT in FILE refers to CHIP.NAME, but no chip was provided.\n");
    214             psFree(contentKey);
    215             return NULL;
    216         }
    217         const char *name = psMetadataLookupStr(&mdok, chip->concepts, "CHIP.NAME");
    218         if (mdok && name && strlen(name) > 0) {
    219             psStringSubstitute(&contentKey, name, "{CHIP.NAME}");
    220         }
    221     }
    222 
    223     if (strstr(contentKey, "{CELL.NAME}")) {
    224         if (!chip) {
    225             psError(PS_ERR_IO, true, "CONTENT in FILE refers to CELL.NAME, but no chip was provided.\n");
    226             psFree(contentKey);
    227             return NULL;
    228         }
    229         const char *name = psMetadataLookupStr(&mdok, cell->concepts, "CELL.NAME");
    230         if (mdok && name && strlen(name) > 0) {
    231             psStringSubstitute(&contentKey, name, "{CELL.NAME}");
    232         }
    233     }
    234 
    235     // XXX: MORE SUBSTITUTION OPTIONS HERE!
    236 
    237     psTrace("psModules.camera", 5, "Looking up %s in the CONTENTS.\n", contentKey);
    238     const char *content = psMetadataLookupStr(&mdok, contents, contentKey);
    239     if (!mdok || !content || strlen(content) == 0) {
    240         psFree(contentKey);
    241         psError(PS_ERR_IO, true, "Unable to find %s in the CONTENTS.\n", contentKey);
     207    psMetadataItem *contentKey = psMetadataLookup(header, contentHeader); // Key to CONTENTS menu
     208    if (!contentKey) {
     209        psError(PS_ERR_UNEXPECTED_NULL, false,
     210                "Unable to find %s in header to determine file content.", contentHeader);
    242211        return NULL;
    243212    }
    244213
    245     psFree(contentKey);
     214    psString contentKeyStr = psMetadataItemParseString(contentKey); // Key, as a string
     215
     216    psTrace("psModules.camera", 5, "Looking up %s in the CONTENTS.\n", contentKeyStr);
     217    const char *content = psMetadataLookupStr(NULL, contents, contentKeyStr);
     218    if (!content || strlen(content) == 0) {
     219        psError(PS_ERR_IO, false, "Unable to find %s in the CONTENTS.\n", contentKeyStr);
     220        return NULL;
     221    }
     222
     223    psFree(contentKeyStr);
    246224
    247225    return content;
     
    252230static bool processContents(pmFPA *fpa,  // The FPA
    253231                            pmChip *chip, // The chip
    254                             pmCell *cell, // The cell
    255232                            pmHDU *hdu,  // The HDU to be added
    256233                            pmFPALevel level, // The level at which to add the HDU
     
    265242    long num = cellTypes->n;            // Number of entries to add
    266243    assert(chip || (chipNames && chipNames->n == num));
    267     assert(cell || (cellNames && cellNames->n == num));
     244    assert(cellNames && cellNames->n == num);
    268245    assert(format);
    269246
     
    310287        // Find the cell
    311288        pmCell *newCell;                // Cell of interest
    312         if (cell) {
    313             newCell = cell;
    314         } else {
    315             psString cellName = cellNames->data[i]; // The name of the cell
    316             int cellNum = pmChipFindCell(newChip, cellName); // The cell we're looking for
    317             if (cellNum == -1) {
    318                 psError(PS_ERR_LOCATION_INVALID, false, "Unable to find cell %s in chip --- ignored.\n",
    319                         cellName);
    320                 return false;
    321             }
    322             newCell = newChip->cells->data[cellNum];
    323         }
     289        psString cellName = cellNames->data[i]; // The name of the cell
     290        int cellNum = pmChipFindCell(newChip, cellName); // The cell we're looking for
     291        if (cellNum == -1) {
     292            psError(PS_ERR_LOCATION_INVALID, false, "Unable to find cell %s in chip --- ignored.\n",
     293                    cellName);
     294            return false;
     295        }
     296        newCell = newChip->cells->data[cellNum];
    324297
    325298        psMetadata *cellData = getCellData(format, cellType); // Data for this cell
     
    380353#endif
    381354
    382 // Find the chip of interest within the FPA, using either the view (simple) or the FITS header (bit more
    383 // complicated).  Also updates the provided view to point to the chip if we have to find it.
    384 static pmChip *whichChip(pmFPAview *view, // View to chip, modified
    385                          const pmFPA *fpa, // FPA holding chip of interest
    386                          const pmFPAview *phuView, // View to PHU, or NULL
    387                          const psMetadata *fileInfo, // FILE information from camera format
    388                          const psMetadata *header // FITS header, or NULL
    389                          )
    390 {
    391     assert(view);
     355// Find the chip of interest within the FPA
     356static bool whichChip(int *chipNum, // Chip number, modified
     357                      psString *chipType, // Type of chip, modified
     358                      const pmFPA *fpa, // FPA holding chip of interest
     359                      const char *content // Content consisting of chipName:chipType
     360                      )
     361{
     362    assert(chipType);
    392363    assert(fpa);
    393     assert(phuView || header);
    394     assert(fileInfo);
    395 
    396     if (phuView) {
    397         return pmFPAviewThisChip(phuView, fpa);
    398     }
    399 
    400     psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, header);
     364    assert(content);
     365
     366    psArray *chipNames = NULL;
     367    psArray *chipTypes = NULL;
     368    if (parseContent(&chipNames, &chipTypes, NULL, content) != 1) {
     369        psError(PS_ERR_UNKNOWN, false,
     370                "Unable to parse chipName:chipType in %s in camera format",
     371                TABLE_OF_CONTENTS);
     372        return false;
     373    }
     374
     375    psString chipName = psMemIncrRefCounter(chipNames->data[0]); // Name of chip
     376    *chipType = psMemIncrRefCounter(chipTypes->data[0]); // Type of chip
     377    psFree(chipNames);
     378    psFree(chipTypes);
     379
    401380    psTrace("psModules.camera", 5, "This is chip %s\n", chipName);
    402     int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
    403     if (chipNum == -1) {
     381
     382    // Get the chip
     383    *chipNum = pmFPAFindChip(fpa, chipName); // Chip number
     384    if (*chipNum == -1) {
    404385        psError(PS_ERR_UNKNOWN, true, "Unable to find chip %s in FPA.\n", chipName);
     386        psFree(chipName);
     387        return false;
     388    }
     389    psFree(chipName);
     390
     391    return true;
     392}
     393
     394
     395// Process a chip, using the cellName:cellType pair
     396static bool processChip(const psMetadata *format, // Camera format
     397                        const char *chipContents, // Contents of chip, cellName:cellType pairs
     398                        pmFPA *fpa, // FPA of interest
     399                        pmChip *chip, // Chip of interest
     400                        pmHDU *hdu      // HDU to add
     401                        )
     402{
     403    assert(format);
     404    assert(chipContents);
     405    assert(fpa);
     406
     407    psMetadata *chips = psMetadataLookupMetadata(NULL, format, CHIP_TYPES); // The chip types
     408    if (!chips) {
     409        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find %s in camera format.", CHIP_TYPES);
     410        return false;
     411    }
     412
     413    psArray *cellNames = NULL;      // Cell names
     414    psArray *cellTypes = NULL;      // Cell types
     415    if (parseContent(&cellNames, &cellTypes, NULL, chipContents) == 0) {
     416        psError(PS_ERR_BAD_PARAMETER_VALUE, false,
     417                "Unable to parse chip contents (within %s in camera format) as cellName:cellType",
     418                CHIP_TYPES);
     419        psFree(cellNames);
     420        psFree(cellTypes);
     421        return false;
     422    }
     423
     424    if (!processContents(fpa, chip, hdu, PM_FPA_LEVEL_CELL, NULL, cellNames, cellTypes, format)) {
     425        psError(PS_ERR_UNKNOWN, false, "Unable to set contents for chip from camera format.");
     426        psFree(cellNames);
     427        psFree(cellTypes);
     428        return false;
     429    }
     430
     431    psFree(cellNames);
     432    psFree(cellTypes);
     433
     434    return true;
     435}
     436
     437// Given a chip, find the corresponding type by searching through the contents, looking for a match to its
     438// name
     439psString findChipType(const pmChip *chip, // Chip of interest
     440                      psMetadata *contents // Contents, from camera format
     441                      )
     442{
     443    assert(chip);
     444    assert(contents);
     445
     446    const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); // Name of chip
     447    assert(chipName);
     448
     449    psString chipType = NULL;           // Type of chip
     450    psMetadataIterator *iter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL); // Iterator
     451    psMetadataItem *item;           // Item from iteration
     452    while ((item = psMetadataGetAndIncrement(iter))) {
     453        if (item->type != PS_DATA_STRING) {
     454            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     455                    "Item %s within %s in camera format is not of type STR.", item->name, TABLE_OF_CONTENTS);
     456            psFree(iter);
     457            psFree(chipType);
     458            return NULL;
     459        }
     460
     461        psArray *chipNames = NULL;  // Chip names
     462        psArray *chipTypes = NULL;  // Chip types
     463        if (parseContent(&chipNames, &chipTypes, NULL, item->data.str) != 1) {
     464            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
     465                    "Unable to parse contents (within %s in camera format) as chipName:chipType",
     466                    TABLE_OF_CONTENTS);
     467            psFree(chipNames);
     468            psFree(chipTypes);
     469            psFree(iter);
     470            psFree(chipType);
     471            return NULL;
     472        }
     473
     474        if (strcmp(chipName, chipNames->data[0]) == 0) {
     475            if (chipType) {
     476                if (strcmp(chipType, chipTypes->data[0]) != 0) {
     477                    psError(PS_ERR_UNKNOWN, true,
     478                            "Multiple instances of chip %s in contents, with differing chipType "
     479                            "(%s vs %s)", chipName, chipType, (char*)chipTypes->data[0]);
     480                    psFree(chipNames);
     481                    psFree(chipTypes);
     482                    psFree(iter);
     483                    psFree(chipType);
     484                    return NULL;
     485                }
     486            } else {
     487                chipType = psMemIncrRefCounter(chipTypes->data[0]);
     488            }
     489        }
     490        psFree(chipNames);
     491        psFree(chipTypes);
     492    }
     493    psFree(iter);
     494
     495    if (!chipType) {
     496        psError(PS_ERR_UNKNOWN, true, "Unable to identify chip type for chip %s", chipName);
    405497        return NULL;
    406498    }
    407     psFree(chipName);
    408     view->chip = chipNum;
    409     return fpa->chips->data[chipNum];
    410 }
    411 
    412 // Find the cell of interest within the chip, using either the view (simple) or the FITS header (bit more
    413 // complicated).  Also updates the provided view to point to the cell if we have to find it.
    414 static pmCell *whichCell(pmFPAview *view, // View to cell
    415                          const pmChip *chip, // Chip holding cell of interest
    416                          const pmFPAview *phuView, // View to PHU, or NULL
    417                          const psMetadata *fileInfo, // FILE information from camera format
    418                          const psMetadata *header // FITS header, or NULL
    419                          )
    420 {
    421     assert(view);
    422     assert(chip);
    423     assert(phuView || header);
    424     assert(fileInfo);
    425 
    426     pmFPA *fpa = chip->parent;          // The parent FPA
    427 
    428     if (phuView) {
    429         return pmFPAviewThisCell(phuView, fpa);
    430     }
    431 
    432     psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, header);
    433     psTrace("psModules.camera", 5, "This is cell %s\n", cellName);
    434     int cellNum = pmChipFindCell(chip, cellName); // Cell number
    435     if (cellNum == -1) {
    436         psError(PS_ERR_UNKNOWN, true, "Unable to find cell %s in chip.\n", cellName);
    437         return NULL;
    438     }
    439     view->cell = cellNum;
    440     return chip->cells->data[cellNum];
    441 }
    442 
     499
     500    return chipType;
     501}
    443502
    444503// PHU=FPA and EXTENSIONS=CHIP:
     
    484543        // What's in the extension?  It's specified by chipName:chipType
    485544        // Assume that an extension contains only a single chip, instead of multiple chips
    486 
    487         psString extContents = item->data.str; // Contents of extension
    488         psArray *chipNames = NULL;
    489         psArray *chipTypes = NULL;
    490         if (parseContent(&chipNames, &chipTypes, NULL, extContents) != 1) {
    491             psError(PS_ERR_UNKNOWN, false,
    492                     "Unable to parse chipName:chipType in %s of %s in camera format",
    493                     extname, TABLE_OF_CONTENTS);
    494         }
    495 
    496         psString chipName = psMemIncrRefCounter(chipNames->data[0]); // Name of chip
    497         psString chipType = psMemIncrRefCounter(chipTypes->data[0]); // Type of chip
    498         psFree(chipNames);
    499         psFree(chipTypes);
    500 
    501         // Get the chip
    502         int chipNum = pmFPAFindChip(fpa, chipName); // Chip number
    503         if (chipNum == -1) {
    504             psError(PS_ERR_UNKNOWN, false, "Unable to find chip %s in FPA.\n", chipName);
     545        psString chipType = NULL;       // Type of chip
     546        int chipNum = -1;               // Chip number
     547        if (!whichChip(&chipNum, &chipType, fpa, item->data.str)) {
     548            psError(PS_ERR_UNKNOWN, false, "Unable to determine chip from contents");
     549            return false;
     550        }
     551        pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest
     552
     553        const char *chipContents = psMetadataLookupStr(NULL, chips, chipType); // Contents of chip
     554        psFree(chipType);
     555        if (!chipContents) {
     556            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip type %s in %s.",
     557                    chipType, CHIP_TYPES);
    505558            psFree(hdu);
    506559            psFree(contentsIter);
    507560            return false;
    508561        }
    509         pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest
    510 
    511         // What's in the chip?
    512 
    513         psString chipContents = psMetadataLookupStr(NULL, chips, chipType); // Contents of the chip
    514         if (!chipContents) {
    515             psError(PS_ERR_UNEXPECTED_NULL, false,
    516                     "Unable to find chip type %s (for extension %s) in %s of camera format",
    517                     chipType, extname, CHIP_TYPES);
    518             psFree(chipName);
    519             psFree(chipType);
     562
     563        if (!processChip(format, chipContents, fpa, chip, hdu)) {
     564            psError(PS_ERR_UNKNOWN, false, "Unable to process chip %d\n", chipNum);
    520565            psFree(hdu);
    521566            psFree(contentsIter);
    522567            return false;
    523568        }
    524 
    525         psArray *cellNames = NULL;      // Cell names
    526         psArray *cellTypes = NULL;      // Cell types
    527         if (parseContent(&cellNames, &cellTypes, NULL, chipContents) == 0) {
    528             psError(PS_ERR_BAD_PARAMETER_VALUE, false,
    529                     "Unable to parse chip contents (within %s->%s in camera format; for chip %s) "
    530                     "as cellName:cellType", CHIP_TYPES, chipType, chipName);
    531             psFree(cellNames);
    532             psFree(cellTypes);
    533             psFree(chipName);
    534             psFree(chipType);
    535             psFree(hdu);
    536             psFree(contentsIter);
    537             return false;
    538         }
    539 
    540         if (!processContents(fpa, chip, NULL, hdu, PM_FPA_LEVEL_CHIP, NULL, cellNames, cellTypes, format)) {
    541             psError(PS_ERR_UNKNOWN, false, "Unable to set contents for chip %s from camera format.",
    542                     chipName);
    543             psFree(cellNames);
    544             psFree(cellTypes);
    545             psFree(chipName);
    546             psFree(chipType);
    547             psFree(hdu);
    548             psFree(contentsIter);
    549             return false;
    550         }
    551 
    552         psFree(cellNames);
    553         psFree(cellTypes);
    554         psFree(chipName);
    555         psFree(chipType);
    556569
    557570        psFree(hdu);                    // Drop reference
     
    612625        }
    613626
    614         if (!processContents(fpa, NULL, NULL, hdu, PM_FPA_LEVEL_CELL, chipNames, cellNames, cellTypes,
     627        if (!processContents(fpa, NULL, hdu, PM_FPA_LEVEL_CELL, chipNames, cellNames, cellTypes,
    615628                             format)) {
    616629            psError(PS_ERR_UNKNOWN, false, "Unable to set contents from camera format.");
     
    664677    }
    665678
    666     if (!processContents(fpa, NULL, NULL, NULL, PM_FPA_LEVEL_NONE, chipNames, cellNames, cellTypes,
     679    if (!processContents(fpa, NULL, NULL, PM_FPA_LEVEL_NONE, chipNames, cellNames, cellTypes,
    667680                         format)) {
    668681        psError(PS_ERR_UNKNOWN, false, "Unable to set contents from camera format.");
     
    682695
    683696// PHU=CHIP and EXTENSIONS=CELL:
    684 // TABLE_OF_CONTENTS(METADATA) has a menu of contents, each with a chipType.
    685 // CHIP_TYPES(METADATA) has a list of chip types, each with extension(METADATA) with cellName:cellType
    686 static bool addSource_CHIP_CELL(pmChip *chip, // Chip to which to add
    687                                 const psMetadata *format // The camera format
     697// TABLE_OF_CONTENTS(METADATA) has a menu of contents, each with a chipName:chipType.
     698// CHIP_TYPES(METADATA) has a list of chip types(METADATA), each with extension(STR) with cellName:cellType
     699static bool addSource_CHIP_CELL(pmFPAview *view, // View for PHU, modified
     700                                pmFPA *fpa, // FPA to which to add
     701                                pmChip *chip, // Known chip to which to add, or NULL
     702                                const psMetadata *format, // The camera format
     703                                pmHDU *phdu // The Primary HDU
    688704                                )
    689705{
    690     assert(chip);
     706    assert(view);
     707    assert(fpa);
    691708    assert(format);
     709    assert(phdu);
    692710
    693711    psMetadata *contents = psMetadataLookupMetadata(NULL, format, TABLE_OF_CONTENTS); // The contents
     
    709727    }
    710728
    711     const char *chipType = getContent(fileInfo, contents, chip, NULL); // The chip type
    712 
    713     // What's in the chip?
    714 
    715     psMetadata *chipContents = psMetadataLookupMetadata(NULL, chips, chipType); // Contents of the chip
     729
     730    psString chipType = NULL;           // Type of chip
     731    if (chip) {
     732        // We're given the chip (adding source from view)
     733        // Need to identify the chip type, which we will do by traversing the contents
     734        chipType = findChipType(chip, contents);
     735    } else {
     736        // We're given a header, from which to identify what chip we've got, and its type
     737        const char *content = getContent(fileInfo, phdu->header, contents); // The contents of this chip
     738
     739        int chipNum = -1;               // Chip number
     740        if (!whichChip(&chipNum, &chipType, fpa, content)) {
     741            psError(PS_ERR_UNKNOWN, false, "Unable to determine chip from contents");
     742            return false;
     743        }
     744        chip = fpa->chips->data[chipNum]; // Chip of interest
     745        view->chip = chipNum;
     746    }
     747
     748    if (!addHDUtoChip(chip, phdu)) {
     749        psError(PS_ERR_UNKNOWN, false, "Unable to add HDU to chip\n");
     750        psFree(chipType);
     751        return false;
     752    }
     753
     754    psMetadata *chipContents = psMetadataLookupMetadata(NULL, chips, chipType); // Contents of chip
     755    psFree(chipType);
    716756    if (!chipContents) {
    717         psError(PS_ERR_UNEXPECTED_NULL, false,
    718                 "Unable to find chip type %s in %s of camera format",
     757        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip type %s in %s.",
    719758                chipType, CHIP_TYPES);
    720759        return false;
    721760    }
    722 
    723     pmFPA *fpa = chip->parent;          // The parent FPA
    724761
    725762    psMetadataIterator *contentsIter = psMetadataIteratorAlloc(chipContents, PS_LIST_HEAD, NULL); // Iterator
     
    740777        hdu->format = psMemIncrRefCounter((const psPtr)format);
    741778
    742         psArray *cellNames = NULL;      // Cell names
    743         psArray *cellTypes = NULL;      // Cell types
    744         if (parseContent(&cellNames, &cellTypes, NULL, contentItem->data.str) == 0) {
    745             psError(PS_ERR_BAD_PARAMETER_VALUE, false,
    746                     "Unable to parse chip contents (within %s->%s in camera format) "
    747                     "as cellName:cellType", CHIP_TYPES, chipType);
    748             psFree(cellNames);
    749             psFree(cellTypes);
     779        if (!processChip(format, contentItem->data.str, fpa, chip, hdu)) {
     780            psError(PS_ERR_UNKNOWN, false, "Unable to process chip\n");
    750781            psFree(hdu);
    751782            psFree(contentsIter);
     
    753784        }
    754785
    755         if (!processContents(fpa, chip, NULL, hdu, PM_FPA_LEVEL_CELL, NULL, cellNames, cellTypes, format)) {
    756             psError(PS_ERR_UNKNOWN, false, "Unable to set contents for chip type %s from camera format.",
    757                     chipType);
    758             psFree(cellNames);
    759             psFree(cellTypes);
    760             psFree(hdu);
    761             psFree(contentsIter);
    762             return false;
    763         }
    764 
    765         psFree(cellNames);
    766         psFree(cellTypes);
    767 
    768786        psFree(hdu);                    // Drop reference
    769787    }
    770788    psFree(contentsIter);
     789
     790    if (!pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_PHU, true, true, NULL)) {
     791        psError(PS_ERR_UNKNOWN, false, "Unable to read concepts for chip.");
     792        return false;
     793    }
    771794
    772795    return true;
     
    776799// TABLE_OF_CONTENTS(METADATA) has a menu of contents, each with a chipName:chipType.
    777800// CHIP_TYPES(METADATA) has a list of chip types, each with cellName:cellType
    778 static bool addSource_CHIP_NONE(pmChip *chip, // Chip to which to add
    779                                 const psMetadata *format // The camera format
     801static bool addSource_CHIP_NONE(pmFPAview *view, // View for PHU, modified
     802                                pmFPA *fpa, // FPA to which to add
     803                                pmChip *chip, // Known chip to which to add, or NULL
     804                                const psMetadata *format, // The camera format
     805                                pmHDU *phdu // Primary HDU
    780806                                )
    781807{
    782     assert(chip);
     808    assert(fpa);
    783809    assert(format);
     810    assert(phdu);
    784811
    785812    psMetadata *contents = psMetadataLookupMetadata(NULL, format, TABLE_OF_CONTENTS); // The contents
     
    801828    }
    802829
    803     pmFPA *fpa = chip->parent;          // Parent FPA
    804 
    805     const char *chipType = getContent(fileInfo, contents, chip, NULL); // The chip type
     830    psString chipType = NULL;           // Type of chip
     831    if (chip) {
     832        // We're given the chip (adding source from view)
     833        // Need to identify the chip type, which we will do by traversing the contents
     834        chipType = findChipType(chip, contents);
     835    } else {
     836        const char *content = getContent(fileInfo, phdu->header, contents); // The chip type
     837
     838        int chipNum = -1;               // Chip number
     839        if (!whichChip(&chipNum, &chipType, fpa, content)) {
     840            psError(PS_ERR_UNKNOWN, false, "Unable to determine chip from contents");
     841            return false;
     842        }
     843        chip = fpa->chips->data[chipNum]; // Chip of interest
     844        view->chip = chipNum;
     845    }
     846
     847    if (!addHDUtoChip(chip, phdu)) {
     848        psError(PS_ERR_UNKNOWN, false, "Unable to add HDU to chip\n");
     849        psFree(chipType);
     850        return false;
     851    }
    806852
    807853    // What's in the chip?
    808 
    809854    psString chipContents = psMetadataLookupStr(NULL, chips, chipType); // Contents of the chip
    810855    if (!chipContents) {
     
    813858        return false;
    814859    }
    815 
    816     psArray *cellNames = NULL;      // Cell names
    817     psArray *cellTypes = NULL;      // Cell types
    818     if (parseContent(&cellNames, &cellTypes, NULL, chipContents) == 0) {
    819         psError(PS_ERR_BAD_PARAMETER_VALUE, false,
    820                 "Unable to parse chip contents (within %s->%s in camera format) "
    821                 "as cellName:cellType", CHIP_TYPES, chipType);
    822         psFree(cellNames);
    823         psFree(cellTypes);
    824         return false;
    825     }
    826 
    827     if (!processContents(fpa, chip, NULL, NULL, PM_FPA_LEVEL_NONE, NULL, cellNames, cellTypes, format)) {
    828         psError(PS_ERR_UNKNOWN, false, "Unable to set contents for chip type %s from camera format.",
    829                 chipType);
    830         psFree(cellNames);
    831         psFree(cellTypes);
    832         return false;
    833     }
    834 
    835     psFree(cellNames);
    836     psFree(cellTypes);
     860    psFree(chipType);
     861
     862    if (!processChip(format, chipContents, fpa, chip, NULL)) {
     863        psError(PS_ERR_UNKNOWN, false, "Unable to process chip\n");
     864        return false;
     865    }
     866
     867    if (!pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_PHU, true, true, NULL)) {
     868        psError(PS_ERR_UNKNOWN, false, "Unable to read concepts for chip.");
     869        return false;
     870    }
    837871
    838872    return true;
     
    840874
    841875// PHU=CELL and EXTENSIONS=NONE:
    842 // TABLE_OF_CONTENTS(METADATA) has a menu of contents, each with a cellName:cellType
    843 static bool addSource_CELL_NONE(pmCell *cell, // Cell to which to add
    844                                 const psMetadata *format // The camera format
     876// TABLE_OF_CONTENTS(METADATA) has a menu of contents, each with a chipName:cellName:cellType
     877static bool addSource_CELL_NONE(pmFPAview *view, // View for PHU, modified
     878                                pmFPA *fpa, // FPA to which to add
     879                                pmCell *cell, // Known cell to which to add, or NULL
     880                                const psMetadata *format, // The camera format
     881                                pmHDU *phdu // The Primary HDU
    845882                                )
    846883{
    847     assert(cell);
     884    assert(fpa);
    848885    assert(format);
     886    assert(phdu);
    849887
    850888    psMetadata *contents = psMetadataLookupMetadata(NULL, format, TABLE_OF_CONTENTS); // The contents
     
    860898    }
    861899
    862     pmChip *chip = cell->parent;        // Parent chip
    863     pmFPA *fpa = chip->parent;          // Parent FPA
    864 
    865     const char *content = getContent(fileInfo, contents, chip, cell); // Content of cell
    866 
    867     psArray *cellNames = NULL;      // Cell names
    868     psArray *cellTypes = NULL;      // Cell types
    869     if (parseContent(&cellNames, &cellTypes, NULL, content) != 1) {
    870         psError(PS_ERR_BAD_PARAMETER_VALUE, false,
    871                 "Unable to parse cell contents (%s) as cellName:cellType", content);
     900    psArray *chipNames = NULL;          // Chip names
     901    psArray *cellNames = NULL;          // Cell names
     902    psArray *cellTypes = NULL;          // Cell types
     903    pmChip *chip = NULL;                // Chip of interest
     904    if (cell) {
     905        // We're given the chip and cell (adding source from view)
     906        // Need to identify the cell type, which we will do by traversing the contents
     907
     908        chip = cell->parent;            // The chip of interest
     909        psString cellType = NULL;       // Type of cell
     910
     911        // The below is very similar to findChipType(), but with modifications for finding the cellType
     912        const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); // Name of chip
     913        assert(chipName);
     914        const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell
     915        assert(cellName);
     916
     917        psMetadataIterator *iter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL); // Iterator
     918        psMetadataItem *item;           // Item from iteration
     919        while ((item = psMetadataGetAndIncrement(iter))) {
     920            if (item->type != PS_DATA_STRING) {
     921                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     922                        "Item %s within %s in camera format is not of type STR.",
     923                        item->name, TABLE_OF_CONTENTS);
     924                psFree(chipNames);
     925                psFree(cellNames);
     926                psFree(cellTypes);
     927                psFree(iter);
     928                psFree(cellType);
     929                return false;
     930            }
     931
     932            psArray *testChipNames = NULL; // Chip names
     933            psArray *testCellNames = NULL; // Cell names
     934            psArray *testCellTypes = NULL; // Cell types
     935            if (parseContent(&testChipNames, &testCellTypes, &testCellTypes, item->data.str) != 1) {
     936                psError(PS_ERR_BAD_PARAMETER_VALUE, false,
     937                        "Unable to parse contents (within %s in camera format) as chipName:cellName:cellType",
     938                        TABLE_OF_CONTENTS);
     939                psFree(chipNames);
     940                psFree(cellNames);
     941                psFree(cellTypes);
     942                psFree(testChipNames);
     943                psFree(testCellNames);
     944                psFree(testCellTypes);
     945                psFree(iter);
     946                psFree(cellType);
     947                return false;
     948            }
     949
     950            if (strcmp(chipName, chipNames->data[0]) == 0 && strcmp(cellName, cellNames->data[0]) == 0) {
     951                if (cellType) {
     952                    if (strcmp(cellType, cellTypes->data[0]) != 0) {
     953                        psError(PS_ERR_UNKNOWN, true,
     954                                "Multiple instances of chip %s cell %s in contents, with differing cellType "
     955                                "(%s vs %s)", chipName, cellName, cellType, (char*)cellTypes->data[0]);
     956                        psFree(chipNames);
     957                        psFree(cellNames);
     958                        psFree(cellTypes);
     959                        psFree(testChipNames);
     960                        psFree(testCellNames);
     961                        psFree(testCellTypes);
     962                        psFree(iter);
     963                        psFree(cellType);
     964                        return false;
     965                    }
     966                } else {
     967                    cellType = psMemIncrRefCounter(cellTypes->data[0]);
     968                    chipNames = psMemIncrRefCounter(testChipNames);
     969                    cellNames = psMemIncrRefCounter(testCellNames);
     970                    cellTypes = psMemIncrRefCounter(testCellTypes);
     971                }
     972            }
     973            psFree(testChipNames);
     974            psFree(testCellNames);
     975            psFree(testCellTypes);
     976        }
     977        psFree(iter);
     978
     979        if (!cellType) {
     980            psError(PS_ERR_UNKNOWN, true, "Unable to identify cell type for chip %s cell %s",
     981                    chipName, cellName);
     982            psFree(chipNames);
     983            psFree(cellNames);
     984            psFree(cellTypes);
     985            return false;
     986        }
     987
     988        // We don't really care about the cell type here --- it's taken care of by processContents
     989        psFree(cellType);
     990
     991    } else {
     992        const char *content = getContent(fileInfo, phdu->header, contents); // Content of cell
     993
     994        if (parseContent(&chipNames, &cellNames, &cellTypes, content) != 1) {
     995            psError(PS_ERR_BAD_PARAMETER_VALUE, false,
     996                    "Unable to parse cell contents (%s) as cellName:cellType", content);
     997            psFree(chipNames);
     998            psFree(cellNames);
     999            psFree(cellTypes);
     1000            return false;
     1001        }
     1002
     1003        int chipNum = pmFPAFindChip(fpa, chipNames->data[0]); // Chip number
     1004        if (chipNum == -1) {
     1005            psError(PS_ERR_UNKNOWN, false, "Unable to find chip %s referred to in contents",
     1006                    (char*)chipNames->data[0]);
     1007            psFree(chipNames);
     1008            psFree(cellNames);
     1009            psFree(cellTypes);
     1010            return false;
     1011        }
     1012        chip = fpa->chips->data[chipNum];
     1013
     1014        int cellNum = pmChipFindCell(chip, cellNames->data[0]); // Cell number
     1015        if (cellNum == -1) {
     1016            psError(PS_ERR_UNKNOWN, false, "Unable to find cell %s referred to in contents",
     1017                    (char*)cellNames->data[0]);
     1018            psFree(chipNames);
     1019            psFree(cellNames);
     1020            psFree(cellTypes);
     1021            return false;
     1022        }
     1023        cell = chip->cells->data[cellNum];
     1024
     1025        view->chip = chipNum;
     1026        view->cell = cellNum;
     1027
     1028        psFree(chipNames);
    8721029        psFree(cellNames);
    8731030        psFree(cellTypes);
    874         return false;
    875     }
    876 
    877     if (!processContents(fpa, chip, cell, NULL, PM_FPA_LEVEL_NONE, NULL, cellNames, cellTypes, format)) {
     1031    }
     1032
     1033    if (!processContents(fpa, NULL, phdu, PM_FPA_LEVEL_NONE, chipNames, cellNames, cellTypes, format)) {
    8781034        psError(PS_ERR_UNKNOWN, false, "Unable to set contents for cell from camera format.");
     1035        psFree(chipNames);
    8791036        psFree(cellNames);
    8801037        psFree(cellTypes);
     
    8821039    }
    8831040
     1041    psFree(chipNames);
    8841042    psFree(cellNames);
    8851043    psFree(cellTypes);
     1044
     1045    if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_PHU, true, NULL)) {
     1046        psError(PS_ERR_UNKNOWN, false, "Unable to read concepts for cell.");
     1047        return false;
     1048    }
    8861049
    8871050    return true;
     
    9411104    pmFPAview *view = pmFPAviewAlloc(0); // View, to be returned
    9421105    if (phuView) {
    943         // Copy the view, for the case where we're given a header.
     1106        // Copy the view, for the case where we're given a view.
    9441107        *view = *phuView;
    9451108    }
     
    9571120    // Case    PHU     EXTENSIONS     Description
    9581121    // ====    ===     ==========     ===========
    959     // 1.      FPA     CHIP           CONTENTS(METADATA) has a list of extensions, each with a chip type.
     1122    // 1.      FPA     CHIP           CONTENTS(METADATA) has a list of extensions, each with chipName:chipType
    9601123    //                                CHIPS(METADATA) has a list of chip types, each with cell:type
    9611124    // 2.      FPA     CELL           CONTENTS(METADATA) has a list of extensions, each with chip:cell:type
     
    9631126    // 3.      FPA     NONE           CONTENTS(STRING) has a list of extensions, chip:cell:type
    9641127    //                                No need for CHIPS
    965     // 4.      CHIP    CELL           CONTENTS(METADATA) is a menu, each with a chip type
     1128    // 4.      CHIP    CELL           CONTENTS(METADATA) is a menu, each with a chipName:chipType
    9661129    //                                CHIPS(METADATA) has a list of chip types(METADATA), containg a list of
    9671130    //                                extensions.
    968     // 5.      CHIP    NONE           CONTENTS(METADATA) is a menu, each with a chip type
     1131    // 5.      CHIP    NONE           CONTENTS(METADATA) is a menu, each with a chipName:chipType
    9691132    //                                CHIPS(METADATA) has a list of chip types(STRING) with cell:type
    970     // 6.      CELL    NONE           CONTENTS(METADATA) is a menu, each with a cell type.
     1133    // 6.      CELL    NONE           CONTENTS(METADATA) is a menu, each with a chipName:cellName:cellType.
    9711134    //                                No need for CHIPS.
    9721135
     
    10321195      }
    10331196      case PM_FPA_LEVEL_CHIP: {
    1034           // Which chip is our PHU?
    1035           pmChip *chip = whichChip(view, fpa, phuView, fileInfo, header); // Chip of interest
    1036           if (!chip) {
    1037               psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip to add.");
    1038               psFree(phdu);
    1039               psFree(view);
    1040               return NULL;
     1197          pmChip *chip = NULL;          // Appropriate chip, if the view is specified
     1198          if (phuView) {
     1199              chip = fpa->chips->data[phuView->chip];
    10411200          }
    10421201          switch (extLevel) {
     
    10441203              if (install) {
    10451204                  phdu->blankPHU = true;
    1046                   if (!addHDUtoChip(chip, phdu) || !addSource_CHIP_CELL(chip, format) ||
    1047                       !pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_PHU,
    1048                                           true, true, NULL)) {
     1205                  if (!addSource_CHIP_CELL(view, fpa, chip, format, phdu)) {
    10491206                      psError(PS_ERR_UNKNOWN, false, "Unable to add source.");
    10501207                      psFree(phdu);
     
    10581215              if (install) {
    10591216                  phdu->blankPHU = false;
    1060                   if (!addHDUtoChip(chip, phdu) || !addSource_CHIP_NONE(chip, format) ||
    1061                       !pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_PHU,
    1062                                           true, true, NULL)) {
     1217                  if (!addSource_CHIP_NONE(view, fpa, chip, format, phdu)) {
    10631218                      psError(PS_ERR_UNKNOWN, false, "Unable to add source.");
    10641219                      psFree(phdu);
     
    10771232      }
    10781233      case PM_FPA_LEVEL_CELL: {
    1079           pmChip *chip = whichChip(view, fpa, phuView, fileInfo, header); // Chip of interest
    1080           if (!chip) {
    1081               psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find chip to add.");
    1082               psFree(phdu);
    1083               psFree(view);
    1084               return NULL;
    1085           }
    1086           pmCell *cell = whichCell(view, chip, phuView, fileInfo, header); // Cell of interest
    1087           if (!cell) {
    1088               psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find cell to add.");
    1089               psFree(phdu);
    1090               psFree(view);
    1091               return NULL;
    1092           }
    10931234          if (extLevel != PM_FPA_LEVEL_NONE) {
    10941235              psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     
    10961237              return NULL;
    10971238          }
     1239          pmChip *chip = NULL;          // Appropriate chip, if the view is specified
     1240          pmCell *cell = NULL;          // Appropriate cell, if the view is specified
     1241          if (phuView) {
     1242              chip = fpa->chips->data[phuView->chip];
     1243              cell = chip->cells->data[phuView->cell];
     1244          }
    10981245          if (install) {
    10991246              phdu->blankPHU = false;
    1100               if (!addHDUtoCell(cell, phdu) || !addSource_CELL_NONE(cell, format) ||
    1101                   !pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_DEFAULTS | PM_CONCEPT_SOURCE_PHU,
    1102                                       true, NULL)) {
     1247              if (!addSource_CELL_NONE(view, fpa, cell, format, phdu)) {
    11031248                  psError(PS_ERR_UNKNOWN, false, "Unable to add source.");
    11041249                  psFree(phdu);
Note: See TracChangeset for help on using the changeset viewer.