IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6734


Ignore:
Timestamp:
Mar 30, 2006, 10:08:30 AM (20 years ago)
Author:
Paul Price
Message:

pmFPACopy now working

Location:
branches/rel10_ifa/psModules/src
Files:
14 edited

Legend:

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

    r6618 r6734  
    7676
    7777// Set all registered concepts to blank value for the specified level
    78 static bool conceptsBlank(psMetadata **specs,  // One of the concepts specifications
     78static bool conceptsBlank(psMetadata **specs, // One of the concepts specifications
    7979                          psMetadata *target // Place to install the concepts
    8080                         )
     
    8989        pmConceptSpec *spec = specItem->data.V; // The specification
    9090        psMetadataItem *blank = spec->blank; // The concept
    91         psMetadataAddItem(target, blank, PS_LIST_TAIL, PS_META_REPLACE);
     91        psMetadataItem *copy = NULL;    // Copy of the blank concept
     92        // Trap the lists, which can't be copied in the ordinary way without a warning
     93        if (blank->type == PS_DATA_LIST) {
     94            copy = psMetadataItemAlloc(blank->name, PS_DATA_LIST, blank->comment, blank->data.V);
     95        } else {
     96            copy = psMetadataItemCopy(blank);
     97        }
     98        if (!psMetadataAddItem(target, copy, PS_LIST_TAIL, PS_META_REPLACE)) {
     99            psLogMsg(__func__, PS_LOG_WARN, "Unable to add blank version of concept %s\n", blank->name);
     100        }
    92101    }
    93102    psFree(specsIter);
     
    158167}
    159168
    160 #if 0
    161 bool pmConceptsRead(pmFPAview *view,
    162                     pmFPAlevel levels,
    163                     pmConceptSource source,
    164                     psDB *db
    165                    )
    166 {
    167     pmFPA *fpa = view->fpa;             // The FPA
    168 
    169     #endif
    170 
    171     // Set the concepts for a given FPA to blanks
    172     bool pmConceptsBlankFPA(pmFPA *fpa    // FPA for which to set blank concepts
    173                            ) {
    174         psTrace("psModule.concepts", 5, "Blanking FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
    175         return conceptsBlank(&conceptsFPA, fpa->concepts);
    176     }
    177 
    178     // Read the concepts for a given FPA
    179     bool pmConceptsReadFPA(pmFPA *fpa,      // FPA for which to read concepts
    180                            pmConceptSource source, // The source of the concepts to read
    181                            psDB *db         // Database handle
    182                           ) {
    183         psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
    184         return conceptsRead(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
    185     }
    186 
    187     // Read the concepts for a given FPA
    188     bool pmConceptsWriteFPA(pmFPA *fpa,     // FPA for which to write concepts
    189                             pmConceptSource source, // The source of the concepts to read
    190                             psDB *db        // Database handle
    191                            ) {
    192         psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
    193         return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
    194     }
    195 
    196     // Set the concepts for a given chip to blanks
    197     bool pmConceptsBlankChip(pmChip *chip // FPA for which to set blank concepts
    198                             ) {
    199         psTrace("psModule.concepts", 5, "Blanking chip concepts: %x %x\n", conceptsChip, chip->concepts);
    200         return conceptsBlank(&conceptsChip, chip->concepts);
    201     }
    202 
    203     // Read the concepts for a given FPA
    204     bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
    205                             pmConceptSource source, // The source of the concepts to read
    206                             bool propagate, // Propagate to higher levels as well?
    207                             psDB *db        // Database handle
    208                            ) {
    209         psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts);
    210         pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
    211         return conceptsRead(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) &&
    212                ((propagate && conceptsRead(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) ||
    213                 !propagate);
    214     }
    215 
    216     // Read the concepts for a given FPA
    217     bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
    218                              pmConceptSource source, // The source of the concepts to read
    219                              bool propagate,// Propagate to higher levels as well?
    220                              psDB *db        // Database handle
    221                             ) {
    222         psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts);
    223         pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
    224         return conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) &&
    225                ((propagate && conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) ||
    226                 !propagate);
    227     }
    228 
    229     // Set the concepts for a given chip to blanks
    230     bool pmConceptsBlankCell(pmCell *cell // Cell for which to set blank concepts
    231                             ) {
    232         psTrace("psModule.concepts", 5, "Blanking cell concepts: %x %x\n", conceptsCell, cell->concepts);
    233         return conceptsBlank(&conceptsCell, cell->concepts);
    234     }
    235 
    236     // Read the concepts for a given FPA
    237     bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
    238                             pmConceptSource source, // The source of the concepts to read
    239                             bool propagate,// Propagate to higher levels as well?
    240                             psDB *db        // Database handle
    241                            ) {
    242         psTrace("psModule.concepts", 5, "Reading cell concepts: %x %x\n", conceptsCell, cell->concepts);
    243         pmChip *chip = cell->parent;        // Chip to which the cell belongs
    244         pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
    245         return conceptsRead(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) &&
    246                ((propagate && conceptsRead(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) &&
    247                  conceptsRead(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate);
    248     }
    249 
    250     // Read the concepts for a given FPA
    251     bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
    252                              pmConceptSource source, // The source of the concepts to read
    253                              bool propagate,// Propagate to higher levels as well?
    254                              psDB *db       // Database handle
    255                             ) {
    256         psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts);
    257         pmChip *chip = cell->parent;        // Chip to which the cell belongs
    258         pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
    259         return conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) &&
    260                ((propagate && conceptsWrite(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) &&
    261                  conceptsWrite(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate);
    262     }
    263 
    264 
    265     bool pmConceptsInit(void) {
    266         bool init = false;                  // Did we initialise anything?
    267         if (! conceptsFPA) {
    268             conceptsFPA = psMetadataAlloc();
    269             init = true;
    270 
    271             // Install the standard concepts
    272 
    273             #if 0
    274             // FPA.NAME
    275             {
    276                 psMetadataItem *fpaName = psMetadataItemAllocStr("FPA.NAME", "Name of FPA", "");
    277                 pmConceptRegister(fpaName, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
    278                 psFree(fpaName);
    279             }
    280             #endif
    281 
    282             // FPA.AIRMASS
    283             {
    284                 psMetadataItem *fpaAirmass = psMetadataItemAllocF32("FPA.AIRMASS", "Airmass at boresight", 0.0);
    285                 pmConceptRegister(fpaAirmass, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
    286                 psFree(fpaAirmass);
    287             }
    288 
    289             // FPA.FILTER
    290             {
    291                 psMetadataItem *fpaFilter = psMetadataItemAllocStr("FPA.FILTER", "Filter used", "");
    292                 pmConceptRegister(fpaFilter, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
    293                 psFree(fpaFilter);
    294             }
    295 
    296             // FPA.POSANGLE
    297             {
    298                 psMetadataItem *fpaPosangle = psMetadataItemAllocF32("FPA.POSANGLE",
    299                                               "Position angle of instrument", 0.0);
    300                 pmConceptRegister(fpaPosangle, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
    301                 psFree(fpaPosangle);
    302             }
    303 
    304             // FPA.RADECSYS
    305             {
    306                 psMetadataItem *fpaRadecsys = psMetadataItemAllocStr("FPA.RADECSYS",
    307                                               "Celestial coordinate system", "");
    308                 pmConceptRegister(fpaRadecsys, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
    309                 psFree(fpaRadecsys);
    310             }
    311 
    312             // FPA.RA
    313             {
    314                 psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN);
    315                 pmConceptRegister(fpaRa, (pmConceptParseFunc)pmConceptParse_FPA_Coords,
    316                                   (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA);
    317                 psFree(fpaRa);
    318             }
    319 
    320             // FPA.DEC
    321             {
    322                 psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN);
    323                 pmConceptRegister(fpaDec, (pmConceptParseFunc)pmConceptParse_FPA_Coords,
    324                                   (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA);
    325                 psFree(fpaDec);
    326             }
    327 
    328             // Done with FPA level concepts
    329         }
    330         if (! conceptsChip) {
    331             conceptsChip = psMetadataAlloc();
    332             init = true;
    333             // There are no standard concepts at the chip level to be installed
    334         }
    335         if (! conceptsCell) {
    336             conceptsCell = psMetadataAlloc();
    337             init = true;
    338 
    339             // Install the standard concepts
    340 
    341             // CELL.GAIN
    342             {
    343                 psMetadataItem *cellGain = psMetadataItemAllocF32("CELL.GAIN", "CCD gain (e/count)", NAN);
    344                 pmConceptRegister(cellGain, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    345                 psFree(cellGain);
    346             }
    347 
    348             // CELL.READNOISE
    349             {
    350                 psMetadataItem *cellReadnoise = psMetadataItemAllocF32("CELL.READNOISE",
    351                                                 "CCD read noise (e)", NAN);
    352                 pmConceptRegister(cellReadnoise, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    353                 psFree(cellReadnoise);
    354             }
    355 
    356             // CELL.SATURATION
    357             {
    358                 psMetadataItem *cellSaturation = psMetadataItemAllocF32("CELL.SATURATION",
    359                                                  "Saturation level (counts)", NAN);
    360                 pmConceptRegister(cellSaturation, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    361                 psFree(cellSaturation);
    362             }
    363 
    364             // CELL.BAD
    365             {
    366                 psMetadataItem *cellBad = psMetadataItemAllocF32("CELL.BAD", "Bad level (counts)", NAN);
    367                 pmConceptRegister(cellBad, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    368                 psFree(cellBad);
    369             }
    370 
    371             // CELL.XPARITY
    372             {
    373                 psMetadataItem *cellXparity = psMetadataItemAllocS32("CELL.XPARITY",
    374                                               "Orientation in x compared to the rest of the FPA", 0);
    375                 pmConceptRegister(cellXparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    376                 psFree(cellXparity);
    377             }
    378 
    379             // CELL.YPARITY
    380             {
    381                 psMetadataItem *cellYparity = psMetadataItemAllocS32("CELL.YPARITY",
    382                                               "Orientation in x compared to the rest of the FPA", 0);
    383                 pmConceptRegister(cellYparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    384                 psFree(cellYparity);
    385             }
    386 
    387             // CELL.READDIR
    388             {
    389                 psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR",
    390                                               "Read direction, rows=1, cols=2", 1);
    391                 pmConceptRegister(cellReaddir, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    392                 psFree(cellReaddir);
    393             }
    394 
    395 
    396             // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that
    397             // doesn't really make sense at the moment.  Maybe we need to add a "parent" link to the readouts.
    398             // But then how are the exposure times REALLY derived?  They're not in the FITS headers, because a
    399             // readout is a plane in a 3D image.  We'll have to dream up some additional suffix to specify these,
    400             // but for now....
    401 
    402             // CELL.EXPOSURE
    403             {
    404                 psMetadataItem *cellExposure = psMetadataItemAllocF32("CELL.EXPOSURE",
    405                                                "Exposure time (sec)", NAN);
    406                 pmConceptRegister(cellExposure, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    407                 psFree(cellExposure);
    408             }
    409 
    410             // CELL.DARKTIME
    411             {
    412                 psMetadataItem *cellDarktime = psMetadataItemAllocF32("CELL.DARKTIME",
    413                                                "Time since flush (sec)", NAN);
    414                 pmConceptRegister(cellDarktime, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
    415                 psFree(cellDarktime);
    416             }
    417 
    418             // CELL.TRIMSEC
    419             {
    420                 psRegion *trimsec = psAlloc(sizeof(psRegion)); // Blank trimsec
    421                 trimsec->x0 = trimsec->y0 = trimsec->x1 = trimsec->y1 = NAN;
    422                 psMetadataItem *cellTrimsec = psMetadataItemAllocPtr("CELL.TRIMSEC", PS_DATA_UNKNOWN,
    423                                               "Trim section", trimsec);
    424                 psFree(trimsec);
    425                 pmConceptRegister(cellTrimsec, (pmConceptParseFunc)pmConceptParse_CELL_TRIMSEC,
    426                                   (pmConceptFormatFunc)pmConceptFormat_CELL_TRIMSEC, PM_CONCEPT_LEVEL_CELL);
    427                 psFree(cellTrimsec);
    428             }
    429 
    430             // CELL.BIASSEC
    431             {
    432                 psList *biassecs = psListAlloc(NULL); // Blank biassecs
    433                 psMetadataItem *cellBiassec = psMetadataItemAllocPtr("CELL.BIASSEC", PS_DATA_LIST,
    434                                               "Bias sections", biassecs);
    435                 psFree(biassecs);
    436                 pmConceptRegister(cellBiassec, (pmConceptParseFunc)pmConceptParse_CELL_BIASSEC,
    437                                   (pmConceptFormatFunc)pmConceptFormat_CELL_BIASSEC, PM_CONCEPT_LEVEL_CELL);
    438                 psFree(cellBiassec);
    439             }
    440 
    441             // CELL.XBIN
    442             {
    443                 psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0);
    444                 pmConceptRegister(cellXbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning,
    445                                   (pmConceptFormatFunc)pmConceptFormat_CELL_XBIN, PM_CONCEPT_LEVEL_CELL);
    446                 psFree(cellXbin);
    447             }
    448 
    449             // CELL.YBIN
    450             {
    451                 psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0);
    452                 pmConceptRegister(cellYbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning,
    453                                   (pmConceptFormatFunc)pmConceptFormat_CELL_YBIN, PM_CONCEPT_LEVEL_CELL);
    454                 psFree(cellYbin);
    455             }
    456 
    457             // CELL.TIMESYS
    458             {
    459                 psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1);
    460                 pmConceptRegister(cellTimesys, (pmConceptParseFunc)pmConceptParse_CELL_TIMESYS,
    461                                   (pmConceptFormatFunc)pmConceptFormat_CELL_TIMESYS, PM_CONCEPT_LEVEL_CELL);
    462                 psFree(cellTimesys);
    463             }
    464 
    465             // CELL.TIME
    466             {
    467                 psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time
    468                 // Not particularly distinguishing, but should be good enough
    469                 time->sec = 0;
    470                 time->nsec = 0;
    471                 psMetadataItem *cellTime = psMetadataItemAlloc("CELL.TIME", PS_DATA_TIME,
    472                                            "Time of exposure", time);
    473                 psFree(time);
    474                 pmConceptRegister(cellTime, (pmConceptParseFunc)pmConceptParse_CELL_TIME,
    475                                   (pmConceptFormatFunc)pmConceptFormat_CELL_TIME, PM_CONCEPT_LEVEL_CELL);
    476                 psFree(cellTime);
    477             }
    478 
    479             // CELL.X0
    480             {
    481                 psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0);
    482                 pmConceptRegister(cellX0, (pmConceptParseFunc)pmConceptParse_CELL_Positions,
    483                                   (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL);
    484                 psFree(cellX0);
    485             }
    486 
    487             // CELL.Y0
    488             {
    489                 psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0);
    490                 pmConceptRegister(cellY0, (pmConceptParseFunc)pmConceptParse_CELL_Positions,
    491                                   (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL);
    492                 psFree(cellY0);
    493             }
    494 
    495         }
    496 
    497         conceptsInitialised = true;
    498 
    499         return init;
    500     }
    501 
    502     void pmConceptsDone(void) {
    503         psFree(conceptsFPA);
    504         psFree(conceptsChip);
    505         psFree(conceptsCell);
    506     }
    507 
    508 
    509     // Copy concepts from one FPA to another
    510     bool pmFPACopyConcepts(pmFPA *target,   // The target FPA
    511                            pmFPA *source    // The target FPA
    512                           ) {
    513         // Copy FPA concepts
    514         target->concepts = psMetadataCopy(target->concepts, source->concepts);
    515 
    516         // Copy chip concepts
    517         psArray *targetChips = target->chips; // Chips in target
    518         psArray *sourceChips = source->chips; // Chips in source
    519         if (targetChips->n != sourceChips->n) {
    520             psError(PS_ERR_IO, true, "Number of chips in target (%d) and source (%d) differ --- unable to copy "
    521                     "concepts.\n", targetChips->n, sourceChips->n);
     169// Set the concepts for a given FPA to blanks
     170bool pmConceptsBlankFPA(pmFPA *fpa    // FPA for which to set blank concepts
     171                       )
     172{
     173    psTrace("psModule.concepts", 5, "Blanking FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
     174    return conceptsBlank(&conceptsFPA, fpa->concepts);
     175}
     176
     177
     178// Read the concepts for a given FPA
     179bool pmConceptsReadFPA(pmFPA *fpa,      // FPA for which to read concepts
     180                       pmConceptSource source, // The source of the concepts to read
     181                       psDB *db         // Database handle
     182                      )
     183{
     184    psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
     185    return conceptsRead(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
     186}
     187
     188// Read the concepts for a given FPA
     189bool pmConceptsWriteFPA(pmFPA *fpa,     // FPA for which to write concepts
     190                        pmConceptSource source, // The source of the concepts to read
     191                        psDB *db        // Database handle
     192                       )
     193{
     194    psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts);
     195    return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts);
     196}
     197
     198// Set the concepts for a given chip to blanks
     199bool pmConceptsBlankChip(pmChip *chip // FPA for which to set blank concepts
     200                        )
     201{
     202    psTrace("psModule.concepts", 5, "Blanking chip concepts: %x %x\n", conceptsChip, chip->concepts);
     203    return conceptsBlank(&conceptsChip, chip->concepts);
     204}
     205
     206// Read the concepts for a given FPA
     207bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
     208                        pmConceptSource source, // The source of the concepts to read
     209                        bool propagate, // Propagate to higher levels as well?
     210                        psDB *db        // Database handle
     211                       )
     212{
     213    psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts);
     214    pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
     215    return conceptsRead(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) &&
     216           ((propagate && conceptsRead(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) ||
     217            !propagate);
     218}
     219
     220// Read the concepts for a given FPA
     221bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
     222                         pmConceptSource source, // The source of the concepts to read
     223                         bool propagate,// Propagate to higher levels as well?
     224                         psDB *db        // Database handle
     225                        )
     226{
     227    psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts);
     228    pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
     229    return conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) &&
     230           ((propagate && conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) ||
     231            !propagate);
     232}
     233
     234// Set the concepts for a given chip to blanks
     235bool pmConceptsBlankCell(pmCell *cell // Cell for which to set blank concepts
     236                        )
     237{
     238    psTrace("psModule.concepts", 5, "Blanking cell concepts: %x %x\n", conceptsCell, cell->concepts);
     239    return conceptsBlank(&conceptsCell, cell->concepts);
     240}
     241
     242// Read the concepts for a given FPA
     243bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
     244                        pmConceptSource source, // The source of the concepts to read
     245                        bool propagate,// Propagate to higher levels as well?
     246                        psDB *db        // Database handle
     247                       )
     248{
     249    psTrace("psModule.concepts", 5, "Reading cell concepts: %x %x\n", conceptsCell, cell->concepts);
     250    pmChip *chip = cell->parent;        // Chip to which the cell belongs
     251    pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
     252    return conceptsRead(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) &&
     253           ((propagate && conceptsRead(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) &&
     254             conceptsRead(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate);
     255}
     256
     257// Read the concepts for a given FPA
     258bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
     259                         pmConceptSource source, // The source of the concepts to read
     260                         bool propagate,// Propagate to higher levels as well?
     261                         psDB *db       // Database handle
     262                        )
     263{
     264    psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts);
     265    pmChip *chip = cell->parent;        // Chip to which the cell belongs
     266    pmFPA *fpa = chip->parent;          // FPA to which the chip belongs
     267    return conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) &&
     268           ((propagate && conceptsWrite(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) &&
     269             conceptsWrite(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate);
     270}
     271
     272
     273bool pmConceptsInit(void)
     274{
     275    bool init = false;                  // Did we initialise anything?
     276    if (! conceptsFPA) {
     277        conceptsFPA = psMetadataAlloc();
     278        init = true;
     279
     280        // Install the standard concepts
     281
     282        #if 0
     283        // FPA.NAME
     284        {
     285            psMetadataItem *fpaName = psMetadataItemAllocStr("FPA.NAME", "Name of FPA", "");
     286            pmConceptRegister(fpaName, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
     287            psFree(fpaName);
     288        }
     289        #endif
     290
     291        // FPA.AIRMASS
     292        {
     293            psMetadataItem *fpaAirmass = psMetadataItemAllocF32("FPA.AIRMASS", "Airmass at boresight", 0.0);
     294            pmConceptRegister(fpaAirmass, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
     295            psFree(fpaAirmass);
     296        }
     297
     298        // FPA.FILTER
     299        {
     300            psMetadataItem *fpaFilter = psMetadataItemAllocStr("FPA.FILTER", "Filter used", "");
     301            pmConceptRegister(fpaFilter, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
     302            psFree(fpaFilter);
     303        }
     304
     305        // FPA.POSANGLE
     306        {
     307            psMetadataItem *fpaPosangle = psMetadataItemAllocF32("FPA.POSANGLE",
     308                                          "Position angle of instrument", 0.0);
     309            pmConceptRegister(fpaPosangle, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
     310            psFree(fpaPosangle);
     311        }
     312
     313        // FPA.RADECSYS
     314        {
     315            psMetadataItem *fpaRadecsys = psMetadataItemAllocStr("FPA.RADECSYS",
     316                                          "Celestial coordinate system", "");
     317            pmConceptRegister(fpaRadecsys, NULL, NULL, PM_CONCEPT_LEVEL_FPA);
     318            psFree(fpaRadecsys);
     319        }
     320
     321        // FPA.RA
     322        {
     323            psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN);
     324            pmConceptRegister(fpaRa, (pmConceptParseFunc)pmConceptParse_FPA_Coords,
     325                              (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA);
     326            psFree(fpaRa);
     327        }
     328
     329        // FPA.DEC
     330        {
     331            psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN);
     332            pmConceptRegister(fpaDec, (pmConceptParseFunc)pmConceptParse_FPA_Coords,
     333                              (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA);
     334            psFree(fpaDec);
     335        }
     336
     337        // Done with FPA level concepts
     338    }
     339    if (! conceptsChip) {
     340        conceptsChip = psMetadataAlloc();
     341        init = true;
     342        // There are no standard concepts at the chip level to be installed
     343    }
     344    if (! conceptsCell) {
     345        conceptsCell = psMetadataAlloc();
     346        init = true;
     347
     348        // Install the standard concepts
     349
     350        // CELL.GAIN
     351        {
     352            psMetadataItem *cellGain = psMetadataItemAllocF32("CELL.GAIN", "CCD gain (e/count)", NAN);
     353            pmConceptRegister(cellGain, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     354            psFree(cellGain);
     355        }
     356
     357        // CELL.READNOISE
     358        {
     359            psMetadataItem *cellReadnoise = psMetadataItemAllocF32("CELL.READNOISE",
     360                                            "CCD read noise (e)", NAN);
     361            pmConceptRegister(cellReadnoise, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     362            psFree(cellReadnoise);
     363        }
     364
     365        // CELL.SATURATION
     366        {
     367            psMetadataItem *cellSaturation = psMetadataItemAllocF32("CELL.SATURATION",
     368                                             "Saturation level (counts)", NAN);
     369            pmConceptRegister(cellSaturation, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     370            psFree(cellSaturation);
     371        }
     372
     373        // CELL.BAD
     374        {
     375            psMetadataItem *cellBad = psMetadataItemAllocF32("CELL.BAD", "Bad level (counts)", NAN);
     376            pmConceptRegister(cellBad, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     377            psFree(cellBad);
     378        }
     379
     380        // CELL.XPARITY
     381        {
     382            psMetadataItem *cellXparity = psMetadataItemAllocS32("CELL.XPARITY",
     383                                          "Orientation in x compared to the rest of the FPA", 0);
     384            pmConceptRegister(cellXparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     385            psFree(cellXparity);
     386        }
     387
     388        // CELL.YPARITY
     389        {
     390            psMetadataItem *cellYparity = psMetadataItemAllocS32("CELL.YPARITY",
     391                                          "Orientation in x compared to the rest of the FPA", 0);
     392            pmConceptRegister(cellYparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     393            psFree(cellYparity);
     394        }
     395
     396        // CELL.READDIR
     397        {
     398            psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR",
     399                                          "Read direction, rows=1, cols=2", 1);
     400            pmConceptRegister(cellReaddir, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     401            psFree(cellReaddir);
     402        }
     403
     404
     405        // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that
     406        // doesn't really make sense at the moment.  Maybe we need to add a "parent" link to the readouts.
     407        // But then how are the exposure times REALLY derived?  They're not in the FITS headers, because a
     408        // readout is a plane in a 3D image.  We'll have to dream up some additional suffix to specify these,
     409        // but for now....
     410
     411        // CELL.EXPOSURE
     412        {
     413            psMetadataItem *cellExposure = psMetadataItemAllocF32("CELL.EXPOSURE",
     414                                           "Exposure time (sec)", NAN);
     415            pmConceptRegister(cellExposure, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     416            psFree(cellExposure);
     417        }
     418
     419        // CELL.DARKTIME
     420        {
     421            psMetadataItem *cellDarktime = psMetadataItemAllocF32("CELL.DARKTIME",
     422                                           "Time since flush (sec)", NAN);
     423            pmConceptRegister(cellDarktime, NULL, NULL, PM_CONCEPT_LEVEL_CELL);
     424            psFree(cellDarktime);
     425        }
     426
     427        // CELL.TRIMSEC
     428        {
     429            psRegion *trimsec = psAlloc(sizeof(psRegion)); // Blank trimsec
     430            trimsec->x0 = trimsec->y0 = trimsec->x1 = trimsec->y1 = NAN;
     431            psMetadataItem *cellTrimsec = psMetadataItemAllocPtr("CELL.TRIMSEC", PS_DATA_REGION,
     432                                          "Trim section", trimsec);
     433            psFree(trimsec);
     434            pmConceptRegister(cellTrimsec, (pmConceptParseFunc)pmConceptParse_CELL_TRIMSEC,
     435                              #if 0
     436                              (pmConceptFormatFunc)pmConceptFormat_CELL_TRIMSEC,
     437                              #else
     438                              NULL,
     439                              #endif
     440                              PM_CONCEPT_LEVEL_CELL);
     441            psFree(cellTrimsec);
     442        }
     443
     444        // CELL.BIASSEC
     445        {
     446            psList *biassecs = psListAlloc(NULL); // Blank biassecs
     447            psMetadataItem *cellBiassec = psMetadataItemAllocPtr("CELL.BIASSEC", PS_DATA_LIST,
     448                                          "Bias sections", biassecs);
     449            psFree(biassecs);
     450            pmConceptRegister(cellBiassec, (pmConceptParseFunc)pmConceptParse_CELL_BIASSEC,
     451                              (pmConceptFormatFunc)pmConceptFormat_CELL_BIASSEC, PM_CONCEPT_LEVEL_CELL);
     452            psFree(cellBiassec);
     453        }
     454
     455        // CELL.XBIN
     456        {
     457            psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0);
     458            pmConceptRegister(cellXbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning,
     459                              (pmConceptFormatFunc)pmConceptFormat_CELL_XBIN, PM_CONCEPT_LEVEL_CELL);
     460            psFree(cellXbin);
     461        }
     462
     463        // CELL.YBIN
     464        {
     465            psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0);
     466            pmConceptRegister(cellYbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning,
     467                              (pmConceptFormatFunc)pmConceptFormat_CELL_YBIN, PM_CONCEPT_LEVEL_CELL);
     468            psFree(cellYbin);
     469        }
     470
     471        // CELL.TIMESYS
     472        {
     473            psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1);
     474            pmConceptRegister(cellTimesys, (pmConceptParseFunc)pmConceptParse_CELL_TIMESYS,
     475                              (pmConceptFormatFunc)pmConceptFormat_CELL_TIMESYS, PM_CONCEPT_LEVEL_CELL);
     476            psFree(cellTimesys);
     477        }
     478
     479        // CELL.TIME
     480        {
     481            psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time
     482            // Not particularly distinguishing, but should be good enough
     483            time->sec = 0;
     484            time->nsec = 0;
     485            psMetadataItem *cellTime = psMetadataItemAlloc("CELL.TIME", PS_DATA_TIME,
     486                                       "Time of exposure", time);
     487            psFree(time);
     488            pmConceptRegister(cellTime, (pmConceptParseFunc)pmConceptParse_CELL_TIME,
     489                              (pmConceptFormatFunc)pmConceptFormat_CELL_TIME, PM_CONCEPT_LEVEL_CELL);
     490            psFree(cellTime);
     491        }
     492
     493        // CELL.X0
     494        {
     495            psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0);
     496            pmConceptRegister(cellX0, (pmConceptParseFunc)pmConceptParse_CELL_Positions,
     497                              (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL);
     498            psFree(cellX0);
     499        }
     500
     501        // CELL.Y0
     502        {
     503            psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0);
     504            pmConceptRegister(cellY0, (pmConceptParseFunc)pmConceptParse_CELL_Positions,
     505                              (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL);
     506            psFree(cellY0);
     507        }
     508
     509    }
     510
     511    conceptsInitialised = true;
     512
     513    return init;
     514}
     515
     516void pmConceptsDone(void)
     517{
     518    psFree(conceptsFPA);
     519    psFree(conceptsChip);
     520    psFree(conceptsCell);
     521}
     522
     523
     524// Copy concepts from one FPA to another
     525bool pmFPACopyConcepts(pmFPA *target,   // The target FPA
     526                       pmFPA *source    // The target FPA
     527                      )
     528{
     529    // Copy FPA concepts
     530    target->concepts = psMetadataCopy(target->concepts, source->concepts);
     531
     532    // Copy chip concepts
     533    psArray *targetChips = target->chips; // Chips in target
     534    psArray *sourceChips = source->chips; // Chips in source
     535    if (targetChips->n != sourceChips->n) {
     536        psError(PS_ERR_IO, true, "Number of chips in target (%d) and source (%d) differ --- unable to copy "
     537                "concepts.\n", targetChips->n, sourceChips->n);
     538        return false;
     539    }
     540    for (int i = 0; i < targetChips->n; i++) {
     541        pmChip *targetChip = targetChips->data[i]; // Target chip of interest
     542        pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest
     543        if (! targetChip || ! sourceChip) {
     544            continue;
     545        }
     546        targetChip->concepts = psMetadataCopy(targetChip->concepts, sourceChip->concepts);
     547
     548        // Copy cell concepts
     549        psArray *targetCells = targetChip->cells; // Cells in target
     550        psArray *sourceCells = sourceChip->cells; // Cells in source
     551        if (targetCells->n != sourceCells->n) {
     552            psError(PS_ERR_IO, true, "Number of cells in target (%d) and source (%d) differ for chip %d ---"
     553                    " unable to copy concepts.\n", targetCells->n, sourceCells->n, i);
    522554            return false;
    523555        }
    524         for (int i = 0; i < targetChips->n; i++) {
    525             pmChip *targetChip = targetChips->data[i]; // Target chip of interest
    526             pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest
    527             if (! targetChip || ! sourceChip) {
     556        for (int j = 0; j < targetCells->n; j++) {
     557            pmCell *targetCell = targetCells->data[j]; // Target chip of interest
     558            pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest
     559            if (! targetCell || ! sourceCell) {
    528560                continue;
    529561            }
    530             targetChip->concepts = psMetadataCopy(targetChip->concepts, sourceChip->concepts);
    531 
    532             // Copy cell concepts
    533             psArray *targetCells = targetChip->cells; // Cells in target
    534             psArray *sourceCells = sourceChip->cells; // Cells in source
    535             if (targetCells->n != sourceCells->n) {
    536                 psError(PS_ERR_IO, true, "Number of cells in target (%d) and source (%d) differ for chip %d ---"
    537                         " unable to copy concepts.\n", targetCells->n, sourceCells->n, i);
    538                 return false;
    539             }
    540             for (int j = 0; j < targetCells->n; j++) {
    541                 pmCell *targetCell = targetCells->data[j]; // Target chip of interest
    542                 pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest
    543                 if (! targetCell || ! sourceCell) {
    544                     continue;
    545                 }
    546                 targetCell->concepts = psMetadataCopy(targetCell->concepts, sourceCell->concepts);
    547             }
    548         }
    549 
    550         return true;
    551     }
     562            targetCell->concepts = psMetadataCopy(targetCell->concepts, sourceCell->concepts);
     563        }
     564    }
     565
     566    return true;
     567}
  • branches/rel10_ifa/psModules/src/astrom/pmConceptsStandard.c

    r6663 r6734  
    156156    }
    157157
    158     psMetadataItem *item = psMetadataItemAllocPtr(pattern->name, PS_DATA_UNKNOWN, pattern->comment, trimsec);
     158    psMetadataItem *item = psMetadataItemAllocPtr(pattern->name, PS_DATA_REGION, pattern->comment, trimsec);
    159159    psFree(trimsec);
    160160    return item;
     
    434434
    435435
    436 
     436#if 0
    437437psMetadataItem *pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
    438438{
     
    446446    return formatted;
    447447}
    448 
    449 
    450 bool pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
    451 {
     448#endif
     449
     450psMetadataItem *pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell)
     451{
     452    // Return a metadata item containing a list of metadata items of region strings
    452453    psList *biassecs = concept->data.V; // The biassecs region list
    453     psString biassecString = NULL;      // String containing the biassecs
    454454    psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator
    455455    psRegion *region = NULL;            // Region from iteration
    456     bool first = true;                  // Are we on the first one?
     456    psList *new = psListAlloc(NULL);    // New list containing metadatas
    457457    while ((region = psListGetAndIncrement(biassecsIter))) {
    458458        psString regionString = psRegionToString(*region); // The string region "[x0:x1,y0:y1]"
    459         if (first) {
    460             psStringAppend(&biassecString, "%s", regionString);
    461             first = false;
    462         } else {
    463             psStringAppend(&biassecString, ";%s", regionString); // Put in a semi-colon
    464         }
    465         psFree(regionString);
     459        psMetadataItem *item = psMetadataItemAllocStr(concept->name, concept->comment, regionString);
     460        psFree(regionString);           // Drop reference
     461        psListAdd(new, PS_LIST_TAIL, item);
     462        psFree(item);                   // Drop reference
    466463    }
    467464    psFree(biassecsIter);
    468     psMetadataItem *formatted = psMetadataItemAllocStr(concept->name, concept->comment, biassecString);
    469     psFree(biassecString);              // Drop reference
     465    psMetadataItem *formatted = psMetadataItemAllocPtr(concept->name, PS_DATA_LIST, concept->comment, new);
     466    psFree(new);                        // Drop reference
    470467    return formatted;
    471468}
    472 
    473469
    474470// This function actually does both CELL.XBIN and CELL.YBIN if CELL.XBIN and CELL.YBIN are specified by the
  • branches/rel10_ifa/psModules/src/astrom/pmConceptsStandard.h

    r6575 r6734  
    1414psMetadataItem *pmConceptParse_CELL_TIME(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
    1515psMetadataItem *pmConceptParse_CELL_Positions(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
     16#if 0
    1617psMetadataItem *pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
    17 bool pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
     18#endif
     19psMetadataItem *pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
    1820psMetadataItem *pmConceptFormat_CELL_XBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
    1921psMetadataItem *pmConceptFormat_CELL_YBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell);
  • branches/rel10_ifa/psModules/src/astrom/pmConceptsWrite.c

    r6663 r6734  
    9595}
    9696
    97 static bool writeHeader(pmHDU *hdu,     // HDU for which to add to the header
    98                         const char *keyword, // Keyword to add
    99                         psMetadataItem *item // Item to add to the header
    100                        )
     97// Write a single value to a header
     98static bool writeSingleHeader(pmHDU *hdu, // HDU for which to add to the header
     99                              const char *keyword, // Keyword to add
     100                              psMetadataItem *item // Item to add to the header
     101                             )
    101102{
    102103    switch (item->type) {
     
    113114        return psMetadataAddF64(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
    114115                                item->data.F64);
     116    case PS_DATA_REGION: {
     117            psString region = psRegionToString(*(psRegion*)item->data.V);
     118            bool result = psMetadataAddStr(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment,
     119                                           region);
     120            psFree(region);
     121            return result;
     122        }
    115123    default:
    116124        psLogMsg(__func__, PS_LOG_WARN, "Type of %s is not suitable for a FITS header --- not added.\n",
     
    118126        return false;
    119127    }
     128}
     129
     130
     131// Write potentially multiple values to a header
     132static bool writeHeader(pmHDU *hdu,     // HDU for which to add to the header
     133                        const char *keywords, // Keywords to add
     134                        psMetadataItem *item // Item to add to the header
     135                       )
     136{
     137    bool status = true;                 // Status of writing headers, to be returned
     138    if (item->type == PS_DATA_LIST) {
     139        psList *values = item->data.V;  // List of outputs
     140        psList *keys = psStringSplit(keywords, " ,;"); // List of keywords
     141        if (keys->n != values->n) {
     142            psLogMsg(__func__, PS_LOG_WARN, "Number of keywords (%d) does not match number of values (%d).\n",
     143                     keys->n, values->n);
     144        }
     145        psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator for keywords
     146        psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator for values
     147        psString key = NULL;            // Keyword from iteration
     148        psMetadataItem *value = NULL;   // Value from iteration
     149        while ((key = psListGetAndIncrement(keysIter)) && (value = psListGetAndIncrement(valuesIter))) {
     150            status |= writeSingleHeader(hdu, key, value);
     151        }
     152        psFree(keysIter);
     153        psFree(valuesIter);
     154        psFree(keys);
     155    } else {
     156        status = writeSingleHeader(hdu, keywords, item);
     157    }
     158    return status;
    120159}
    121160
     
    156195                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
    157196                if (mdok && strlen(source) > 0) {
     197                    psTrace(__func__, 8, "%s is %s\n", nameSource, source);
    158198                    if (strcasecmp(source, "HEADER") == 0) {
    159199                        if (cameraItem->type != PS_DATA_STRING) {
     
    162202                            continue;
    163203                        }
     204                        psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V);
    164205                        writeHeader(hdu, cameraItem->data.V, formatted);
    165206                        continue;
    166207                    }
    167208                    if (strcasecmp(source, "VALUE") == 0) {
     209                        psTrace(__func__, 8, "Checking %s against camera format.\n", name);
    168210                        if (! compareConcepts(cameraItem, formatted)) {
    169211                            psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
    170                                      "format, but the values don't match.\n");
     212                                     "format, but the values don't match.\n", name);
    171213                        }
    172214                        continue;
     
    179221                if (! compareConcepts(cameraItem, formatted)) {
    180222                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
    181                              "format, but the values don't match.\n");
     223                             "format, but the values don't match.\n", name);
    182224                }
    183225            }
  • branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c

    r6713 r6734  
    682682// Print out the focal plane structure
    683683void pmFPAPrint(pmFPA *fpa,             // FPA to print
     684                bool header,            // Print headers?
    684685                bool concepts           // Print concepts?
    685686               )
     
    703704        if (chip->hdu) {
    704705            psTrace(__func__, 4, "---> Chip is extension %s.\n", chip->hdu->extname);
     706            if (chip->hdu->header && header) {
     707                psTrace(__func__, 4, "---> Header:\n");
     708                psMetadataPrint(chip->hdu->header, 8);
     709            }
    705710            if (! chip->hdu->images) {
    706711                psTrace(__func__, 4, "---> NO PIXELS read in for extension %s\n", chip->hdu->extname);
     
    718723            if (cell->hdu) {
    719724                psTrace(__func__, 6, "---> Cell is extension %s.\n", cell->hdu->extname);
     725                if (cell->hdu->header && header) {
     726                    psTrace(__func__, 4, "---> Header:\n");
     727                    psMetadataPrint(cell->hdu->header, 8);
     728                }
    720729                if (! cell->hdu->images) {
    721730                    psTrace(__func__, 6, "---> NO PIXELS read in for extension %s\n", cell->hdu->extname);
     
    731740                pmReadout *readout = readouts->data[k]; // The readout
    732741                psImage *image = readout->image; // The image
     742                psList *bias = readout->bias; // The list of bias images
    733743                if (image) {
    734744                    psTrace(__func__, 8, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 +
     
    736746                            image->numRows);
    737747                }
     748                if (bias) {
     749                    psListIterator *biasIter = psListIteratorAlloc(bias, PS_LIST_HEAD, false); // Iterator
     750                    psImage *biasImage = NULL; // Bias image from iteration
     751                    while ((biasImage = psListGetAndIncrement(biasIter))) {
     752                        psTrace(__func__, 8, "Bias:  [%d:%d,%d:%d] (%dx%d)\n", biasImage->col0,
     753                                biasImage->col0 + biasImage->numCols, biasImage->row0,
     754                                biasImage->row0 + biasImage->numRows, biasImage->numCols, biasImage->numRows);
     755                    }
     756                    psFree(biasIter);
     757                }
    738758            } // Iterating over cell
    739759        } // Iterating over chip
  • branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.h

    r6618 r6734  
    1717// Print out the FPA
    1818void pmFPAPrint(pmFPA *fpa,             // FPA to print
     19                bool header,            // Print headers?
    1920                bool concepts           // Print concepts?
    2021               );
    2122
    22 
    2323#endif
  • branches/rel10_ifa/psModules/src/astrom/pmFPACopy.c

    r6720 r6734  
    117117            *xSize = MAX(trimsec->x1, *xSize);
    118118            *ySize = MAX(trimsec->y1, *ySize);
     119        } else {
     120            psFree(cellsIter);
     121            return false;
    119122        }
    120123        psList *biassecs = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.BIASSEC"); // Bias sections
     
    126129                    *xSize = MAX(biassec->x1, *xSize);
    127130                    *ySize = MAX(biassec->y1, *ySize);
     131                } else {
     132                    psFree(biassecsIter);
     133                    psFree(cellsIter);
     134                    return false;
    128135                }
    129136            }
     
    133140    psFree(cellsIter);
    134141
    135     return (*xSize == 0 || *ySize == 0);
     142    return (*xSize != 0 && *ySize != 0);
    136143}
    137144
     
    145152    switch (readdir) {
    146153    case 1:                           // Read direction is rows
    147         region = psRegionSet(*position, image->row0, *position + image->numCols,
     154        region = psRegionSet(*position, *position + image->numCols, image->row0,
    148155                             image->row0 + image->numRows);
    149156        *position += image->numCols;
    150157        break;
    151158    case 2:                           // Read direction is columns
    152         region = psRegionSet(image->col0, *position, image->col0 + image->numCols,
     159        region = psRegionSet(image->col0, image->col0 + image->numCols, *position,
    153160                             *position + image->numRows);
    154161        *position += image->numRows;
     
    209216    int numCells = targets->n;          // Number of cells
    210217    int cellNum = 0;                    // The cell number
    211     int position;                       // Position on the image
     218    int position = 0;                   // Position on the image
    212219    bool mdok = true;                   // Status of MD lookup
    213220
     
    218225    while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter)) &&
    219226            !done) {
    220         if (cellNum < numCells/2) {
     227        if (cellNum <= numCells/2 - 1) {
    221228            doBiasSections(&position, target, source);
     229            cellNum++;
    222230        } else {
    223231            done = true;
     
    249257
    250258    // A final run through to do the RHS biases
    251     psListIteratorSet(targetsIter, numCells/2);
    252     psListIteratorSet(sourcesIter, numCells/2);
     259    psListIteratorSet(targetsIter, cellNum);
     260    psListIteratorSet(sourcesIter, cellNum);
    253261    while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter))) {
    254262        doBiasSections(&position, target, source);
     
    299307    // Get the size of the HDU, either from existing trimsec and biassec, or generate these and try again
    300308    int xSize = 0, ySize = 0;           // Size of HDU
    301     if (!sizeHDU(&xSize, &ySize, targetCells) || !(generateTrimBias(targetCells, sourceCells) &&
     309    #if 1
     310
     311    if (!sizeHDU(&xSize, &ySize, targetCells) && !(generateTrimBias(targetCells, sourceCells) &&
    302312            sizeHDU(&xSize, &ySize, targetCells))) {
    303313        psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n");
    304314        return false;
    305315    }
     316    #else
     317    if (!sizeHDU(&xSize, &ySize, targetCells)) {
     318        if (generateTrimBias(targetCells, sourceCells)) {
     319            if (!sizeHDU(&xSize, &ySize, targetCells)) {
     320                psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n");
     321                return false;
     322            }
     323        } else {
     324            psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n");
     325            return false;
     326        }
     327    }
     328    #endif
    306329
    307330    hdu->images = psArrayAlloc(numReadouts);
     
    314337    return true;
    315338}
    316 
    317 
    318 #define UPDATE_CASE(TYPENAME,TYPE) \
    319 case TYPENAME: targetItem->data.TYPE = sourceItem->data.TYPE; \
    320 break;
    321 
    322 // Update a particular "concept" for the target cell from the source cell
    323 static bool updateConcept(pmCell *target, // Target cell
    324                           const pmCell *source, // Source cell
    325                           const char *concept // Concept name
    326                          )
    327 {
    328     psMetadataItem *targetItem = psMetadataLookup(target->concepts, concept); // Concept from the target
    329     psMetadataItem *sourceItem = psMetadataLookup(source->concepts, concept); // Concept from the source
    330 
    331     switch (targetItem->type) {
    332         UPDATE_CASE(PS_TYPE_S32, S32);
    333         UPDATE_CASE(PS_TYPE_F32, F32);
    334         UPDATE_CASE(PS_TYPE_F64, F64);
    335         UPDATE_CASE(PS_DATA_STRING, V);
    336     default:
    337         psLogMsg(__func__, PS_LOG_WARN, "Unsupported type (%x) for concept %s --- ignored.\n",
    338                  targetItem->type, concept);
    339         return false;
    340     }
    341     return true;
    342 }
    343 
    344339
    345340// Copy pixels from a target image to a source image, with flips
     
    386381        return false;
    387382    }
     383
     384    #if 1
     385    // Copy any headers
     386    if (target->hdu && !target->hdu->phu) {
     387        pmHDU *sourceHDU = pmHDUFromFPA(source);
     388        target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header);
     389    }
     390    #endif
    388391
    389392    int numChips = 0;                   // Number of chips copied
     
    400403    }
    401404
     405    // Update the concepts
     406    psMetadataCopy(target->concepts, source->concepts);
     407
    402408    return numChips;
    403409}
     
    417423        return false;
    418424    }
     425
     426    #if 1
     427    // Copy any headers
     428    if (target->hdu && !target->hdu->phu) {
     429        pmHDU *sourceHDU = pmHDUFromChip(source);
     430        target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header);
     431    }
     432    #endif
    419433
    420434    int numCells = 0;                   // Number of cells copied
     
    431445    }
    432446
     447    // Update the concepts
     448    psMetadataCopy(target->concepts, source->concepts);
     449
    433450    return numCells;
    434451
     
    442459    assert(source);
    443460
    444     psArray *targetReadouts = target->readouts; // The target readouts
    445461    psArray *sourceReadouts = source->readouts; // The source readouts
    446     if (targetReadouts->n != sourceReadouts->n) {
    447         psError(PS_ERR_IO, true, "Number of source readouts (%d) differs from the number of target readouts "
    448                 "(%d)\n", sourceReadouts->n, targetReadouts->n);
    449         return false;
    450     }
    451     int numReadouts = targetReadouts->n; // Number of readouts copied
     462    int numReadouts = sourceReadouts->n; // Number of readouts copied
     463
     464    #if 1
     465    // Copy any headers
     466    if (target->hdu && !target->hdu->phu) {
     467        pmHDU *sourceHDU = pmHDUFromCell(source);
     468        target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header);
     469    }
     470    #endif
    452471
    453472    pmHDU *hdu = pmHDUFromCell(target); // The target HDU; we need to fix this up
    454     if (! hdu->images) {
     473    if (!hdu->images) {
    455474        generateHDU(target, source);
    456475    }
    457 
    458     // Need to check CELL.X0, CELL.Y0, CELL.XBIN, CELL.YBIN should be unchanged; we can check this by
    459     // setting the values and leaving it to the pmConceptWrite functions to do the checking against the
    460     // camera configuration when it comes time to write them out.
    461     updateConcept(target, source, "CELL.X0");
    462     updateConcept(target, source, "CELL.Y0");
    463     updateConcept(target, source, "CELL.XBIN");
    464     updateConcept(target, source, "CELL.YBIN");
     476    if (!hdu->header) {
     477        hdu->header = psMetadataAlloc();
     478    }
    465479
    466480    // Need to check/change CELL.XPARITY and CELL.YPARITY
    467481    bool xFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.XPARITY") !=
    468                   psMetadataLookupS32(NULL, target->concepts, "CELL.XPARITY")); // Switch parity in x?
     482                  psMetadataLookupS32(NULL, source->concepts, "CELL.XPARITY")); // Switch parity in x?
    469483    bool yFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY") !=
    470                   psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY")); // Switch parity in y?
     484                  psMetadataLookupS32(NULL, source->concepts, "CELL.YPARITY")); // Switch parity in y?
    471485
    472486    bool mdok = true;                   // Status of MD lookup
     
    482496    }
    483497
    484     for (int i = 0; i < targetReadouts->n; i++) {
     498    for (int i = 0; i < numReadouts; i++) {
    485499        pmReadout *sourceReadout = sourceReadouts->data[i]; // The source readout
    486500        psImage *sourceImage = sourceReadout->image; // The source image
    487         pmReadout *targetReadout = targetReadouts->data[i]; // The target readout
     501        pmReadout *targetReadout = pmReadoutAlloc(target); // The target readout; this adds it to the cell
    488502        if (sourceImage->numCols != trimsec->x1 - trimsec->x0 ||
    489503                sourceImage->numRows != trimsec->y1 - trimsec->y0) {
     
    500514        psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator
    501515        psRegion *biassec = NULL;       // Bias section from iteration
    502         while ((biassec = psListGetAndIncrement(biassecsIter))) {
     516        psListIterator *biasIter = psListIteratorAlloc(sourceReadout->bias, PS_LIST_HEAD, false); // Iterator
     517        psImage *bias = NULL;           // Bias image from iteration
     518        while ((biassec = psListGetAndIncrement(biassecsIter)) && (bias = psListGetAndIncrement(biasIter))) {
    503519            if (psRegionIsBad(*biassec)) {
    504520                psString biassecString = psRegionToString(*biassec); // String for bias section
     
    507523                continue;
    508524            }
    509             if (sourceImage->numCols != biassec->x1 - biassec->x0 ||
    510                     sourceImage->numRows != biassec->y1 - biassec->y0) {
     525            if (bias->numCols != biassec->x1 - biassec->x0 ||
     526                    bias->numRows != biassec->y1 - biassec->y0) {
    511527                psString biassecString = psRegionToString(*biassec); // String with the bias section
    512528                psLogMsg(__func__, PS_LOG_WARN, "Source image size (%dx%d) for readout %d doesn't match "
    513                          "CELL.BIASSEC for target (%s) -- ignored.\n", sourceImage->numCols,
    514                          sourceImage->numRows, i, biassecString);
     529                         "CELL.BIASSEC for target (%s) -- ignored.\n", bias->numCols, bias->numRows, i,
     530                         biassecString);
    515531                psFree(biassecString);
    516532            } else {
    517                 copyPixels(hdu->images->data[i], sourceImage, *biassec, xFlip, yFlip);
    518                 psImage *bias = psMemIncrRefCounter(psImageSubset(hdu->images->data[i], *biassec));
    519                 psListAdd(targetReadout->bias, PS_LIST_TAIL, bias);
    520                 psFree(bias);           // Drop reference
     533                copyPixels(hdu->images->data[i], bias, *biassec, xFlip, yFlip);
     534                psImage *newBias = psMemIncrRefCounter(psImageSubset(hdu->images->data[i], *biassec));
     535                psListAdd(targetReadout->bias, PS_LIST_TAIL, newBias);
     536                psFree(newBias);        // Drop reference
    521537            }
    522538        }
    523539        psFree(biassecsIter);
    524 
     540        psFree(biasIter);
     541    }
     542
     543    // Copy the remaining "concepts" over
     544    psMetadataIterator *conceptsIter = psMetadataIteratorAlloc(source->concepts, PS_LIST_HEAD, NULL);
     545    psMetadataItem *conceptItem = NULL; // Item from iteration
     546    while ((conceptItem = psMetadataGetAndIncrement(conceptsIter))) {
     547        psString name = conceptItem->name; // Name of concept
     548        if (strcmp(name, "CELL.TRIMSEC") != 0 && strcmp(name, "CELL.BIASSEC") != 0 &&
     549                strcmp(name, "CELL.XPARITY") != 0 && strcmp(name, "CELL.YPARITY") != 0) {
     550            psMetadataAddItem(target->concepts, conceptItem, PS_LIST_TAIL, PS_META_REPLACE);
     551        }
     552    }
     553
     554    // Need to update CELL.X0 and CELL.Y0 if we flipped
     555    if (xFlip) {
     556        psMetadataItem *xZero = psMetadataLookup(target->concepts, "CELL.X0"); // CELL.X0
     557        pmReadout *readout = target->readouts->data[0]; // A representative readout
     558        xZero->data.S32 -= readout->image->numCols - 1;
     559    }
     560    if (yFlip) {
     561        psMetadataItem *yZero = psMetadataLookup(target->concepts, "CELL.Y0"); // CELL.Y0
     562        pmReadout *readout = target->readouts->data[0]; // A representative readout
     563        yZero->data.S32 -= readout->image->numRows - 1;
    525564    }
    526565
  • branches/rel10_ifa/psModules/src/astrom/pmFPAWrite.c

    r6663 r6734  
    1313                )
    1414{
    15     pmConceptsWriteCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL);
     15    pmConceptsWriteCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS,
     16                        false, NULL);
    1617
    1718    pmHDU *hdu = cell->hdu;             // The HDU
     
    3031                )
    3132{
    32     pmConceptsWriteChip(chip, PM_CONCEPT_SOURCE_HEADER, false, NULL);
     33    pmConceptsWriteChip(chip, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS,
     34                        false, NULL);
    3335
    3436    pmHDU *hdu = chip->hdu;             // The HDU
     
    5658               )
    5759{
    58     pmConceptsWriteFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
     60    pmConceptsWriteFPA(fpa, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS,
     61                       NULL);
    5962
    6063    pmHDU *hdu = fpa->hdu;              // The HDU
  • branches/rel10_ifa/psModules/src/astrom/pmHDU.c

    r6726 r6734  
    44#include "pslib.h"
    55#include "pmFPA.h"
     6#include "psAdditionals.h"
    67
    78
     
    3536        hdu->extname = psStringCopy(extname);
    3637    }
    37     hdu->format = NULL;
    38     hdu->header = NULL;
    39     hdu->images = NULL;
    40     hdu->table  = NULL;
     38    hdu->format  = NULL;
     39    hdu->header  = NULL;
     40    hdu->images  = NULL;
     41    hdu->table   = NULL;
     42    hdu->weights = NULL;
     43    hdu->masks   = NULL;
    4144
    4245    return hdu;
  • branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.c

    r6713 r6734  
    5959}
    6060
    61 
  • branches/rel10_ifa/psModules/src/config/pmConfig.c

    r6713 r6734  
    33 *  @author PAP, IfA
    44 *
    5  *  @version $Revision: 1.7.4.6 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2006-03-28 02:16:26 $
     5 *  @version $Revision: 1.7.4.7 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2006-03-30 20:08:30 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    539539    return(psDBInit(dbServer, dbUsername, dbPassword, dbName));
    540540}
     541
     542
     543bool pmConfigConformHeader(psMetadata *header, // Header to conform
     544                           const psMetadata *format // Camera format
     545                          )
     546{
     547    bool mdok = true;                   // Status of MD lookup
     548    psMetadata *rules = psMetadataLookupMD(&mdok, format, "RULE"); // How to identify this format
     549    if (!mdok || !rules) {
     550        psError(PS_ERR_IO, false, "Unable to find RULE in camer format.\n");
     551        return false;
     552    }
     553
     554    psMetadataIterator *rulesIter = psMetadataIteratorAlloc(rules, PS_LIST_HEAD, NULL); // Iterator for rules
     555    psMetadataItem *rulesItem = NULL;   // Item from iteration
     556    while ((rulesItem = psMetadataGetAndIncrement(rulesIter))) {
     557        psMetadataItem *newItem = psMetadataItemCopy(rulesItem); // Copy of item
     558        psMetadataAddItem(header, newItem, PS_LIST_TAIL, PS_META_REPLACE);
     559        psFree(newItem);                // Drop reference
     560    }
     561    psFree(rulesIter);
     562
     563    return true;
     564}
  • branches/rel10_ifa/psModules/src/config/pmConfig.h

    r6713 r6734  
    33 *  @author PAP, IfA
    44 *
    5  *  @version $Revision: 1.3.4.4 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2006-03-28 02:16:26 $
     5 *  @version $Revision: 1.3.4.5 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2006-03-30 20:08:30 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    100100);
    101101
     102/** pmConfigConformHeader
     103 *
     104 * Make the supplied header conform to the nominated camera format.
     105 */
     106bool pmConfigConformHeader(psMetadata *header, // Header to conform
     107                           const psMetadata *format // Camera format
     108                          );
     109
    102110
    103111#endif
  • branches/rel10_ifa/psModules/src/pslib/psImageFlip.c

    r6721 r6734  
    3636    }
    3737
    38     return image;
     38    return output;
    3939}
    4040
     
    7373    }
    7474
    75     return image;
     75    return output;
    7676}
  • branches/rel10_ifa/psModules/src/psmodules.h

    r6723 r6734  
    77// the following headers are from psModule:pslib
    88#include <psImageJpeg.h>
     9#include <psImageFlip.h>
    910#include <psLine.h>
    1011#include <psPolynomialUtils.h>
Note: See TracChangeset for help on using the changeset viewer.