IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 24803


Ignore:
Timestamp:
Jul 15, 2009, 2:33:17 PM (17 years ago)
Author:
eugene
Message:

interpret DARK.ORDINATE rule

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/pmDark.c

    r21183 r24803  
    22#include <pslib.h>
    33#include <string.h>
     4#include <strings.h>
    45
    56#include "psPolynomialMD.h"
     
    1213#include "pmReadoutStack.h"
    1314#include "pmDetrendThreads.h"
     15#include "pmErrorCodes.h"
    1416
    1517#include "pmDark.h"
     
    1719#define PM_DARK_FITS_EXTNAME "PS_DARK"  // FITS extension name for ordinates table
    1820#define PM_DARK_FITS_NAME    "NAME"     // Column name for concept name in ordinates table
     21#define PM_DARK_FITS_RULE    "RULE"     // Column name for concept rule in ordinates table
    1922#define PM_DARK_FITS_ORDER   "ORDER"    // Column name for polynomial order in ordinates table
    2023#define PM_DARK_FITS_SCALE   "SCALE"    // Column name for scaling option in ordinates table
     
    2225#define PM_DARK_FITS_MAX     "MAX"      // Column name for maximum value in ordinates table
    2326
    24 
    25 
    26 // Look up the value of an ordinate in a readout
    27 static bool ordinateLookup(float *value, // Value of ordinate, to return
    28                            bool *inRange, // is value within min : max range?
    29                            const char *name, // Name of ordinate (concept name)
    30                            bool scale,  // Scale the value?
    31                            float min, float max, // Minimum and maximum values for scaling
    32                            const pmReadout *ro // Readout of interest
    33                            )
    34 {
    35     assert(value);
    36     assert(name);
    37     assert(ro);
    38 
    39     *inRange = true;
    40 
    41     pmCell *cell = ro->parent; // Parent cell
    42     if (!cell) {
    43         return false;
    44     }
     27static bool ordinateParseConcept(double *value, const pmReadout *readout, const char *name) {
     28
     29    *value = NAN;
     30
     31    pmCell *cell = readout->parent; // Parent cell
     32    psAssert(cell, "readout is missing cell \n");
     33
    4534    psMetadataItem *item = psMetadataLookup(cell->concepts, name);
    4635    if (!item) {
    4736        pmChip *chip = cell->parent; // Parent chip
    48         if (!chip) {
    49             return false;
    50         }
     37        psAssert(chip, "cell is missing chip \n");
     38
    5139        item = psMetadataLookup(chip->concepts, name);
    5240        if (!item) {
    5341            pmFPA *fpa = chip->parent; // Parent FPA
    54             if (!fpa) {
    55                 return false;
    56             }
     42            psAssert(fpa, "chip is missing fpa \n");
     43
    5744            item = psMetadataLookup(fpa->concepts, name);
    5845            if (!item) {
    59                 psWarning("Unable to find concept %s in readout", name);
     46                psError(PM_ERR_CONFIG, true, "Unable to find concept %s in readout", name);
    6047                return false;
    6148            }
     
    6350    }
    6451
    65     *value = psMetadataItemParseF32(item); // Value of interest
     52    *value = psMetadataItemParseF64(item); // Value of interest
    6653    if (!isfinite(*value)) {
    6754        psWarning("Non-finite value (%f) of concept %s in readout", *value, name);
    68         return false;
    69     }
     55    }
     56    return true;
     57}
     58
     59static bool ordinateParseRule(double *value, const pmReadout *readout, const char *name, const char *rule) {
     60
     61    psAssert(name, "ordinate name is not defined");
     62    psAssert(rule, "ordinate rule is not defined");
     63
     64    *value = NAN;
     65
     66    psArray *words = psStringSplitArray(rule, " ", false);
     67   
     68    // we should have a rule of the form (concept) OP (concept) OP (concept) ...
     69    // for now, the only allowed OP is * (eventually, we can steal code from opihi for a better
     70    // RPN parser).
     71
     72    if (words->n % 2 == 0) {
     73        psError(PM_ERR_CONFIG, true, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     74        psFree(words);
     75        return false;
     76    }
     77
     78    for (int i = 1; i < words->n; i+=2) {
     79        if (strcmp((char *)words->data[i], "*")) {
     80            psError(PM_ERR_CONFIG, true, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     81            psFree(words);
     82            return false;
     83        }
     84    }
     85   
     86    if (!ordinateParseConcept(value, readout, words->data[0])) {
     87        psError(PM_ERR_CONFIG, false, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     88        psFree(words);
     89        return false;
     90    }
     91
     92    double value2 = 0.0;
     93    for (int i = 2; i < words->n; i+=2) {
     94        if (!ordinateParseConcept(&value2, readout, words->data[i])) {
     95            psError(PM_ERR_CONFIG, false, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     96            psFree(words);
     97            return false;
     98        }
     99        *value *= value2;
     100    }
     101    psFree(words);
     102    return true;
     103}
     104
     105// Look up the value of an ordinate in a readout
     106static bool ordinateLookup(double *value, // Value of ordinate, to return
     107                           bool *inRange, // is value within min : max range?
     108                           const char *name, // Name of ordinate (concept or abstract name)
     109                           const char *rule, // Rule for generating the value (if NULL use name as concept)
     110                           bool scale,  // Scale the value?
     111                           float min, float max, // Minimum and maximum values for scaling
     112                           const pmReadout *readout // Readout of interest
     113                           )
     114{
     115    assert(value);
     116    assert(name);
     117    assert(readout);
     118
     119    *inRange = true;
     120
     121    if (rule) {
     122        if (!ordinateParseRule(value, readout, name, rule)) {
     123            psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name);
     124            return false;
     125        }
     126    } else {
     127        if (!ordinateParseConcept(value, readout, name)) {
     128            psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name);
     129            return false;
     130        }
     131    }
     132
    70133    if (scale) {
    71134        if (*value < min || *value > max) {
     
    82145{
    83146    psFree(ord->name);
     147    psFree(ord->rule);
    84148    return;
    85149}
     
    91155
    92156    ord->name = psStringCopy(name);
     157    ord->rule = NULL;
    93158    ord->order = order;
    94159    ord->scale = false;
     
    118183
    119184        pmReadout *readout = inputs->data[i]; // Readout of interest
    120         float normValue;            // Normalisation value
    121         if (!ordinateLookup(&normValue, &inRange, normConcept, false, NAN, NAN, readout)) {
    122             psWarning("Unable to find value of %s for readout %d", normConcept, i);
     185        double normValue;            // Normalisation value
     186        if (!ordinateLookup(&normValue, &inRange, normConcept, NULL, false, NAN, NAN, readout)) {
     187            psError(PM_ERR_CONFIG, false, "problem finding concept %s for DARK.NORM", normConcept);
     188            return false;
     189        }
     190        if (!isfinite(normValue)) {
     191            psWarning("Unable to find acceptable value of %s for readout %d", normConcept, i);
    123192            roMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff;
    124193            norm->data.F32[i] = NAN;
     
    140209        pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information
    141210        if (ord->order <= 0) {
    142             psError(PS_ERR_UNKNOWN, true, "Bad order for concept %s (%d) --- ignored", ord->name, ord->order);
     211            psError(PS_ERR_UNKNOWN, true, "Bad order for DARK.ORDINATE %s (%d) --- ignored", ord->name, ord->order);
    143212            psFree(values);
    144213            psFree(roMask);
     
    157226
    158227            pmReadout *readout = inputs->data[j]; // Readout of interest
    159             float value = NAN;          // Value of ordinate
    160             if (!ordinateLookup(&value, &inRange, ord->name, ord->scale, ord->min, ord->max, readout)) {
     228            double value = NAN;          // Value of ordinate
     229            if (!ordinateLookup(&value, &inRange, ord->name, ord->rule, ord->scale, ord->min, ord->max, readout)) {
     230                psError(PM_ERR_CONFIG, false, "problem finding rule for DARK.ORDINATE %s", ord->name);
     231                return false;
     232            }
     233            if (!isfinite(value)) {
     234                psWarning("Unable to find acceptable value of DARK.ORDINATE %s for readout %d", ord->name, i);
    161235                roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    162236                val->data.F32[i] = NAN;
     
    165239            }
    166240            if (!inRange) {
     241                psWarning("Value of DARK.ORDINATE %s for readout %d is out of range", ord->name, i);
    167242                roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    168243                val->data.F32[i] = NAN;
     
    447522    for (int i = 0; i < numOrdinates; i++) {
    448523        pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest
    449         float value = NAN;              // Value for ordinate
    450         if (!ordinateLookup(&value, &inRange, ord->name, ord->scale, ord->min, ord->max, readout)) {
    451             psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", ord->name);
     524        double value = NAN;              // Value for ordinate
     525        if (!ordinateLookup(&value, &inRange, ord->name, ord->rule, ord->scale, ord->min, ord->max, readout)) {
     526            psError(PS_ERR_UNKNOWN, true, "Unable to find value for DARK.ORDINATE %s", ord->name);
    452527            psFree(values);
    453528            return false;
    454529        }
     530        if (!isfinite(value)) {
     531            psError(PS_ERR_UNKNOWN, true, "Value for DARK.ORDINATE %s is NAN", ord->name);
     532            psFree(values);
     533            return false;
     534        }
    455535        values->data.F32[i] = value;
    456536    }
    457     float norm = NAN;                   // Normalisation value
     537    double norm = NAN;                   // Normalisation value
    458538    bool doNorm = false;                // Do normalisation?
    459539    if (normConcept && strlen(normConcept) > 0) {
    460         if (!ordinateLookup(&norm, &inRange, normConcept, false, NAN, NAN, readout)) {
     540        if (!ordinateLookup(&norm, &inRange, normConcept, NULL, false, NAN, NAN, readout)) {
    461541            psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", normConcept);
    462542            psFree(values);
     
    470550        pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information
    471551        if (ord->order <= 0) {
    472             psError(PS_ERR_UNKNOWN, true, "Bad order for concept %s (%d) --- ignored", ord->name, ord->order);
     552            psError(PS_ERR_UNKNOWN, true, "Bad order for DARK.ORDINATE %s (%d) --- ignored", ord->name, ord->order);
    473553            psFree(values);
    474554            psFree(orders);
     
    701781            pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest
    702782            psMetadata *row = psMetadataAlloc(); // FITS table row
    703             psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "Concept name", ord->name);
     783            psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "DARK.ORDINATE name", ord->name);
     784
     785            // XXX write a dummy value if ord->rule == NULL? (eg, NONE)
     786            if (ord->rule) {
     787                psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_RULE, 0, "DARK.ORDINATE rule", ord->rule);
     788            } else {
     789                psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_RULE, 0, "DARK.ORDINATE rule", "NONE");
     790            }
     791
    704792            psMetadataAddS32(row, PS_LIST_TAIL, PM_DARK_FITS_ORDER, 0, "Polynomial order", ord->order);
    705793            psMetadataAddBool(row, PS_LIST_TAIL, PM_DARK_FITS_SCALE, 0, "Scale values?", ord->scale);
     
    878966              ord->max = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MAX);
    879967
     968              // load the ordinate rule; it is not an error if this field is missing or NULL
     969              // a NULL rule means 'use the name as the single concept'
     970              const char *rule = psMetadataLookupStr(&mdok, row, PM_DARK_FITS_RULE);
     971              if (!strcasecmp(rule, "NONE")) {
     972                  ord->rule = NULL;
     973              } else {
     974                  ord->rule = psStringCopy(rule);
     975              }
    880976              ordinates->data[i] = ord;
    881977          }
Note: See TracChangeset for help on using the changeset viewer.