IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6618


Ignore:
Timestamp:
Mar 16, 2006, 3:47:44 PM (20 years ago)
Author:
Paul Price
Message:

PHU=NONE (i.e., megacam split) now working, with concept ingest; changed definition of pmFPAAddSource to return a pmFPAview

Location:
branches/rel10_ifa/psModules/src/astrom
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • branches/rel10_ifa/psModules/src/astrom/Makefile.am

    r6586 r6618  
    11noinst_LTLIBRARIES = libpsmoduleastrom.la
    22
    3 libpsmoduleastrom_la_CPPFLAGS = $(SRCINC) $(PSMODULE_CFLAGS)
     3libpsmoduleastrom_la_CPPFLAGS = $(SRCINC) $(PSMODULE_CFLAGS) -I../pslib/
    44libpsmoduleastrom_la_LDFLAGS  = -release $(PACKAGE_VERSION)
    55libpsmoduleastrom_la_SOURCES  = \
  • branches/rel10_ifa/psModules/src/astrom/pmConcepts.c

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

    r6575 r6618  
    6565bool pmConceptsReadChip(pmChip *chip,   // Chip for which to read concepts
    6666                        pmConceptSource source, // Source for concepts
     67                        bool propagate, // Propagate to higher levels as well?
    6768                        psDB *db        // Database handle
    6869                       );
    6970bool pmConceptsWriteChip(pmChip *chip,  // Chip for which to write concepts
    7071                         pmConceptSource source, // Source for concepts
     72                         bool propagate,// Propagate to higher levels as well?
    7173                         psDB *db       // Database handle
    7274                        );
     
    7577bool pmConceptsReadCell(pmCell *cell,   // Cell for which to read concepts
    7678                        pmConceptSource source, // Source for concepts
     79                        bool propagate, // Propagate to higher levels as well?
    7780                        psDB *db        // Database handle
    7881                       );
    7982bool pmConceptsWriteCell(pmCell *cell,  // FPA for which to write concepts
    8083                         pmConceptSource source, // Source for concepts
     84                         bool propagate,// Propagate to higher levels as well?
    8185                         psDB *db       // Database handle
    8286                        );
  • branches/rel10_ifa/psModules/src/astrom/pmConceptsRead.c

    r6582 r6618  
    22
    33#include "pslib.h"
     4#include "psMetadataItemParse.h"
    45
    56#include "pmFPA.h"
     
    1213// File-static functions
    1314//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    14 
    15 
    16 static float parseF32(psMetadataItem *item
    17                      )
    18 {
    19     switch (item->type) {
    20     case PS_DATA_F32:
    21         return item->data.F32;
    22     case PS_DATA_F64:
    23         // Assume it's OK to truncate to floating point from double
    24         return (float)item->data.F64;
    25     case PS_DATA_S32:
    26         // Promote to float
    27         return (float)item->data.S32;
    28     default:
    29         psError(PS_ERR_IO, true, "Concept %s (%s) is not of floating point type (%x) --- treating as NaN.\n",
    30                 item->name, item->comment, item->type);
    31         return NAN;
    32     }
    33 }
    34 
    35 static double parseF64(psMetadataItem *item
    36                       )
    37 {
    38     switch (item->type) {
    39     case PS_TYPE_F64:
    40         return item->data.F64;
    41     case PS_TYPE_F32:
    42         // Promote to double
    43         return (double)item->data.F32;
    44     case PS_TYPE_S32:
    45         // Promote to double
    46         return (double)item->data.S32;
    47     default:
    48         psError(PS_ERR_IO, true, "Concept %s (%s) is not of double-precision floating point type (%x) "
    49                 "--- treating as NaN.\n", item->name, item->comment, item->type);
    50         return NAN;
    51     }
    52 }
    53 
    54 static int parseS32(psMetadataItem *item
    55                    )
    56 {
    57     switch (item->type) {
    58     case PS_TYPE_S32:
    59         return item->data.S32;
    60     case PS_TYPE_F32:
    61         psLogMsg(__func__, PS_LOG_WARN, "Concept %s (%s) should be S32, but is F32 --- converting.\n",
    62                  item->name, comment);
    63         return (int)item->data.F32;
    64     case PS_TYPE_F64:
    65         psLogMsg(__func__, PS_LOG_WARN, "Concept %s (%s) should be S32, but is F64 --- converting.\n",
    66                  item->name, comment);
    67         return (int)item->data.F64;
    68     default:
    69         psError(PS_ERR_IO, true, "Concept %s (%s) is not of integer type (%x) --- treating as zero.\n",
    70                 item->name, item->comment, item->type);
    71         return 0;
    72     }
    73 }
    74 
    75 static psString parseString(psMetadataItem *item
    76                            )
    77 {
    78     switch (item->type) {
    79     case PS_DATA_STRING:
    80         return psMemIncrRefCounter(item->data.V);
    81     case PS_DATA_F32: {
    82             psString value = NULL;    // String to return
    83             psStringAppend(&value, "%f", item->data.F32);
    84             return value;
    85         }
    86     case PS_DATA_S32: {
    87             psString value = NULL;    // String to return
    88             psStringAppend(&value, "%d", item->data.S32);
    89             return value;
    90         }
    91     default:
    92         psError(PS_ERR_IO, true, "Concept %s (%s) is not of string type (%x) --- treating as "
    93                 "undefined.\n", item->name, item->comment, item->type);
    94         return psStringCopy("");
    95     }
    96 }
    97 
    9815
    9916// This function gets called for the really boring concepts --- where all you have to do is parse from a
     
    10623    switch (pattern->type) {
    10724    case PS_DATA_STRING: {
    108             psString string = parseString(concept); // Get the string, so I can free it after it goes on the MDI
     25            psString string = psMetadataItemParseString(concept); // Get the string, so I can free it after it
     26            // goes on the MetadataItem
    10927            psMetadataItem *item = psMetadataItemAllocStr(pattern->name, pattern->comment, string);
    11028            psFree(string);
     
    11230        }
    11331    case PS_DATA_S32:
    114         return psMetadataItemAllocS32(pattern->name, pattern->comment, parseS32(concept));
     32        return psMetadataItemAllocS32(pattern->name, pattern->comment, psMetadataItemParseS32(concept));
    11533    case PS_DATA_F32:
    116         return psMetadataItemAllocF32(pattern->name, pattern->comment, parseF32(concept));
     34        return psMetadataItemAllocF32(pattern->name, pattern->comment, psMetadataItemParseF32(concept));
    11735    case PS_DATA_F64:
    118         return psMetadataItemAllocF64(pattern->name, pattern->comment, parseF64(concept));
     36        return psMetadataItemAllocF64(pattern->name, pattern->comment, psMetadataItemParseF64(concept));
    11937    default:
    12038        psLogMsg(__func__, PS_LOG_WARN, "Concept %s (%s) is not of a standard type (%x)\n",
  • branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c

    r6589 r6618  
    11#include <stdio.h>
    2 #include <strings.h>
     2#include <assert.h>
     3#include <string.h>
    34#include "pslib.h"
     5#include "psMetadataItemParse.h"
    46
    57#include "pmFPA.h"
    68#include "pmConcepts.h"
    79#include "pmFPAConstruct.h"
     10#include "pmFPAview.h"
    811
    912//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    3134}
    3235
    33 // Find a chip by name
    34 static pmChip *findChip(pmFPA *fpa, // FPA in which to find the chip
    35                         const char *name // Name of the chip
    36                        )
     36// Find a chip by name; return the index
     37static int findChip(pmFPA *fpa, // FPA in which to find the chip
     38                    const char *name // Name of the chip
     39                   )
    3740{
    3841    psArray *chips = fpa->chips;    // Array of chips
     
    4144        psString testName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); // Name of this chip
    4245        if (strcmp(name, testName) == 0) {
    43             return chip;
     46            return i;
    4447        }
    4548    }
    4649
    4750    psError(PS_ERR_IO, true, "Unable to find chip %s\n", name);
    48     return NULL;
    49 }
    50 
    51 // Find a cell by name
    52 static pmCell *findCell(pmChip *chip, // Chip in which to find the cell
    53                         const char *name // Name of the cell
    54                        )
     51    return -1;
     52}
     53
     54// Find a cell by name; return the index
     55static int findCell(pmChip *chip, // Chip in which to find the cell
     56                    const char *name // Name of the cell
     57                   )
    5558{
    5659    psArray *cells = chip->cells;    // Array of cells
     
    5962        psString testName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of this cell
    6063        if (strcmp(name, testName) == 0) {
    61             return cell;
     64            return i;
    6265        }
    6366    }
    6467
    6568    psError(PS_ERR_IO, true, "Unable to find cell %s\n", name);
    66     return NULL;
     69    return -1;
    6770}
    6871
     
    100103}
    101104
    102 // Get the chip name from a primary header lookup
    103 static psString chipNameFromHeader(const psMetadata *format, // FORMAT within the camera format description
    104                                    const psMetadata *header // Primary header
    105                                   )
     105// Get the name of a PHU chip or cell from the header
     106static psString phuNameFromHeader(const char *name, // The name to lookup: "CELL.NAME" or "CHIP.NAME"
     107                                  const psMetadata *format, // FORMAT within the camera format description
     108                                  const psMetadata *header // Primary header
     109                                 )
    106110{
    107111    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");
     112    psString keyword = psMetadataLookupStr(&mdok, format, name);
     113    if (!mdok || strlen(keyword) == 0) {
     114        psError(PS_ERR_IO, false, "Unable to find %s in the FORMAT.\n", name);
    111115        return false;
    112116    }
    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);
     117    psString result = psMetadataLookupStr(&mdok, header, keyword);
     118    if (!mdok || strlen(result) == 0) {
     119        psError(PS_ERR_IO, false, "Unable to find %s in primary header to identify %s.\n", keyword, name);
    116120        return NULL;
    117121    }
    118122
    119     return chipName;
     123    return result;
    120124}
    121125
     
    159163
    160164// Add an input file to the FPA
    161 bool 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                     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     }
     165pmFPAview *pmFPAAddSource(pmFPA *fpa, // The FPA
     166                          psMetadata *phu, // Primary header of file
     167                          psMetadata *format // Format of file
     168                         )
     169{
     170    assert(fpa);
     171    assert(phu);
     172    assert(format);
     173
     174    pmChip *chip = NULL;                // The chip, if any one in particular
     175    pmCell *cell = NULL;                // The cell, if any one in particular
     176    psString phuChipName = NULL;        // Name of the chip from the PHU
    175177
    176178    bool mdok = true;                   // Status from metadata lookups
     
    178180    if (!mdok || !formatSpec) {
    179181        psError(PS_ERR_IO, false, "Unable to find FORMAT in the camera format configuration.\n");
    180         return false;
    181     }
     182        return NULL;
     183    }
     184
     185    // Check the name of the FPA
     186    const char *nameKeyword = psMetadataLookupStr(&mdok, formatSpec, "FPA.NAME"); // Keyword that gives name
     187    if (!mdok || strlen(nameKeyword) == 0) {
     188        psError(PS_ERR_IO, false, "Unable to find FPA.NAME in the format specification.\n");
     189        return NULL;
     190    }
     191    psMetadataItem *fpaNameItem = psMetadataLookup(phu, nameKeyword); // Name of the FPA
     192    const char *newFPAname = psMetadataItemParseString(fpaNameItem); // FPA.NAME for new source
     193    fpaNameItem = psMetadataLookup(fpa->concepts, "FPA.NAME"); // Current name of FPA
     194    if (fpaNameItem && fpaNameItem->type == PS_DATA_STRING) {
     195        const char *currentFPAname = fpaNameItem->data.V; // Name of the current FPA
     196        if (currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) {
     197            psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current "
     198                     "fpa (%s).\n", newFPAname, currentFPAname);
     199        }
     200    }
     201    psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.NAME", PS_META_REPLACE, "Name of FPA", newFPAname);
    182202
    183203    // Where does the PHU go?
     
    185205    if (!mdok || strlen(phuType) == 0) {
    186206        psError(PS_ERR_IO, false, "Unable to find PHU in the format specification.\n");
    187         return false;
     207        return NULL;
    188208    }
    189209    pmHDU *phdu = pmHDUAlloc("PHU");    // The primary header data unit
    190210    phdu->header = psMemIncrRefCounter(phu);
    191211    phdu->format = psMemIncrRefCounter(format);
    192     if (fpa && !fpa->hdu && strcasecmp(phuType, "FPA") == 0) {
     212
     213    // Generate the view
     214    pmFPAview *view = pmFPAviewAlloc(0); // The FPA view corresponding to the PHU, to be returned
     215    view->chip = -1;
     216    view->cell = -1;
     217    view->readout = -1;
     218    view->fpa = psMemIncrRefCounter(fpa);
     219    if (strcasecmp(phuType, "FPA") == 0) {
     220        if (fpa->hdu) {
     221            // Something's already here
     222            psError(PS_ERR_IO, true, "Unable to add source since FPA already has a PHU.\n");
     223            psFree(view);
     224            return NULL;
     225        }
    193226        fpa->hdu = phdu;
    194227        pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
    195     } else if (chip && !chip->hdu && strcasecmp(phuType, "CHIP") == 0) {
    196         chip->hdu = phdu;
    197         pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, NULL);
    198     } else if (cell && !cell->hdu && strcasecmp(phuType, "CELL") == 0) {
    199         // cell->hdu = phdu;
    200         psError(PS_ERR_IO, true, "The case of PHU == CELL has not been written yet!\n");
    201         return false;
     228    } else {
     229        // Get the chip
     230        phuChipName = phuNameFromHeader("CHIP.NAME", formatSpec, phu); // Name of the chip
     231        int chipNum = findChip(fpa, phuChipName); // Chip number
     232        if (chipNum == -1) {
     233            psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", phuChipName);
     234            psFree(view);
     235            return NULL;
     236        }
     237        chip = fpa->chips->data[chipNum];
     238        view->chip = chipNum;
     239
     240        if (strcasecmp(phuType, "CHIP") == 0) {
     241            if (chip->hdu) {
     242                // Something's already here
     243                psError(PS_ERR_IO, true, "Unable to add source since chip already has a PHU.\n");
     244                psFree (view);
     245                return NULL;
     246            }
     247            chip->hdu = phdu;
     248            pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, true, NULL);
     249        } else if (strcasecmp(phuType, "CELL") == 0) {
     250            psError(PS_ERR_IO, true, "Not yet sure how to handle PHU=CELL.\n");
     251            psFree(view);
     252            return NULL;
     253            #if 0
     254            // Added this for possible future plans which might allow PHU=CELL
     255            phuCellName = phuNameFromHeader("CELL.NAME", formatSpec, phu); // Name of the cell
     256            int cellNum = findCell(chip, phuCellName); // Cell number
     257            if (cellNum == -1) {
     258                psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", phuCellName, phuChipName);
     259                psFree(view);
     260                return NULL;
     261            }
     262            cell = chip->cells->data[cellNum];
     263            view->cell = cellNum;
     264
     265            if (cell->hdu) {
     266                // Something's already here
     267                psError(PS_ERR_IO, true, "Unable to add source since cell already has a PHU.\n");
     268                psFree(view);
     269                return NULL;
     270            }
     271            cell->hdu = phdu;
     272            pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, true, NULL);
     273            #endif
     274
     275        } else {
     276            psError(PS_ERR_IO, true, "The format of the PHU (%s) is not FPA, CHIP or CELL.\n", phuType);
     277            psFree(view);
     278            return NULL;
     279        }
    202280    }
    203281
     
    206284    if (!mdok || strlen(extType) == 0) {
    207285        psError(PS_ERR_IO, false, "Unable to find EXTENSIONS in the format specification.\n");
    208         return false;
     286        psFree(view);
     287        return NULL;
    209288    }
    210289    psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
    211290    if (!mdok || !contents) {
    212291        psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n");
    213         return false;
    214     }
    215 
     292        psFree(view);
     293        return NULL;
     294    }
     295
     296
     297    // Now, different actions, according to what's in the file:
     298
     299    // No extensions --- it's all in the PHU
    216300    if (strcasecmp(extType, "NONE") == 0) {
    217         // No extensions --- it's all in the PHU
    218         psString chipType = chipNameFromHeader(formatSpec, phu); // Type of chip
    219         printf("chipType: %s<---\n", chipType);
    220         #if 1                                   // This is here for the courtesy of MegaCam, which has "CCD13   "
    221 
    222         char *space = NULL;             // Position of a space
    223         if ((space = strchr(chipType, ' '))) {
    224             psString temp = psStringNCopy(chipType, strlen(chipType) - strlen(space));
    225             // Free memory???
    226             chipType = temp;
    227         }
    228         #endif
    229 
    230         psString content = psMetadataLookupStr(&mdok, contents, chipType); // The content line
     301        if (strcasecmp(phuType, "FPA") == 0) {
     302            psError(PS_ERR_IO, true, "Not sure how to handle the case PHU=FPA, EXTENSIONS=NONE.\n");
     303            psFree(view);
     304            return NULL;
     305        }
     306        if (strcasecmp(phuType, "CELL") == 0) {
     307            psError(PS_ERR_IO, true, "Not sure how to handle the case PHU=CELL, EXTENSIONS=NONE.\n");
     308            psFree(view);
     309            return NULL;
     310        }
     311
     312        psString content = psMetadataLookupStr(&mdok, contents, phuChipName); // The content line
    231313        if (!mdok || strlen(content) == 0) {
    232             psError(PS_ERR_IO, true, "Cannot find chip %s in the list of CONTENTS.\n");
    233             psFree(chipType);
    234             psFree(content);
    235             return false;
     314            psError(PS_ERR_IO, true, "Cannot find chip %s in the list of CONTENTS.\n", phuChipName);
     315            psFree(view);
     316            return NULL;
    236317        }
    237318
     
    241322        parsePairs(&names, &values, content);
    242323        for (int i = 0; i < names->n; i++) {
    243             psString chipName = names->data[i]; // The name of the chip
    244             psString cellName = values->data[i]; // The name of the cell
    245             pmChip *chip = findChip(fpa, chipName); // The chip we're looking for
    246             if (!chip) {
    247                 psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in fpa --- ignored.\n", chipName);
     324            psString chipName = names->data[i]; // The name of the chip specified
     325            if (phuChipName && strcmp(phuChipName, chipName) != 0) {
     326                psLogMsg(__func__, PS_LOG_WARN, "Chip name in CONTENT (%s) does not match chip name from PHU "
     327                         "(%s) --- there may be problems when reading!\n", chipName, phuChipName);
     328                // Find the other chip
     329                int chipNum = findChip(fpa, chipName); // The chip we're looking for
     330                if (chipNum == -1) {
     331                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in fpa --- ignored.\n", chipName);
     332                    continue;
     333                }
     334                chip = fpa->chips->data[chipNum];
     335            }
     336            psString cellName = values->data[i]; // The name of the cell specified
     337            int cellNum = findCell(chip, cellName); // The cell we're looking for
     338            if (cellNum == -1) {
     339                psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored.\n",
     340                         cellName, chipName);
    248341                continue;
    249342            }
    250             pmCell *cell = findCell(chip, cellName); // The cell we're looking for
    251             if (!cell) {
    252                 psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored.\n", cellName,
    253                          chipName);
    254                 continue;
    255             }
     343            cell = chip->cells->data[cellNum];
     344
    256345            psMetadata *cellData = getCellData(format, cellName); // Data for this cell
    257346
    258             // Have already plugged in the PHU
     347            // Have already plugged in the PHU, which is all we have
    259348
    260349            // Put in the cell data
     
    265354            }
    266355            cell->config = psMemIncrRefCounter(cellData);
    267             pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, NULL);
    268         }
    269         return true;
    270     }
    271 
    272 
    273     // Go through the contents
     356            pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
     357        }
     358
     359        return view;
     360    }
     361
     362
     363    // Otherwise, go through the contents
    274364    psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL);
    275365    psMetadataItem *contentsItem = NULL; // Item from contents
     
    295385                psString chipName = names->data[i]; // The name of the chip
    296386                psString cellName = values->data[i]; // The name of the cell
    297                 pmChip *chip = findChip(fpa, chipName); // The chip we're looking for
    298                 if (!chip) {
     387                int chipNum = findChip(fpa, chipName); // The chip we're looking for
     388                if (chipNum == -1) {
    299389                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in FPA --- ignored.\n", chipName);
    300390                    continue;
    301391                }
    302                 pmCell *cell = findCell(chip, cellName); // The cell we're looking for
    303                 if (!cell) {
     392                chip = fpa->chips->data[chipNum];
     393                int cellNum = findCell(chip, cellName); // The cell we're looking for
     394                if (cellNum == -1) {
    304395                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored\n",
    305396                             cellName, chipName);
    306397                    continue;
    307398                }
     399                pmCell *cell = chip->cells->data[cellNum];
    308400                psMetadata *cellData = getCellData(format, cellName); // Data for this cell
    309401
     
    322414                }
    323415                cell->config = psMemIncrRefCounter(cellData);
    324                 pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, NULL);
     416                pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
    325417            }
    326418
     
    331423            if (! fpa->hdu->phu) {
    332424                // Need to look up the name of the chip
    333                 chipName = chipNameFromHeader(formatSpec, phu);
    334                 chip = findChip(fpa, chipName);
    335                 if (!chip) {
     425                chipName = phuNameFromHeader("CHIP.NAME", formatSpec, phu);
     426                int chipNum = findChip(fpa, chipName);
     427                if (chipNum == -1) {
    336428                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in FPA --- ignored.\n", chipName);
    337429                    continue;
    338430                }
     431                chip = fpa->chips->data[chipNum];
    339432            }
    340433            for (int i = 0; i < names->n; i++) {
     
    345438                    chipName = names->data[i];
    346439                    cellName = cellType;
    347                     chip = findChip(fpa, chipName);
    348                     if (! chip) {
     440                    int chipNum = findChip(fpa, chipName); // The chip we're looking for
     441                    if (chipNum == -1) {
    349442                        psLogMsg(__func__, PS_LOG_WARN, "Unable to find chip %s in FPA --- ignored.\n",
    350443                                 chipName);
    351444                        continue;
    352445                    }
     446                    chip = fpa->chips->data[chipNum];
    353447                } else {
    354448                    // We've got cellName:cellType and the chipName comes from before
    355449                    cellName = names->data[i];
    356450                }
    357                 pmCell *cell = findCell(chip, cellName); // The cell we're looking for
    358                 if (!cell) {
     451                int cellNum = findCell(chip, cellName); // The cell we're looking for
     452                if (cellNum == -1) {
    359453                    psLogMsg(__func__, PS_LOG_WARN, "Unable to find cell %s in chip %s --- ignored.\n",
    360454                             cellName, chipName);
    361455                    continue;
    362456                }
     457                pmCell *cell = chip->cells->data[cellNum];
    363458                psMetadata *cellData = getCellData(format, cellType); // Data for this cell
    364459
     
    378473                }
    379474                cell->config = psMemIncrRefCounter(cellData);
    380                 pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, NULL);
     475                pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
    381476            }
    382477
     
    390485    pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_DEFAULTS, NULL);
    391486
    392     return true;
     487    return view;
    393488}
    394489
     
    663758                pmReadout *readout = readouts->data[k]; // The readout
    664759                psImage *image = readout->image; // The image
    665                 psTrace(__func__, 8, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 +
    666                         image->numCols, image->row0, image->row0 + image->numRows, image->numCols,
    667                         image->numRows);
     760                if (image) {
     761                    psTrace(__func__, 8, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 +
     762                            image->numCols, image->row0, image->row0 + image->numRows, image->numCols,
     763                            image->numRows);
     764                }
    668765            } // Iterating over cell
    669766        } // Iterating over chip
  • branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.h

    r6580 r6618  
    44#include "pslib.h"
    55#include "pmFPA.h"
     6#include "pmFPAview.h"
    67
    78// Construct an FPA instance on the basis of a camera configuration
     
    910                     );
    1011
    11 // Add an input file to the FPA
    12 bool pmFPAAddSource(pmFPA *fpa,         // FPA to which to add
    13                     pmChip *chip,       // Chip to which to add, or NULL
    14                     pmCell *cell,       // Cell to which to add, or NULL
    15                     psMetadata *phu,    // Primary header of file
    16                     psMetadata *format  // Format of file
    17                    );
     12pmFPAview *pmFPAAddSource(pmFPA *fpa, // The FPA
     13                          psMetadata *phu, // Primary header of file
     14                          psMetadata *format // Format of file
     15                         );
    1816
    1917// Print out the FPA
  • branches/rel10_ifa/psModules/src/astrom/pmFPARead.c

    r6582 r6618  
    137137#endif
    138138
     139static bool badRegion(const psRegion *region)
     140{
     141    return isnan(region->x0) || isnan(region->x1) || isnan(region->y0) || isnan(region->y1);
     142}
    139143
    140144// Carve a readout from the image pixels
     
    148152
    149153    // The image corresponding to the trim region
     154    if (badRegion(trimsec)) {
     155        psString regionString = psRegionToString(*trimsec);
     156        psError(PS_ERR_IO, true, "Invalid trim section: %s\n", regionString);
     157        psFree(regionString);
     158        psFree(readout);
     159        return NULL;
     160    }
    150161    readout->image = psMemIncrRefCounter(psImageSubset(image, *trimsec));
    151162
     
    154165    psRegion *biassec = NULL;       // A BIASSEC region from the list
    155166    while ((biassec = psListGetAndIncrement(iter))) {
     167        if (badRegion(trimsec)) {
     168            psString regionString = psRegionToString(*biassec);
     169            psError(PS_ERR_IO, true, "Invalid bias section: %s\n", regionString);
     170            psFree(regionString);
     171            psFree(readout);
     172            return NULL;
     173        }
    156174        psImage *overscan = psMemIncrRefCounter(psImageSubset(image, *biassec));
    157175        psListAdd(readout->bias, PS_LIST_TAIL, overscan);
     
    192210    }
    193211
    194     pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, NULL);
     212    pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL);
    195213
    196214    // Having read the cell, we now have to cut it up
     
    216234               )
    217235{
     236    bool success = false;               // Were we able to read at least one HDU?
    218237    psArray *cells = chip->cells;       // Array of cells
    219238    for (int i = 0; i < cells->n; i++) {
    220239        pmCell *cell = cells->data[i];  // The cell of interest
    221         if (!pmCellRead(cell, fits, db)) {
    222             psError(PS_ERR_IO, false, "Unable to read cell %d.\n", i);
    223             return false;
    224         }
    225         pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, NULL);
    226     }
    227 
    228     return true;
     240        success |= pmCellRead(cell, fits, db);
     241    }
     242    if (success) {
     243        pmConceptsReadChip(chip, PM_CONCEPT_SOURCE_HEADER, false, NULL);
     244    }
     245
     246    return success;
    229247}
    230248
     
    235253              )
    236254{
    237     psArray *chips = fpa->chips;       // Array of chips
     255    bool success = false;               // Were we able to read at least one HDU?
     256    psArray *chips = fpa->chips;        // Array of chips
    238257    for (int i = 0; i < chips->n; i++) {
    239258        pmChip *chip = chips->data[i];  // The cell of interest
    240         if (!pmChipRead(chip, fits, db)) {
    241             psError(PS_ERR_IO, false, "Unable to read chip %d.\n", i);
    242             return false;
    243         }
     259        success |= pmChipRead(chip, fits, db);
     260    }
     261    if (success) {
    244262        pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
    245     }
    246 
    247     return true;
     263    } else {
     264        psLogMsg(__func__, PS_LOG_WARN, "Unable to read any chips in FPA.\n");
     265    }
     266
     267    return success;
    248268}
    249269
  • branches/rel10_ifa/psModules/src/astrom/pmFPAview.h

    r6580 r6618  
    77*  @author EAM, IfA
    88*
    9 *  @version $Revision: 1.1.2.5 $ $Name: not supported by cvs2svn $
    10 *  @date $Date: 2006-03-14 04:40:37 $
     9*  @version $Revision: 1.1.2.6 $ $Name: not supported by cvs2svn $
     10*  @date $Date: 2006-03-17 01:47:44 $
    1111*
    1212*  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
     
    3232typedef struct
    3333{
    34     int chip;
    35     int cell;
    36     int readout;
    37     int nRows;
    38     int iRows;
     34    int chip;                           // Number of the chip, or -1 for all
     35    int cell;                           // Number of the cell, or -1 for all
     36    int readout;                        // Number of the readout, or -1 for all
     37    int nRows;                          // Maximum number of rows per readout segment read, or 0 for all
     38    int iRows;                          // Starting point for this read
    3939    pmFPA *fpa;
    4040}
Note: See TracChangeset for help on using the changeset viewer.