IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 4, 2008, 3:32:28 PM (18 years ago)
Author:
Paul Price
Message:

I've implemented the chip-dependent concepts. It uses a generalised version of the dependent DEFAULT concepts, which can, unfortunately, make the camera format configuration a bit longer, but it consolidates code and keeps things simple both for the code and the configuration.

In the process, I took care of a couple of other concept bugs that have been sitting in my inbox for nearly a year:

  • FPA.NAME has been replaced with FPA.OBS, which is intended to be an observation identifier (bug 885). You're welcome to change the name, so long as you also volunteer to fix all the camera formats.
  • FPA.CAMERA is automatically set (on construction of the FPA) to the camera name as used by the configuration files (bug 931). I've changed the ppStats REGISTER recipe to use FPA.CAMERA instead of FPA.INSTRUMENT (which is retained in the concepts as the instrument's name according to the instrument, whereas FPA.CAMERA is the instrument's name according to our configuration).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/concepts/pmConcepts.c

    r17874 r17911  
    462462}
    463463
     464// Register a concept
     465#define CONCEPT_REGISTER_FUNCTION(TYPENAME, SUFFIX, DEFAULT) \
     466static void conceptRegister##SUFFIX(const char *name, /* Name of concept */ \
     467                                    const char *comment, /* Comment for concept */ \
     468                                    pmConceptParseFunc parse, /* Parsing function */ \
     469                                    pmConceptFormatFunc format, /* Formatting function */ \
     470                                    bool required, /* Required concept? */ \
     471                                    pmFPALevel level /* Level at which concept applies */ \
     472    ) \
     473{ \
     474    psMetadataItem *item = psMetadataItemAlloc##TYPENAME(name, comment, DEFAULT); /* Item to add */ \
     475    pmConceptRegister(item, parse, format, required, level); \
     476    psFree(item); \
     477    return; \
     478}
     479
     480CONCEPT_REGISTER_FUNCTION(Str, Str, "");
     481CONCEPT_REGISTER_FUNCTION(F32, F32, NAN);
     482CONCEPT_REGISTER_FUNCTION(F64, F64, NAN);
     483CONCEPT_REGISTER_FUNCTION(S32, Enum, -1); // For enums: set default to -1
     484CONCEPT_REGISTER_FUNCTION(S32, S32, 0); // For values: set default to 0
     485
     486static void conceptRegisterTime(const char *name, /* Name of concept */ \
     487                                const char *comment, /* Comment for concept */ \
     488                                bool required, /* Required concept? */ \
     489                                pmFPALevel level /* Level at which concept applies */ \
     490    )
     491{
     492    psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time
     493    // Not particularly distinguishing, but should be good enough
     494    time->sec = 0;
     495    time->nsec = 0;
     496    psMetadataItem *item = psMetadataItemAlloc(name, PS_DATA_TIME, comment, time);
     497    psFree(time);
     498    pmConceptRegister(item, (pmConceptParseFunc)p_pmConceptParse_TIME,
     499                      (pmConceptFormatFunc)p_pmConceptFormat_TIME, required, level);
     500    psFree(item);
     501}
    464502
    465503bool pmConceptsInit(void)
     
    470508
    471509    bool init = false;                  // Did we initialise anything?
     510
    472511    if (! conceptsFPA) {
    473512        conceptsFPA = psMetadataAlloc();
     
    475514
    476515        // Install the standard concepts
    477 
    478         // FPA.TELESCOPE
    479         {
    480             psMetadataItem *fpaTelescope = psMetadataItemAllocStr("FPA.TELESCOPE", "Camera used", "");
    481             pmConceptRegister(fpaTelescope, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    482             psFree(fpaTelescope);
    483         }
    484 
    485         // FPA.INSTRUMENT
    486         {
    487             psMetadataItem *fpaInstrument = psMetadataItemAllocStr("FPA.INSTRUMENT", "Camera used", "");
    488             pmConceptRegister(fpaInstrument, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    489             psFree(fpaInstrument);
    490         }
    491 
    492         // FPA.DETECTOR
    493         {
    494             psMetadataItem *fpaDetector = psMetadataItemAllocStr("FPA.DETECTOR", "Detector used", "");
    495             pmConceptRegister(fpaDetector, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    496             psFree(fpaDetector);
    497         }
    498 
    499         // FPA.CAMERA
    500         // XXX keep or deprecate?
    501         {
    502             psMetadataItem *fpaCamera = psMetadataItemAllocStr("FPA.CAMERA", "Camera used", "");
    503             pmConceptRegister(fpaCamera, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    504             psFree(fpaCamera);
    505         }
    506 
    507         // FPA.COMMENT
    508         {
    509             psMetadataItem *item = psMetadataItemAllocStr("FPA.COMMENT", "Obs Comment", "");
    510             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    511             psFree(item);
    512         }
    513 
    514         // FPA.FOCUS
    515         {
    516             psMetadataItem *fpaFocus = psMetadataItemAllocF32("FPA.FOCUS", "Telescope focus", NAN);
    517             pmConceptRegister(fpaFocus, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    518             psFree(fpaFocus);
    519         }
    520 
    521         // FPA.AIRMASS
    522         {
    523             psMetadataItem *fpaAirmass = psMetadataItemAllocF32("FPA.AIRMASS", "Airmass at boresight", NAN);
    524             pmConceptRegister(fpaAirmass, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    525             psFree(fpaAirmass);
    526         }
    527 
    528         // FPA.FILTERID
    529         {
    530             psMetadataItem *fpaFilterid = psMetadataItemAllocStr("FPA.FILTERID",
    531                                                                  "Filter used (parsed, abstract name) ", "");
    532             pmConceptRegister(fpaFilterid, (pmConceptParseFunc)p_pmConceptParse_FPA_FILTER,
    533                               (pmConceptFormatFunc)p_pmConceptFormat_FPA_FILTER, false, PM_FPA_LEVEL_FPA);
    534             psFree(fpaFilterid);
    535         }
    536 
    537         // FPA.FILTER
    538         {
    539             psMetadataItem *fpaFilter = psMetadataItemAllocStr("FPA.FILTER", "Filter used", "");
    540             pmConceptRegister(fpaFilter, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    541             psFree(fpaFilter);
    542         }
    543 
    544         // FPA.POSANGLE
    545         {
    546             psMetadataItem *fpaPosangle = psMetadataItemAllocF32("FPA.POSANGLE",
    547                                           "Position angle of instrument", NAN);
    548             pmConceptRegister(fpaPosangle, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    549             psFree(fpaPosangle);
    550         }
    551 
    552         // FPA.RADECSYS
    553         {
    554             psMetadataItem *fpaRadecsys = psMetadataItemAllocStr("FPA.RADECSYS",
    555                                           "Celestial coordinate system", "");
    556             pmConceptRegister(fpaRadecsys, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    557             psFree(fpaRadecsys);
    558         }
    559 
    560         // FPA.RA
    561         {
    562             psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN);
    563             pmConceptRegister(fpaRa, (pmConceptParseFunc)p_pmConceptParse_FPA_Coords,
    564                               (pmConceptFormatFunc)p_pmConceptFormat_FPA_Coords, false, PM_FPA_LEVEL_FPA);
    565             psFree(fpaRa);
    566         }
    567 
    568         // FPA.DEC
    569         {
    570             psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN);
    571             pmConceptRegister(fpaDec, (pmConceptParseFunc)p_pmConceptParse_FPA_Coords,
    572                               (pmConceptFormatFunc)p_pmConceptFormat_FPA_Coords, false, PM_FPA_LEVEL_FPA);
    573             psFree(fpaDec);
    574         }
    575 
    576         // FPA.OBSTYPE
    577         {
    578             psMetadataItem *fpaObstype = psMetadataItemAllocStr("FPA.OBSTYPE", "Type of observation", "");
    579             pmConceptRegister(fpaObstype, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    580             psFree(fpaObstype);
    581         }
    582 
    583         // FPA.OBJECT
    584         {
    585             psMetadataItem *fpaObject = psMetadataItemAllocStr("FPA.OBJECT", "Object of observation", "");
    586             pmConceptRegister(fpaObject, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    587             psFree(fpaObject);
    588         }
    589 
    590         // FPA.ALT
    591         {
    592             psMetadataItem *fpaAlt = psMetadataItemAllocF64("FPA.ALT", "Altitude of telescope", NAN);
    593             pmConceptRegister(fpaAlt, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    594             psFree(fpaAlt);
    595         }
    596 
    597         // FPA.AZ
    598         {
    599             psMetadataItem *fpaAz = psMetadataItemAllocF64("FPA.AZ", "Azimuth of telescope", NAN);
    600             pmConceptRegister(fpaAz, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    601             psFree(fpaAz);
    602         }
    603 
    604         // FPA.TIMESYS
    605         {
    606             psMetadataItem *fpaTimesys = psMetadataItemAllocS32("FPA.TIMESYS", "Time system", -1);
    607             pmConceptRegister(fpaTimesys, (pmConceptParseFunc)p_pmConceptParse_TIMESYS,
    608                               (pmConceptFormatFunc)p_pmConceptFormat_TIMESYS, false, PM_FPA_LEVEL_FPA);
    609             psFree(fpaTimesys);
    610         }
    611 
    612         // FPA.TIME
    613         {
    614             psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time
    615             // Not particularly distinguishing, but should be good enough
    616             time->sec = 0;
    617             time->nsec = 0;
    618             psMetadataItem *fpaTime = psMetadataItemAlloc("FPA.TIME", PS_DATA_TIME,
    619                                       "Time of exposure", time);
    620             psFree(time);
    621             pmConceptRegister(fpaTime, (pmConceptParseFunc)p_pmConceptParse_TIME,
    622                               (pmConceptFormatFunc)p_pmConceptFormat_TIME, false, PM_FPA_LEVEL_FPA);
    623             psFree(fpaTime);
    624         }
    625 
    626         // FPA.TEMP
    627         {
    628             psMetadataItem *fpaTemp = psMetadataItemAllocF32("FPA.TEMP", "Temperature of focal plane", NAN);
    629             pmConceptRegister(fpaTemp, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    630             psFree(fpaTemp);
    631         }
    632 
    633         // FPA.M1X,Y,Z,TIP,TILT
    634         {
    635             psMetadataItem *item = psMetadataItemAllocF32("FPA.M1X", "Primary Mirror X Position", NAN);
    636             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    637             psFree(item);
    638         }
    639         {
    640             psMetadataItem *item = psMetadataItemAllocF32("FPA.M1Y", "Primary Mirror Y Position", NAN);
    641             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    642             psFree(item);
    643         }
    644         {
    645             psMetadataItem *item = psMetadataItemAllocF32("FPA.M1Z", "Primary Mirror Z Position", NAN);
    646             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    647             psFree(item);
    648         }
    649         {
    650             psMetadataItem *item = psMetadataItemAllocF32("FPA.M1TIP", "Primary Mirror TIP", NAN);
    651             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    652             psFree(item);
    653         }
    654         {
    655             psMetadataItem *item = psMetadataItemAllocF32("FPA.M1TILT", "Primary Mirror TILT", NAN);
    656             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    657             psFree(item);
    658         }
    659 
    660         // FPA.M2X,Y,Z,TIP,TILT
    661         {
    662             psMetadataItem *item = psMetadataItemAllocF32("FPA.M2X", "Primary Mirror X Position", NAN);
    663             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    664             psFree(item);
    665         }
    666         {
    667             psMetadataItem *item = psMetadataItemAllocF32("FPA.M2Y", "Primary Mirror Y Position", NAN);
    668             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    669             psFree(item);
    670         }
    671         {
    672             psMetadataItem *item = psMetadataItemAllocF32("FPA.M2Z", "Primary Mirror Z Position", NAN);
    673             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    674             psFree(item);
    675         }
    676         {
    677             psMetadataItem *item = psMetadataItemAllocF32("FPA.M2TIP", "Primary Mirror TIP", NAN);
    678             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    679             psFree(item);
    680         }
    681         {
    682             psMetadataItem *item = psMetadataItemAllocF32("FPA.M2TILT", "Primary Mirror TILT", NAN);
    683             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    684             psFree(item);
    685         }
    686 
    687         // FPA.ENV.*
    688         {
    689             psMetadataItem *item = psMetadataItemAllocF32("FPA.ENV.TEMP", "Environment: Temperature", NAN);
    690             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    691             psFree(item);
    692         }
    693         {
    694             psMetadataItem *item = psMetadataItemAllocF32("FPA.ENV.HUMID", "Environment: Humidity", NAN);
    695             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    696             psFree(item);
    697         }
    698         {
    699             psMetadataItem *item = psMetadataItemAllocF32("FPA.ENV.WIND", "Environment: Wind Speed", NAN);
    700             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    701             psFree(item);
    702         }
    703         {
    704             psMetadataItem *item = psMetadataItemAllocF32("FPA.ENV.DIR", "Environment: Wind Direction", NAN);
    705             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    706             psFree(item);
    707         }
    708 
    709         // FPA.TELTEMP.*
    710         {
    711             psMetadataItem *item = psMetadataItemAllocF32("FPA.TELTEMP.M1", "Telescope Temperatures: M1", NAN);
    712             pmConceptRegister(item, p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
    713             psFree(item);
    714         }
    715         {
    716             psMetadataItem *item = psMetadataItemAllocF32("FPA.TELTEMP.M1CELL", "Telescope Temperatures: M1 CELL", NAN);
    717             pmConceptRegister(item, p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
    718             psFree(item);
    719         }
    720         {
    721             psMetadataItem *item = psMetadataItemAllocF32("FPA.TELTEMP.M2", "Telescope Temperatures: M2", NAN);
    722             pmConceptRegister(item, p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
    723             psFree(item);
    724         }
    725         {
    726             psMetadataItem *item = psMetadataItemAllocF32("FPA.TELTEMP.SPIDER", "Telescope Temperatures: SPIDER", NAN);
    727             pmConceptRegister(item, p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
    728             psFree(item);
    729         }
    730         {
    731             psMetadataItem *item = psMetadataItemAllocF32("FPA.TELTEMP.TRUSS", "Telescope Temperatures: TRUSS", NAN);
    732             pmConceptRegister(item, p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
    733             psFree(item);
    734         }
    735         {
    736             psMetadataItem *item = psMetadataItemAllocF32("FPA.TELTEMP.EXTRA", "Telescope Temperatures: EXTRA", NAN);
    737             pmConceptRegister(item, p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
    738             psFree(item);
    739         }
    740 
    741         // FPA.PON.TIME
    742         {
    743             psMetadataItem *item = psMetadataItemAllocF32("FPA.PON.TIME", "Power On Time", NAN);
    744             pmConceptRegister(item, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    745             psFree(item);
    746         }
    747 
    748         // FPA.EXPOSURE
    749         {
    750             psMetadataItem *fpaExposure = psMetadataItemAllocF32("FPA.EXPOSURE",
    751                                           "Exposure time (sec)", NAN);
    752             pmConceptRegister(fpaExposure, NULL, NULL, false, PM_FPA_LEVEL_FPA);
    753             psFree(fpaExposure);
    754         }
    755 
    756         // Done with FPA level concepts
     516        conceptRegisterStr("FPA.TELESCOPE", "Telescope of origin", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     517        conceptRegisterStr("FPA.INSTRUMENT", "Instrument name (according to the instrument)",
     518                           NULL, NULL, false, PM_FPA_LEVEL_FPA);
     519        conceptRegisterStr("FPA.DETECTOR", "Detector name", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     520        conceptRegisterStr("FPA.COMMENT", "Observation comment", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     521        conceptRegisterF32("FPA.FOCUS", "Telescope focus", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     522        conceptRegisterF32("FPA.AIRMASS", "Airmass at boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     523        conceptRegisterStr("FPA.FILTERID", "Filter used (parsed, abstract name)",
     524                           NULL, NULL, false, PM_FPA_LEVEL_FPA);
     525        conceptRegisterStr("FPA.FILTER", "Filter used (instrument name)",
     526                           NULL, NULL, false, PM_FPA_LEVEL_FPA);
     527        conceptRegisterF32("FPA.POSANGLE", "Position angle of instrument",
     528                           NULL, NULL, false, PM_FPA_LEVEL_FPA);
     529        conceptRegisterStr("FPA.RADECSYS", "Celestial coordinate system",
     530                           NULL, NULL, false, PM_FPA_LEVEL_FPA);
     531        conceptRegisterF64("FPA.RA", "Right Ascension of boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     532        conceptRegisterF64("FPA.DEC", "Declination of boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     533        conceptRegisterStr("FPA.OBSTYPE", "Type of observation", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     534        conceptRegisterStr("FPA.OBJECT", "Object of observation", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     535        conceptRegisterF64("FPA.ALT", "Altitude of boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     536        conceptRegisterF64("FPA.AZ", "Azimuth of boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     537        conceptRegisterEnum("FPA.TIMESYS", "Time system", p_pmConceptParse_TIMESYS,
     538                            p_pmConceptFormat_TIMESYS, false, PM_FPA_LEVEL_FPA);
     539        conceptRegisterF32("FPA.TEMP", "Temperature of focal plane", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     540        conceptRegisterF32("FPA.M1X", "Primary Mirror X Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     541        conceptRegisterF32("FPA.M1Y", "Primary Mirror Y Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     542        conceptRegisterF32("FPA.M1Z", "Primary Mirror Z Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     543        conceptRegisterF32("FPA.M1TIP", "Primary Mirror TIP", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     544        conceptRegisterF32("FPA.M1TILT", "Primary Mirror TILT", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     545        conceptRegisterF32("FPA.M2X", "Primary Mirror X Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     546        conceptRegisterF32("FPA.M2Y", "Primary Mirror Y Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     547        conceptRegisterF32("FPA.M2Z", "Primary Mirror Z Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     548        conceptRegisterF32("FPA.M2TIP", "Primary Mirror TIP", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     549        conceptRegisterF32("FPA.M2TILT", "Primary Mirror TILT", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     550        conceptRegisterF32("FPA.ENV.TEMP", "Environment: Temperature", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     551        conceptRegisterF32("FPA.ENV.HUMID", "Environment: Humidity", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     552        conceptRegisterF32("FPA.ENV.WIND", "Environment: Wind speed", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     553        conceptRegisterF32("FPA.ENV.DIR", "Environment: Wind direction", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     554        conceptRegisterF32("FPA.TELTEMP.M1", "Telescope Temperatures: M1",
     555                           p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
     556        conceptRegisterF32("FPA.TELTEMP.M1CELL", "Telescope Temperatures: M1 cell",
     557                           p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
     558        conceptRegisterF32("FPA.TELTEMP.M2", "Telescope Temperatures: M2",
     559                           p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
     560        conceptRegisterF32("FPA.TELTEMP.SPIDER", "Telescope Temperatures: spider",
     561                           p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
     562        conceptRegisterF32("FPA.TELTEMP.TRUSS", "Telescope Temperatures: truss",
     563                           p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
     564        conceptRegisterF32("FPA.TELTEMP.EXTRA", "Telescope Temperatures: extra",
     565                           p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);
     566        conceptRegisterF32("FPA.PON.TIME", "Power On Time", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     567        conceptRegisterF32("FPA.EXPOSURE", "Exposure time (sec)", NULL, NULL, false, PM_FPA_LEVEL_FPA);
     568        conceptRegisterTime("FPA.TIME", "Time of exposure", false, PM_FPA_LEVEL_FPA);
    757569    }
    758570    if (! conceptsChip) {
     
    761573
    762574        // Install the standard concepts
    763 
    764         // CHIP.XPARITY
    765         {
    766             psMetadataItem *chipXparity = psMetadataItemAllocS32("CHIP.XPARITY",
    767                                           "Orientation in x compared to the rest of the FPA", 0);
    768             pmConceptRegister(chipXparity, NULL, NULL, true, PM_FPA_LEVEL_CHIP);
    769             psFree(chipXparity);
    770         }
    771 
    772         // CHIP.YPARITY
    773         {
    774             psMetadataItem *chipYparity = psMetadataItemAllocS32("CHIP.YPARITY",
    775                                           "Orientation in y compared to the rest of the FPA", 0);
    776             pmConceptRegister(chipYparity, NULL, NULL, true, PM_FPA_LEVEL_CHIP);
    777             psFree(chipYparity);
    778         }
    779 
    780         // CHIP.X0
    781         {
    782             psMetadataItem *chipX0 = psMetadataItemAllocS32("CHIP.X0", "Position of (0,0) on the FPA", 0);
    783             pmConceptRegister(chipX0, (pmConceptParseFunc)p_pmConceptParse_Positions,
    784                               (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CHIP);
    785             psFree(chipX0);
    786         }
    787 
    788         // CHIP.Y0
    789         {
    790             psMetadataItem *chipY0 = psMetadataItemAllocS32("CHIP.Y0", "Position of (0,0) on the FPA", 0);
    791             pmConceptRegister(chipY0, (pmConceptParseFunc)p_pmConceptParse_Positions,
    792                               (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CHIP);
    793             psFree(chipY0);
    794         }
    795 
    796         // CHIP.XSIZE
    797         {
    798             psMetadataItem *chipXsize = psMetadataItemAllocS32("CHIP.XSIZE", "Size of chip (pixels)", 0);
    799             pmConceptRegister(chipXsize, NULL, NULL, true, PM_FPA_LEVEL_CHIP);
    800             psFree(chipXsize);
    801         }
    802 
    803         // CHIP.YSIZE
    804         {
    805             psMetadataItem *chipYsize = psMetadataItemAllocS32("CHIP.YSIZE", "Size of chip (pixels)", 0);
    806             pmConceptRegister(chipYsize, NULL, NULL, true, PM_FPA_LEVEL_CHIP);
    807             psFree(chipYsize);
    808         }
    809 
    810         // CHIP.TEMP
    811         {
    812             psMetadataItem *chipTemp = psMetadataItemAllocF32("CHIP.TEMP", "Temperature of chip", NAN);
    813             pmConceptRegister(chipTemp, NULL, NULL, false, PM_FPA_LEVEL_CHIP);
    814             psFree(chipTemp);
    815         }
    816 
    817         // CHIP.ID
    818         {
    819             psMetadataItem *chipID = psMetadataItemAllocStr("CHIP.ID", "Chip identifier", "");
    820             pmConceptRegister(chipID, NULL, NULL, false, PM_FPA_LEVEL_CHIP);
    821             psFree(chipID);
    822         }
    823 
    824         // Done with chip level concepts
    825     }
     575        conceptRegisterS32("CHIP.XPARITY", "Orientation in x compared to the rest of the FPA",
     576                           NULL, NULL, true, PM_FPA_LEVEL_CHIP);
     577
     578        conceptRegisterS32("CHIP.YPARITY", "Orientation in y compared to the rest of the FPA",
     579                           NULL, NULL, true, PM_FPA_LEVEL_CHIP);
     580        conceptRegisterS32("CHIP.X0", "Position of (0,0) on the FPA",
     581                           (pmConceptParseFunc)p_pmConceptParse_Positions,
     582                           (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CHIP);
     583        conceptRegisterS32("CHIP.Y0", "Position of (0,0) on the FPA",
     584                           (pmConceptParseFunc)p_pmConceptParse_Positions,
     585                           (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CHIP);
     586        conceptRegisterS32("CHIP.XSIZE", "Size of chip (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CHIP);
     587        conceptRegisterS32("CHIP.YSIZE", "Size of chip (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CHIP);
     588        conceptRegisterF32("CHIP.TEMP", "Temperature of chip", NULL, NULL, false, PM_FPA_LEVEL_CHIP);
     589        conceptRegisterStr("CHIP.ID", "Chip identifier", NULL, NULL, false, PM_FPA_LEVEL_CHIP);
     590    }
     591
    826592    if (! conceptsCell) {
    827593        conceptsCell = psMetadataAlloc();
     
    829595
    830596        // Install the standard concepts
    831 
    832         // CELL.GAIN
    833         {
    834             psMetadataItem *cellGain = psMetadataItemAllocF32("CELL.GAIN", "CCD gain (e/count)", NAN);
    835             pmConceptRegister(cellGain, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    836             psFree(cellGain);
    837         }
    838 
    839         // CELL.READNOISE
    840         {
    841             psMetadataItem *cellReadnoise = psMetadataItemAllocF32("CELL.READNOISE",
    842                                             "CCD read noise (e)", NAN);
    843             pmConceptRegister(cellReadnoise, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    844             psFree(cellReadnoise);
    845         }
    846 
    847         // CELL.SATURATION
    848         {
    849             psMetadataItem *cellSaturation = psMetadataItemAllocF32("CELL.SATURATION",
    850                                              "Saturation level (counts)", NAN);
    851             pmConceptRegister(cellSaturation, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    852             psFree(cellSaturation);
    853         }
    854 
    855         // CELL.BAD
    856         {
    857             psMetadataItem *cellBad = psMetadataItemAllocF32("CELL.BAD", "Bad level (counts)", NAN);
    858             pmConceptRegister(cellBad, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    859             psFree(cellBad);
    860         }
    861 
    862         // CELL.XPARITY
    863         {
    864             psMetadataItem *cellXparity = psMetadataItemAllocS32("CELL.XPARITY",
    865                                           "Orientation in x compared to the rest of the chip", 0);
    866             pmConceptRegister(cellXparity, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    867             psFree(cellXparity);
    868         }
    869 
    870         // CELL.YPARITY
    871         {
    872             psMetadataItem *cellYparity = psMetadataItemAllocS32("CELL.YPARITY",
    873                                           "Orientation in y compared to the rest of the chip", 0);
    874             pmConceptRegister(cellYparity, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    875             psFree(cellYparity);
    876         }
    877 
    878         // CELL.READDIR
    879         {
    880             psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR",
    881                                           "Read direction, rows=1, cols=2", 0);
    882             pmConceptRegister(cellReaddir, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    883             psFree(cellReaddir);
    884         }
    885 
     597        conceptRegisterF32("CELL.GAIN", "CCD gain (e/count)", NULL, NULL, true, PM_FPA_LEVEL_CELL);
     598        conceptRegisterF32("CELL.READNOISE", "CCD read noise (e)", NULL, NULL, true, PM_FPA_LEVEL_CELL);
     599        conceptRegisterF32("CELL.SATURATION", "Saturation level (counts)",
     600                           NULL, NULL, true, PM_FPA_LEVEL_CELL);
     601        conceptRegisterF32("CELL.BAD", "Bad level (counts)", NULL, NULL, true, PM_FPA_LEVEL_CELL);
     602        conceptRegisterS32("CELL.XPARITY", "Orientation in x compared to the rest of the chip",
     603                           NULL, NULL, true, PM_FPA_LEVEL_CELL);
     604        conceptRegisterS32("CELL.YPARITY", "Orientation in y compared to the rest of the chip",
     605                           NULL, NULL, true, PM_FPA_LEVEL_CELL);
     606        conceptRegisterS32("CELL.READDIR", "Read direction, rows=1, cols=2",
     607                           NULL, NULL, true, PM_FPA_LEVEL_CELL);
    886608
    887609        // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that
     
    890612        // readout is a plane in a 3D image.  We'll have to dream up some additional suffix to specify these,
    891613        // but for now....
    892 
    893         // CELL.EXPOSURE
    894         {
    895             psMetadataItem *cellExposure = psMetadataItemAllocF32("CELL.EXPOSURE",
    896                                            "Exposure time (sec)", NAN);
    897             pmConceptRegister(cellExposure, NULL, NULL, false, PM_FPA_LEVEL_CELL);
    898             psFree(cellExposure);
    899         }
    900 
    901         // CELL.DARKTIME
    902         {
    903             psMetadataItem *cellDarktime = psMetadataItemAllocF32("CELL.DARKTIME",
    904                                            "Time since flush (sec)", NAN);
    905             pmConceptRegister(cellDarktime, NULL, NULL, false, PM_FPA_LEVEL_CELL);
    906             psFree(cellDarktime);
    907         }
     614        conceptRegisterF32("CELL.EXPOSURE", "Exposure time (sec)", NULL, NULL, false, PM_FPA_LEVEL_CELL);
     615        conceptRegisterF32("CELL.DARKTIME", "Time since flush (sec)", NULL, NULL, false, PM_FPA_LEVEL_CELL);
     616
     617        conceptRegisterS32("CELL.XBIN", "Binning in x", (pmConceptParseFunc)p_pmConceptParse_CELL_Binning,
     618                           (pmConceptFormatFunc)p_pmConceptFormat_CELL_XBIN, true, PM_FPA_LEVEL_CELL);
     619        conceptRegisterS32("CELL.YBIN", "Binning in y",(pmConceptParseFunc)p_pmConceptParse_CELL_Binning,
     620                           (pmConceptFormatFunc)p_pmConceptFormat_CELL_YBIN, true, PM_FPA_LEVEL_CELL);
     621        conceptRegisterEnum("CELL.TIMESYS", "Time system", (pmConceptParseFunc)p_pmConceptParse_TIMESYS,
     622                            (pmConceptFormatFunc)p_pmConceptFormat_TIMESYS, false, PM_FPA_LEVEL_CELL);
     623        conceptRegisterTime("CELL.TIME", "Time of exposure", false, PM_FPA_LEVEL_CELL);
     624        conceptRegisterS32("CELL.X0", "Position of (0,0) on the chip",
     625                           (pmConceptParseFunc)p_pmConceptParse_Positions,
     626                           (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
     627        conceptRegisterS32("CELL.Y0", "Position of (0,0) on the chip",
     628                           (pmConceptParseFunc)p_pmConceptParse_Positions,
     629                           (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
     630        conceptRegisterS32("CELL.XSIZE", "Size of cell (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CELL);
     631        conceptRegisterS32("CELL.YSIZE", "Size of cell (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CELL);
     632        conceptRegisterS32("CELL.XWINDOW", "Start of cell window (pixels)",
     633                           (pmConceptParseFunc)p_pmConceptParse_Positions,
     634                           (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
     635        conceptRegisterS32("CELL.YWINDOW", "Start of cell window (pixels)",
     636                           (pmConceptParseFunc)p_pmConceptParse_Positions,
     637                           (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
    908638
    909639        // CELL.TRIMSEC
     
    930660        }
    931661
    932         // CELL.XBIN
    933         {
    934             psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0);
    935             pmConceptRegister(cellXbin, (pmConceptParseFunc)p_pmConceptParse_CELL_Binning,
    936                               (pmConceptFormatFunc)p_pmConceptFormat_CELL_XBIN, true, PM_FPA_LEVEL_CELL);
    937             psFree(cellXbin);
    938         }
    939 
    940         // CELL.YBIN
    941         {
    942             psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0);
    943             pmConceptRegister(cellYbin, (pmConceptParseFunc)p_pmConceptParse_CELL_Binning,
    944                               (pmConceptFormatFunc)p_pmConceptFormat_CELL_YBIN, true, PM_FPA_LEVEL_CELL);
    945             psFree(cellYbin);
    946         }
    947 
    948         // CELL.TIMESYS
    949         {
    950             psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1);
    951             pmConceptRegister(cellTimesys, (pmConceptParseFunc)p_pmConceptParse_TIMESYS,
    952                               (pmConceptFormatFunc)p_pmConceptFormat_TIMESYS, false, PM_FPA_LEVEL_CELL);
    953             psFree(cellTimesys);
    954         }
    955 
    956         // CELL.TIME
    957         {
    958             psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time
    959             // Not particularly distinguishing, but should be good enough
    960             time->sec = 0;
    961             time->nsec = 0;
    962             psMetadataItem *cellTime = psMetadataItemAlloc("CELL.TIME", PS_DATA_TIME,
    963                                        "Time of exposure", time);
    964             psFree(time);
    965             pmConceptRegister(cellTime, (pmConceptParseFunc)p_pmConceptParse_TIME,
    966                               (pmConceptFormatFunc)p_pmConceptFormat_TIME, false, PM_FPA_LEVEL_CELL);
    967             psFree(cellTime);
    968         }
    969 
    970         // CELL.X0
    971         {
    972             psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0);
    973             pmConceptRegister(cellX0, (pmConceptParseFunc)p_pmConceptParse_Positions,
    974                               (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
    975             psFree(cellX0);
    976         }
    977 
    978         // CELL.Y0
    979         {
    980             psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0);
    981             pmConceptRegister(cellY0, (pmConceptParseFunc)p_pmConceptParse_Positions,
    982                               (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
    983             psFree(cellY0);
    984         }
    985 
    986         // CELL.XSIZE
    987         {
    988             psMetadataItem *cellXsize = psMetadataItemAllocS32("CELL.XSIZE", "Size of cell (pixels)", 0);
    989             pmConceptRegister(cellXsize, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    990             psFree(cellXsize);
    991         }
    992 
    993         // CELL.YSIZE
    994         {
    995             psMetadataItem *cellYsize = psMetadataItemAllocS32("CELL.YSIZE", "Size of cell (pixels)", 0);
    996             pmConceptRegister(cellYsize, NULL, NULL, true, PM_FPA_LEVEL_CELL);
    997             psFree(cellYsize);
    998         }
    999 
    1000         // CELL.XWINDOW
    1001         {
    1002             psMetadataItem *cellXwindow = psMetadataItemAllocS32("CELL.XWINDOW",
    1003                                                                  "Start of cell window (pixels)", 0);
    1004             pmConceptRegister(cellXwindow, (pmConceptParseFunc)p_pmConceptParse_Positions,
    1005                               (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
    1006             psFree(cellXwindow);
    1007         }
    1008 
    1009         // CELL.YWINDOW
    1010         {
    1011             psMetadataItem *cellYwindow = psMetadataItemAllocS32("CELL.YWINDOW",
    1012                                                                  "Start of cell window (pixels)", 0);
    1013             pmConceptRegister(cellYwindow, (pmConceptParseFunc)p_pmConceptParse_Positions,
    1014                               (pmConceptFormatFunc)p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);
    1015             psFree(cellYwindow);
    1016         }
    1017662    }
    1018663
     
    1037682// List of concepts not to copy, for each level.
    1038683// Must be NULL-terminated
    1039 static const char *dontCopyConceptsFPA[] = { "FPA.NAME", 0 };
     684static const char *dontCopyConceptsFPA[] = { "FPA.NAME", "FPA.CAMERA", 0 };
    1040685static const char *dontCopyConceptsChip[] = { "CHIP.NAME", 0 };
    1041686static const char *dontCopyConceptsCell[] = { "CELL.NAME", "CELL.TRIMSEC", "CELL.BIASSEC", 0 };
     
    1202847// Interpolate the concept.  Generalises the FPA/Chip/Cell
    1203848#define CONCEPT_INTERPOLATE(SOURCE, NAME) \
    1204     if (strncmp(concept, NAME, 4) == 0) { \
     849    if (strncmp(concept, NAME, strlen(NAME)) == 0) { \
    1205850        if (!(SOURCE)) { \
    1206851            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot interpolate %s because %s not provided", \
     
    1274919    return string;
    1275920}
     921
     922
     923psMetadataItem *p_pmConceptsDepend(const char *name, const psMetadata *menu, const psMetadata *source,
     924                                   const pmFPA *fpa, const pmChip *chip, const pmCell *cell)
     925{
     926    psAssert(name && strlen(name) > 0, "Concept name is empty");
     927    psAssert(menu, "Must have menu");
     928    psAssert(source, "Must have source");
     929
     930    // Check for DEPEND
     931    psString depend = NULL; // The CONCEPT.DEPEND
     932    psStringAppend(&depend, "%s.DEPEND", name);
     933    bool mdok;                          // Status of MD lookup
     934    const char *dependConcept = psMetadataLookupStr(&mdok, source, depend); // The concept name
     935    if (!mdok || !dependConcept || strlen(dependConcept) == 0) {
     936        psError(PS_ERR_IO, true, "Unable to parse %s: couldn't find %s in DEFAULTS.\n", name, depend);
     937        psFree(depend);
     938        return NULL;
     939    }
     940    psFree(depend);
     941    // Now look up the depend value
     942    psMetadataItem *dependValue = NULL; // The value of the concept we're looking up
     943    if (cell) {
     944        dependValue = psMetadataLookup(cell->concepts, dependConcept);
     945    }
     946    if (chip && !dependValue) {
     947        dependValue = psMetadataLookup(chip->concepts, dependConcept);
     948    }
     949    if (fpa && !dependValue) {
     950        dependValue = psMetadataLookup(chip->concepts, dependConcept);
     951    }
     952    if (!dependValue) {
     953        // Not an error --- it may be specified some other way
     954        psTrace("psModules.concepts", 7, "Couldn't find DEPEND for %s", name);
     955        return NULL;
     956    }
     957    if (dependValue->type != PS_DATA_STRING) {
     958        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "%s is required to resolve %s in DEFAULTS, "
     959                "but it is not of type STRING.\n", dependConcept, name);
     960        return NULL;
     961    }
     962    const char *key = dependValue->data.V; // The key to the DEPEND menu
     963    psTrace("psModules.concepts", 7, "%s.DEPEND resolves to %s....\n", name, key);
     964
     965    return psMetadataLookup(menu, key);
     966}
     967
Note: See TracChangeset for help on using the changeset viewer.