IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 8, 2006, 5:08:08 PM (20 years ago)
Author:
Paul Price
Message:

Broad changes to introduce pmHDU, and allow read/write at any level. Modified the camera configuration to use camera config (components of the camera) and format descriptions (FITS file layout).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c

    r6448 r6552  
    1111//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1212
    13 // Read data for a particular cell from the camera configuration
    14 static psMetadata *getCellData(const psMetadata *camera, // The camera configuration
     13// Read data for a particular cell from the camera format description
     14static psMetadata *getCellData(const psMetadata *format, // The camera format description
    1515                               const char *cellName // The name of the cell
    1616                              )
    1717{
    1818    bool status = true;                 // Result of MD lookup
    19     psMetadata *cells = psMetadataLookupMD(&status, camera, "CELLS"); // The CELLS
     19    psMetadata *cells = psMetadataLookupMD(&status, format, "CELLS"); // The CELLS
    2020    if (! status) {
    2121        psError(PS_ERR_IO, false, "Unable to determine CELLS of camera.\n");
     
    2828    }
    2929
    30     #if 0
    31     // Need to create a new instance, so that each cell can work with its own
    32     psMetadata *copy = psMetadataAlloc();
    33     psMetadataIterator *iter = psMetadataIteratorAlloc(cellData, PS_LIST_HEAD, NULL); // Iterator
    34     psMetadataItem *item = NULL;        // Item from iteration
    35     while (item = psMetadataGetAndIncrement(iter)) {
    36         if (item->type == PS_DATA_METADATA_MULTI || item->type == PS_DATA_METADATA) {
    37             psLogMsg(__func__, PS_LOG_WARN, "PS_DATA_METADATA_MULTI and PS_DATA_METADATA are not supported "
    38                      "in a cell definition --- %s ignored.\n", item->name);
     30    return cellData;
     31}
     32
     33// Find a chip by name
     34static pmChip *findChip(pmFPA *fpa, // FPA in which to find the chip
     35                        const char *name // Name of the chip
     36                       )
     37{
     38    psArray *chips = fpa->chips;    // Array of chips
     39    for (int i = 0; i < chips->n; i++) {
     40        pmChip *chip = chips->data[i]; // The chip of interest
     41        psString testName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); // Name of this chip
     42        if (strcmp(name, testName) == 0) {
     43            return chip;
     44        }
     45    }
     46
     47    psError(PS_ERR_IO, true, "Unable to find chip %s\n", name);
     48    return NULL;
     49}
     50
     51// Find a cell by name
     52static pmCell *findCell(pmChip *chip, // Chip in which to find the cell
     53                        const char *name // Name of the cell
     54                       )
     55{
     56    psArray *cells = chip->cells;    // Array of cells
     57    for (int i = 0; i < cells->n; i++) {
     58        pmCell *cell = cells->data[i]; // The cell of interest
     59        psString testName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of this cell
     60        if (strcmp(name, testName) == 0) {
     61            return cell;
     62        }
     63    }
     64
     65    psError(PS_ERR_IO, true, "Unable to find cell %s\n", name);
     66    return NULL;
     67}
     68
     69// Parse a list of first:second pairs in a string
     70static bool parsePairs(psArray **first, // Array of the first values
     71                       psArray **second, // Array of the second values
     72                       const char *string // The string to parse
     73                      )
     74{
     75    bool allOK = true;                  // Everything was OK?
     76    psList *pairs = psStringSplit(string, " ,;"); // List of the pairs
     77    *first = psArrayAlloc(pairs->n);
     78    *second = psArrayAlloc(pairs->n);
     79    int num = 0;
     80    psListIterator *pairsIter = psListIteratorAlloc(pairs, PS_LIST_HEAD, false); // Iterator for pairs
     81    psString pair = NULL;               // "first:second" pair string
     82    while ((pair = psListGetAndIncrement(pairsIter))) {
     83        psList *firstSecond = psStringSplit(pair, ":"); // List containing the first and second
     84        if (firstSecond->n != 2) {
     85            psLogMsg(__func__, PS_LOG_WARN, "Badly formated first:second pair: %s --- ignored.\n", pair);
     86            allOK = false;
    3987            continue;
    4088        }
    41         if (! psMetadataAdd(copy, PS_LIST_TAIL, item->name, item->type, item->comment, item->data.V)) {
    42             psAbort(__func__, "Should never reach here!\n");
    43         }
    44     }
    45     psFree(iter);
    46 
    47     return copy;
    48     #else
    49 
    50     return cellData;
    51     #endif
    52 
    53 }
    54 
     89        psString firstBit = psListGet(firstSecond, PS_LIST_HEAD); // The first bit
     90        psString secondBit = psListGet(firstSecond, PS_LIST_TAIL); // The second bit
     91        psArraySet(*first, num, firstBit);
     92        psArraySet(*second, num, secondBit);
     93        num++;
     94        psFree(firstSecond);
     95    }
     96    psFree(pairsIter);
     97    psFree(pairs);
     98
     99    return allOK;
     100}
     101
     102// Get the chip name from a primary header lookup
     103static psString chipNameFromHeader(const psMetadata *format, // FORMAT within the camera format description
     104                                   const psMetadata *header // Primary header
     105                                  )
     106{
     107    bool mdok = true;                   // Result of MD lookup
     108    psString chipNameHeader = psMetadataLookupStr(&mdok, format, "CHIP.NAME");
     109    if (!mdok || strlen(chipNameHeader) == 0) {
     110        psError(PS_ERR_IO, false, "Unable to find CHIP.NAME in the FORMAT.\n");
     111        return false;
     112    }
     113    psString chipName = psMetadataLookupStr(&mdok, header, chipNameHeader);
     114    if (!chipName || strlen(chipName) == 0) {
     115        psError(PS_ERR_IO, false, "Unable to find %s in primary header to identify chip name.\n", chipName);
     116        return NULL;
     117    }
     118
     119    return chipName;
     120}
    55121
    56122//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    58124//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    59125
     126// Construct an FPA instance on the basis of a camera configuration
     127pmFPA *pmFPAConstruct(const psMetadata *camera // The camera configuration
     128                     )
     129{
     130    pmFPA *fpa = pmFPAAlloc(camera);    // The FPA to fill out
     131
     132    bool mdok = true;                   // Status from MD lookups
     133    psMetadata *components = psMetadataLookupMD(&mdok, camera, "FPA"); // FPA components
     134    psMetadataIterator *componentsIter = psMetadataIteratorAlloc(components, PS_LIST_HEAD, NULL);
     135    psMetadataItem *componentsItem = NULL; // Item from components
     136    while ((componentsItem = psMetadataGetAndIncrement(componentsIter))) {
     137        const char *chipName = componentsItem->name; // Name of the chip
     138        if (componentsItem->type != PS_DATA_STRING) {
     139            psLogMsg(__func__, PS_LOG_WARN, "Element %s in FPA within the camera configuration is not of "
     140                     "type STR (type=%x) --- ignored.\n", chipName, componentsItem->type);
     141            continue;
     142        }
     143        pmChip *chip = pmChipAlloc(fpa, chipName); // The chip
     144        psList *cellNames = psStringSplit(componentsItem->data.V, " ,;"); // List of cell names
     145        psListIterator *cellNamesIter = psListIteratorAlloc(cellNames, PS_LIST_HEAD, false); // Iterator
     146        psString cellName = NULL;       // Name of cell
     147        while ((cellName = psListGetAndIncrement(cellNamesIter))) {
     148            pmCell *cell = pmCellAlloc(chip, cellName); // New cell
     149            psFree(cell);               // Drop reference
     150        }
     151        psFree(chip);                   // Drop reference
     152        psFree(cellNamesIter);
     153    }
     154    psFree(componentsIter);
     155
     156    return fpa;
     157}
     158
     159
     160// Add an input file to the FPA
     161bool pmFPAAddSource(pmFPA *fpa,         // FPA to which to add
     162                    pmChip *chip,       // Chip to which to add, or NULL
     163                    pmCell *cell,       // Cell to which to add, or NULL
     164                    psMetadata *phu,    // Primary header of file
     165                    const psMetadata *format // Format of file
     166                   )
     167{
     168    // Just in case someone's playing silly billy...
     169    if (cell && !chip) {
     170        chip = cell->parent;
     171    }
     172    if (chip && !fpa) {
     173        fpa = chip->parent;
     174    }
     175
     176    bool mdok = true;                   // Status from metadata lookups
     177    psMetadata *formatSpec = psMetadataLookupMD(&mdok, format, "FORMAT"); // The format specification
     178    if (!mdok || !formatSpec) {
     179        psError(PS_ERR_IO, false, "Unable to find FORMAT in the camera format configuration.\n");
     180        return false;
     181    }
     182
     183    // Where does the PHU go?
     184    const char *phuType = psMetadataLookupStr(&mdok, formatSpec, "PHU"); // What is the PHU?
     185    if (!mdok || strlen(phuType) == 0) {
     186        psError(PS_ERR_IO, false, "Unable to find PHU in the format specification.\n");
     187        return false;
     188    }
     189    pmHDU *phdu = pmHDUAlloc("PHU");    // The primary header data unit
     190    phdu->header = psMemIncrRefCounter(phu);
     191    if (fpa && !fpa->hdu && strcasecmp(phuType, "FPA") == 0) {
     192        fpa->hdu = phdu;
     193    } else if (chip && !chip->hdu && strcasecmp(phuType, "CHIP") == 0) {
     194        chip->hdu = phdu;
     195    } else if (cell && !cell->hdu && strcasecmp(phuType, "CELL") == 0) {
     196        // cell->hdu = phdu;
     197        psError(PS_ERR_IO, true, "The case of PHU == CELL has not been written yet!\n");
     198        return false;
     199    }
     200
     201    // And the individual extensions?
     202    const char *extType = psMetadataLookupStr(&mdok, formatSpec, "EXTENSIONS"); // What's in the extns?
     203    if (!mdok || strlen(extType) == 0) {
     204        psError(PS_ERR_IO, false, "Unable to find EXTENSIONS in the format specification.\n");
     205        return false;
     206    }
     207    psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
     208    if (!mdok || !contents) {
     209        psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n");
     210        return false;
     211    }
     212
     213    if (strcasecmp(extType, "NONE") == 0) {
     214        // No extensions --- it's all in the PHU
     215        psString chipType = chipNameFromHeader(formatSpec, phu); // Type of chip
     216        psString content = psMetadataLookupStr(&mdok, contents, chipType); // The content line
     217
     218        // Parse the list of first:second
     219        psArray *names = NULL;          // The first bits
     220        psArray *values = NULL;         // The second bits
     221        parsePairs(&names, &values, content);
     222        for (int i = 0; i < names->n; i++) {
     223            psString chipName = names->data[i]; // The name of the chip
     224            psString cellName = values->data[i]; // The name of the cell
     225            pmChip *chip = findChip(fpa, chipName); // The chip we're looking for
     226            pmCell *cell = findCell(chip, cellName); // The cell we're looking for
     227            psMetadata *cellData = getCellData(format, cellName); // Data for this cell
     228            if (! cellData) {
     229                psLogMsg(__func__, PS_LOG_WARN, "Unable to find data for %s in CELLS --- ignored.\n",
     230                         cellName);
     231                continue;
     232            }
     233
     234            // Have already plugged in the PHU
     235
     236            // Put in the cell data
     237            if (cell->config) {
     238                psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
     239                         cellName);
     240                psFree(cell->config); // Make way!
     241            }
     242            cell->config = psMemIncrRefCounter(cellData);
     243        }
     244    }
     245
     246
     247    // Go through the contents
     248    psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
     249    psMetadataItem *contentsItem = NULL; // Item from contents
     250    while ((contentsItem = psMetadataGetAndIncrement(contentsIter))) {
     251        const char *extName = contentsItem->name;
     252        if (contentsItem->type != PS_DATA_STRING) {
     253            psLogMsg(__func__, PS_LOG_WARN, "CONTENTS item %s is not of type STR --- ignored.\n", extName);
     254            continue;
     255        }
     256
     257        pmHDU *hdu = pmHDUAlloc(extName); // The extension
     258
     259        // Parse the list of first:second
     260        psArray *names = NULL;          // The first bits
     261        psArray *values = NULL;         // The second bits
     262        parsePairs(&names, &values, contentsItem->data.V);
     263
     264        // XXX Memory problems in here --> leaks and/or double frees???
     265        if (strcasecmp(extType, "CHIP") == 0) {
     266            // Extensions are chips
     267            for (int i = 0; i < names->n; i++) {
     268                psString chipName = names->data[i]; // The name of the chip
     269                psString cellName = values->data[i]; // The name of the cell
     270                pmChip *chip = findChip(fpa, chipName); // The chip we're looking for
     271                pmCell *cell = findCell(chip, cellName); // The cell we're looking for
     272                psMetadata *cellData = getCellData(format, cellName); // Data for this cell
     273                if (! cellData) {
     274                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find data for %s in CELLS --- ignored.\n",
     275                             cellName);
     276                    continue;
     277                }
     278
     279                // Put in the extension
     280                if (chip->hdu) {
     281                    psLogMsg(__func__, PS_LOG_WARN, "Overwriting HDU in chip %s\n", chipName);
     282                    psFree(chip->hdu);  // Make way!
     283                }
     284                chip->hdu = psMemIncrRefCounter(hdu);
     285
     286                // Put in the cell data
     287                if (cell->config) {
     288                    psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
     289                             cellName);
     290                    psFree(cell->config); // Make way!
     291                }
     292                cell->config = psMemIncrRefCounter(cellData);
     293            }
     294
     295        } else if (strcasecmp(extType, "CELL") == 0) {
     296            // Extensions are cells
     297            psString chipName = NULL;   // Name of chip under consideration
     298            pmChip *chip = NULL;        // The chip we're looking for
     299            if (! fpa->hdu->phu) {
     300                // Need to look up the name of the chip
     301                chipName = chipNameFromHeader(formatSpec, phu);
     302                chip = findChip(fpa, chipName);
     303            }
     304            for (int i = 0; i < names->n; i++) {
     305                psString cellType = values->data[i]; // The type of the cell
     306                psString cellName = NULL; // The name of the cell
     307                if (fpa->hdu->phu) {
     308                    // We've got chipName:cellType with cellType == cellName
     309                    chipName = names->data[i];
     310                    cellName = cellType;
     311                    chip = findChip(fpa, chipName);
     312                } else {
     313                    // We've got cellName:cellType and the chipName comes from before
     314                    cellName = names->data[i];
     315                }
     316                psMetadata *cellData = getCellData(format, cellType); // Data for this cell
     317                pmCell *cell = findCell(chip, cellName); // The cell we're looking for
     318
     319                // Put in the extension
     320                if (cell->hdu) {
     321                    psLogMsg(__func__, PS_LOG_WARN, "Overwriting HDU in chip %s, cell %s\n", chipName,
     322                             cellName);
     323                    psFree(cell->hdu);
     324                }
     325                cell->hdu = psMemIncrRefCounter(hdu);
     326
     327                // Put in the cell data
     328                if (cell->config) {
     329                    psLogMsg(__func__, PS_LOG_WARN, "Overwriting cell data in chip %s, cell %s\n", chipName,
     330                             cellName);
     331                    psFree(cell->config);
     332                }
     333                cell->config = psMemIncrRefCounter(cellData);
     334            }
     335
     336        }
     337        psFree(hdu);
     338        psFree(names);
     339        psFree(values);
     340    }
     341    psFree(contentsIter);
     342
     343    return true;
     344}
     345
     346
     347
     348
     349#if 0
    60350pmFPA *pmFPAConstruct(const psMetadata *camera // The camera configuration
    61351                     )
     
    270560    return fpa;
    271561}
     562#endif
     563
    272564
    273565// Print out the focal plane structure
    274 void pmFPAPrint(pmFPA *fpa              // FPA to print
     566void pmFPAPrint(pmFPA *fpa,             // FPA to print
     567                bool concepts           // Print concepts?
    275568               )
    276569{
     
    279572        psTrace(__func__, 2, "---> FPA is extension %s.\n", fpa->hdu->extname);
    280573        if (! fpa->hdu->images) {
    281             psTrace(__func__, 2, "---> NO PIXELS for extension %s\n", fpa->hdu->extname);
    282         }
    283     }
    284     psMetadataPrint(fpa->concepts, 2);
     574            psTrace(__func__, 2, "---> NO PIXELS read in for extension %s\n", fpa->hdu->extname);
     575        }
     576    }
     577    if (concepts) {
     578        psMetadataPrint(fpa->concepts, 2);
     579    }
    285580
    286581    psArray *chips = fpa->chips;        // Array of chips
     
    292587            psTrace(__func__, 4, "---> Chip is extension %s.\n", chip->hdu->extname);
    293588            if (! chip->hdu->images) {
    294                 psTrace(__func__, 4, "---> NO PIXELS for extension %s\n", chip->hdu->extname);
    295             }
    296         }
    297         psMetadataPrint(chip->concepts, 4);
     589                psTrace(__func__, 4, "---> NO PIXELS read in for extension %s\n", chip->hdu->extname);
     590            }
     591        }
     592        if (concepts) {
     593            psMetadataPrint(chip->concepts, 4);
     594        }
    298595
    299596        // Iterate over the chip
     
    305602                psTrace(__func__, 6, "---> Cell is extension %s.\n", cell->hdu->extname);
    306603                if (! cell->hdu->images) {
    307                     psTrace(__func__, 6, "---> NO PIXELS for extension %s\n", cell->hdu->extname);
    308                 }
    309             }
    310             psMetadataPrint(cell->concepts, 6);
     604                    psTrace(__func__, 6, "---> NO PIXELS read in for extension %s\n", cell->hdu->extname);
     605                }
     606            }
     607            if (concepts) {
     608                psMetadataPrint(cell->concepts, 6);
     609            }
    311610
    312611            psTrace(__func__, 7, "Readouts:\n");
Note: See TracChangeset for help on using the changeset viewer.