IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 30, 2009, 5:20:29 PM (17 years ago)
Author:
watersc1
Message:

Finished up my edits to the detrend cleanup, and some changes to my
copy of burntool and the pslib astrometry. Detrend cleanup has not
been tested yet. That's up next.

Location:
branches/czw_branch/cleanup
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/cleanup

  • branches/czw_branch/cleanup/psModules/src/detrend/pmDark.c

    r21183 r24951  
     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.