IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 7, 2009, 12:45:24 PM (17 years ago)
Author:
eugene
Message:

update from mainline

Location:
branches/eam_branches/20090715
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715

  • branches/eam_branches/20090715/psModules/src/detrend/pmDark.c

    r21183 r25022  
     1#ifdef HAVE_CONFIG_H
     2#include <config.h>
     3#endif
     4
    15#include <stdio.h>
    26#include <pslib.h>
    37#include <string.h>
     8#include <strings.h>
    49
    510#include "psPolynomialMD.h"
     
    1217#include "pmReadoutStack.h"
    1318#include "pmDetrendThreads.h"
    14 
     19#include "pmErrorCodes.h"
    1520#include "pmDark.h"
    1621
    1722#define PM_DARK_FITS_EXTNAME "PS_DARK"  // FITS extension name for ordinates table
    1823#define PM_DARK_FITS_NAME    "NAME"     // Column name for concept name in ordinates table
     24#define PM_DARK_FITS_RULE    "RULE"     // Column name for concept rule in ordinates table
    1925#define PM_DARK_FITS_ORDER   "ORDER"    // Column name for polynomial order in ordinates table
    2026#define PM_DARK_FITS_SCALE   "SCALE"    // Column name for scaling option in ordinates table
     
    2228#define PM_DARK_FITS_MAX     "MAX"      // Column name for maximum value in ordinates table
    2329
    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     }
     30static bool ordinateParseConcept(double *value, const pmReadout *readout, const char *name) {
     31
     32    *value = NAN;
     33
     34    pmCell *cell = readout->parent; // Parent cell
     35    psAssert(cell, "readout is missing cell \n");
     36
    4537    psMetadataItem *item = psMetadataLookup(cell->concepts, name);
    4638    if (!item) {
    4739        pmChip *chip = cell->parent; // Parent chip
    48         if (!chip) {
    49             return false;
    50         }
     40        psAssert(chip, "cell is missing chip \n");
     41
    5142        item = psMetadataLookup(chip->concepts, name);
    5243        if (!item) {
    5344            pmFPA *fpa = chip->parent; // Parent FPA
    54             if (!fpa) {
    55                 return false;
    56             }
     45            psAssert(fpa, "chip is missing fpa \n");
     46
    5747            item = psMetadataLookup(fpa->concepts, name);
    5848            if (!item) {
    59                 psWarning("Unable to find concept %s in readout", name);
     49                psError(PM_ERR_CONFIG, true, "Unable to find concept %s in readout", name);
    6050                return false;
    6151            }
     
    6353    }
    6454
    65     *value = psMetadataItemParseF32(item); // Value of interest
     55    *value = psMetadataItemParseF64(item); // Value of interest
    6656    if (!isfinite(*value)) {
    6757        psWarning("Non-finite value (%f) of concept %s in readout", *value, name);
    68         return false;
    69     }
     58    }
     59    return true;
     60}
     61
     62static bool ordinateParseRule(double *value, const pmReadout *readout, const char *name, const char *rule) {
     63
     64    psAssert(name, "ordinate name is not defined");
     65    psAssert(rule, "ordinate rule is not defined");
     66
     67    *value = NAN;
     68
     69    psArray *words = psStringSplitArray(rule, " ", false);
     70   
     71    // we should have a rule of the form (concept) OP (concept) OP (concept) ...
     72    // for now, the only allowed OP is * (eventually, we can steal code from opihi for a better
     73    // RPN parser).
     74
     75    if (words->n % 2 == 0) {
     76        psError(PM_ERR_CONFIG, true, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     77        psFree(words);
     78        return false;
     79    }
     80
     81    for (int i = 1; i < words->n; i+=2) {
     82        if (strcmp((char *)words->data[i], "*")) {
     83            psError(PM_ERR_CONFIG, true, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     84            psFree(words);
     85            return false;
     86        }
     87    }
     88   
     89    if (!ordinateParseConcept(value, readout, words->data[0])) {
     90        psError(PM_ERR_CONFIG, false, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     91        psFree(words);
     92        return false;
     93    }
     94
     95    double value2 = 0.0;
     96    for (int i = 2; i < words->n; i+=2) {
     97        if (!ordinateParseConcept(&value2, readout, words->data[i])) {
     98            psError(PM_ERR_CONFIG, false, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule);
     99            psFree(words);
     100            return false;
     101        }
     102        *value *= value2;
     103    }
     104    psFree(words);
     105    return true;
     106}
     107
     108// Look up the value of an ordinate in a readout
     109static bool ordinateLookup(double *value, // Value of ordinate, to return
     110                           bool *inRange, // is value within min : max range?
     111                           const char *name, // Name of ordinate (concept or abstract name)
     112                           const char *rule, // Rule for generating the value (if NULL use name as concept)
     113                           bool scale,  // Scale the value?
     114                           float min, float max, // Minimum and maximum values for scaling
     115                           const pmReadout *readout // Readout of interest
     116                           )
     117{
     118    assert(value);
     119    assert(name);
     120    assert(readout);
     121
     122    *inRange = true;
     123
     124    if (rule) {
     125        if (!ordinateParseRule(value, readout, name, rule)) {
     126            psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name);
     127            return false;
     128        }
     129    } else {
     130        if (!ordinateParseConcept(value, readout, name)) {
     131            psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name);
     132            return false;
     133        }
     134    }
     135
    70136    if (scale) {
    71137        if (*value < min || *value > max) {
     
    82148{
    83149    psFree(ord->name);
     150    psFree(ord->rule);
    84151    return;
    85152}
     
    91158
    92159    ord->name = psStringCopy(name);
     160    ord->rule = NULL;
    93161    ord->order = order;
    94162    ord->scale = false;
     
    118186
    119187        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);
     188        double normValue;            // Normalisation value
     189        if (!ordinateLookup(&normValue, &inRange, normConcept, NULL, false, NAN, NAN, readout)) {
     190            psError(PM_ERR_CONFIG, false, "problem finding concept %s for DARK.NORM", normConcept);
     191            return false;
     192        }
     193        if (!isfinite(normValue)) {
     194            psWarning("Unable to find acceptable value of %s for readout %d", normConcept, i);
    123195            roMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff;
    124196            norm->data.F32[i] = NAN;
     
    140212        pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information
    141213        if (ord->order <= 0) {
    142             psError(PS_ERR_UNKNOWN, true, "Bad order for concept %s (%d) --- ignored", ord->name, ord->order);
     214            psError(PS_ERR_UNKNOWN, true, "Bad order for DARK.ORDINATE %s (%d) --- ignored", ord->name, ord->order);
    143215            psFree(values);
    144216            psFree(roMask);
     
    157229
    158230            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)) {
     231            double value = NAN;          // Value of ordinate
     232            if (!ordinateLookup(&value, &inRange, ord->name, ord->rule, ord->scale, ord->min, ord->max, readout)) {
     233                psError(PM_ERR_CONFIG, false, "problem finding rule for DARK.ORDINATE %s", ord->name);
     234                return false;
     235            }
     236            if (!isfinite(value)) {
     237                psWarning("Unable to find acceptable value of DARK.ORDINATE %s for readout %d", ord->name, i);
    161238                roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    162239                val->data.F32[i] = NAN;
     
    165242            }
    166243            if (!inRange) {
     244                psWarning("Value of DARK.ORDINATE %s for readout %d is out of range", ord->name, i);
    167245                roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff;
    168246                val->data.F32[i] = NAN;
     
    309387        return false;
    310388    }
     389
     390    pmDarkVisualInit(values);
    311391
    312392    pmReadout *outReadout = output->readouts->data[0];
     
    352432                psVectorInit(poly->coeff, NAN);
    353433            }
     434
     435            pmDarkVisualPixelFit(pixels, mask);
     436            pmDarkVisualPixelModel(poly, values);
     437
    354438            for (int k = 0; k < poly->coeff->n; k++) {
    355439                pmReadout *ro = output->readouts->data[k]; // Readout of interest
     
    447531    for (int i = 0; i < numOrdinates; i++) {
    448532        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);
     533        double value = NAN;              // Value for ordinate
     534        if (!ordinateLookup(&value, &inRange, ord->name, ord->rule, ord->scale, ord->min, ord->max, readout)) {
     535            psError(PS_ERR_UNKNOWN, true, "Unable to find value for DARK.ORDINATE %s", ord->name);
    452536            psFree(values);
    453537            return false;
    454538        }
     539        if (!isfinite(value)) {
     540            psError(PS_ERR_UNKNOWN, true, "Value for DARK.ORDINATE %s is NAN", ord->name);
     541            psFree(values);
     542            return false;
     543        }
    455544        values->data.F32[i] = value;
    456545    }
    457     float norm = NAN;                   // Normalisation value
     546    double norm = NAN;                   // Normalisation value
    458547    bool doNorm = false;                // Do normalisation?
    459548    if (normConcept && strlen(normConcept) > 0) {
    460         if (!ordinateLookup(&norm, &inRange, normConcept, false, NAN, NAN, readout)) {
     549        if (!ordinateLookup(&norm, &inRange, normConcept, NULL, false, NAN, NAN, readout)) {
    461550            psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", normConcept);
    462551            psFree(values);
     
    470559        pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information
    471560        if (ord->order <= 0) {
    472             psError(PS_ERR_UNKNOWN, true, "Bad order for concept %s (%d) --- ignored", ord->name, ord->order);
     561            psError(PS_ERR_UNKNOWN, true, "Bad order for DARK.ORDINATE %s (%d) --- ignored", ord->name, ord->order);
    473562            psFree(values);
    474563            psFree(orders);
     
    701790            pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest
    702791            psMetadata *row = psMetadataAlloc(); // FITS table row
    703             psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "Concept name", ord->name);
     792            psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "DARK.ORDINATE name", ord->name);
     793
     794            // XXX write a dummy value if ord->rule == NULL? (eg, NONE)
     795            if (ord->rule) {
     796                psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_RULE, 0, "DARK.ORDINATE rule", ord->rule);
     797            } else {
     798                psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_RULE, 0, "DARK.ORDINATE rule", "NONE");
     799            }
     800
    704801            psMetadataAddS32(row, PS_LIST_TAIL, PM_DARK_FITS_ORDER, 0, "Polynomial order", ord->order);
    705802            psMetadataAddBool(row, PS_LIST_TAIL, PM_DARK_FITS_SCALE, 0, "Scale values?", ord->scale);
     
    878975              ord->max = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MAX);
    879976
     977              // load the ordinate rule; it is not an error if this field is missing or NULL
     978              // a NULL rule means 'use the name as the single concept'
     979              const char *rule = psMetadataLookupStr(&mdok, row, PM_DARK_FITS_RULE);
     980              if (!rule || !strcasecmp(rule, "NONE")) {
     981                  ord->rule = NULL;
     982              } else {
     983                  ord->rule = psStringCopy(rule);
     984              }
    880985              ordinates->data[i] = ord;
    881986          }
     
    892997}
    893998
     999#if (HAVE_KAPA)
     1000#include <kapa.h>
     1001#include "pmKapaPlots.h"
     1002#include "pmVisual.h"
     1003
     1004static int nKapa = 0;
     1005static int *kapa = NULL;
     1006static bool plotFlag = true;
     1007static psArray *xVectors = NULL;
     1008
     1009// this init function only gets the ordinates for the first readout...
     1010bool pmDarkVisualInit(psArray *values) {
     1011   
     1012    if (!pmVisualIsVisual()) return true;
     1013
     1014    // skip if we have already opened the windows (or if none are requested...)
     1015    if (nKapa) return true;
     1016
     1017    // values has Ninput vectors with Norder elements; we need Norder vectors with Ninput elements...
     1018    int nOrders = 0;
     1019    for (int i = 0; i < values->n; i++) {
     1020        psVector *vect = values->data[i];
     1021        if (!nOrders) {
     1022            nOrders = vect->n;
     1023        } else {
     1024            psAssert (nOrders == vect->n, "mismatch in order vector lengths");
     1025        }
     1026    }
     1027    xVectors = psArrayAlloc(nOrders);
     1028    for (int i = 0; i < nOrders; i++) {
     1029        xVectors->data[i] = psVectorAlloc(values->n, PS_TYPE_F32);
     1030    }
     1031
     1032    for (int i = 0; i < values->n; i++) {
     1033        psVector *vect = values->data[i];
     1034        for (int j = 0; j < vect->n; j++) {
     1035            psVector *xVec = xVectors->data[j];
     1036            xVec->data.F32[i] = vect->data.F32[j];
     1037        }
     1038    }
     1039
     1040    nKapa = nOrders;
     1041
     1042    kapa = psAlloc(nKapa*sizeof(int));
     1043   
     1044    for (int i = 0; i < nKapa; i++) {
     1045        kapa[i] = -1;
     1046        pmVisualInitWindow(&kapa[i], "ppmerge");
     1047    }
     1048    return true;
     1049}
     1050
     1051bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) {
     1052
     1053    Graphdata graphdata;
     1054
     1055    if (!pmVisualIsVisual()) return true;
     1056
     1057    KapaInitGraph(&graphdata);
     1058
     1059    psAssert(nKapa == xVectors->n, "inconsistent number of orders %d vs %ld\n", nKapa, xVectors->n);
     1060
     1061    psVector *xSub = psVectorAlloc(pixels->n, PS_TYPE_F32);
     1062    psVector *ySub = psVectorAlloc(pixels->n, PS_TYPE_F32);
     1063
     1064    for (int i = 0; i < xVectors->n; i++) {
     1065        psVector *x = xVectors->data[i];
     1066
     1067        // generate vectors of the unmasked values
     1068        int nSub = 0;
     1069        for (int j = 0; j < pixels->n; j++) {
     1070            if (mask && mask->data.PS_TYPE_VECTOR_MASK_DATA[j]) continue;
     1071            xSub->data.F32[nSub] = x->data.F32[j];
     1072            ySub->data.F32[nSub] = pixels->data.F32[j];
     1073            nSub ++;
     1074        }
     1075        xSub->n = ySub->n = nSub;
     1076       
     1077        // plot the unmasked values
     1078        pmVisualScaleGraphdata (&graphdata, xSub, ySub, false);
     1079        KapaSetGraphData(kapa[i], &graphdata);
     1080        KapaSetLimits(kapa[i], &graphdata);
     1081        KapaClearPlots (kapa[i]);
     1082
     1083        KapaSetFont (kapa[i], "courier", 14);
     1084        KapaBox (kapa[i], &graphdata);
     1085        KapaSendLabel (kapa[i], "ordinate", KAPA_LABEL_XM);
     1086        KapaSendLabel (kapa[i], "pixel values", KAPA_LABEL_YM);
     1087
     1088        graphdata.color = KapaColorByName("black");
     1089        graphdata.style = 2;
     1090        graphdata.ptype = 2;
     1091        KapaPrepPlot  (kapa[i], xSub->n, &graphdata);
     1092        KapaPlotVector(kapa[i], xSub->n, xSub->data.F32, "x");
     1093        KapaPlotVector(kapa[i], xSub->n, ySub->data.F32, "y");
     1094    }
     1095    pmVisualAskUser (&plotFlag);
     1096    return true;
     1097}
     1098
     1099bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) {
     1100
     1101    Graphdata graphdata;
     1102
     1103    if (!pmVisualIsVisual()) return true;
     1104
     1105    KapaInitGraph(&graphdata);
     1106
     1107    psAssert(nKapa == xVectors->n, "inconsistent number of orders %d vs %ld\n", nKapa, xVectors->n);
     1108
     1109    psVector *yFit = psVectorAlloc(values->n, PS_TYPE_F32);
     1110
     1111    for (int i = 0; i < values->n; i++) {
     1112        psVector *coord = values->data[i];
     1113        yFit->data.F32[i] = psPolynomialMDEval (poly, coord);
     1114    }
     1115
     1116    for (int i = 0; i < xVectors->n; i++) {
     1117        psVector *xFit = xVectors->data[i];
     1118
     1119        KapaGetGraphData(kapa[i], &graphdata);
     1120        graphdata.color = KapaColorByName("red");
     1121        graphdata.style = 2;
     1122        graphdata.ptype = 7;
     1123        KapaPrepPlot  (kapa[i], xFit->n, &graphdata);
     1124        KapaPlotVector(kapa[i], xFit->n, xFit->data.F32, "x");
     1125        KapaPlotVector(kapa[i], xFit->n, yFit->data.F32, "y");
     1126    }
     1127    pmVisualAskUser (&plotFlag);
     1128    return true;
     1129}
     1130
     1131bool pmDarkVisualCleanup() {
     1132
     1133    for (int i = 0; i < nKapa; i++) {
     1134        KapaClose(kapa[i]);
     1135    }
     1136    psFree (kapa);
     1137    psFree (xVectors);
     1138    return true;
     1139}
     1140
     1141# else
     1142
     1143bool pmDarkVisualInit(psArray *values) { return true; }
     1144bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) { return true; }
     1145bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) { return true; }
     1146bool pmDarkVisualCleanup() { return true; }
     1147
     1148# endif
Note: See TracChangeset for help on using the changeset viewer.