- Timestamp:
- Jul 30, 2009, 5:20:29 PM (17 years ago)
- Location:
- branches/czw_branch/cleanup
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psModules/src/detrend/pmDark.c (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/czw_branch/cleanup
- Property svn:mergeinfo changed
/trunk (added) merged: 24714-24742,24744-24784,24786-24798,24801-24824,24827-24834,24836-24859,24861-24901,24903-24912,24914-24939
- Property svn:mergeinfo changed
-
branches/czw_branch/cleanup/psModules/src/detrend/pmDark.c
r21183 r24951 1 #ifdef HAVE_CONFIG_H 2 #include <config.h> 3 #endif 4 1 5 #include <stdio.h> 2 6 #include <pslib.h> 3 7 #include <string.h> 8 #include <strings.h> 4 9 5 10 #include "psPolynomialMD.h" … … 12 17 #include "pmReadoutStack.h" 13 18 #include "pmDetrendThreads.h" 14 19 #include "pmErrorCodes.h" 15 20 #include "pmDark.h" 16 21 17 22 #define PM_DARK_FITS_EXTNAME "PS_DARK" // FITS extension name for ordinates table 18 23 #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 19 25 #define PM_DARK_FITS_ORDER "ORDER" // Column name for polynomial order in ordinates table 20 26 #define PM_DARK_FITS_SCALE "SCALE" // Column name for scaling option in ordinates table … … 22 28 #define PM_DARK_FITS_MAX "MAX" // Column name for maximum value in ordinates table 23 29 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 } 30 static 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 45 37 psMetadataItem *item = psMetadataLookup(cell->concepts, name); 46 38 if (!item) { 47 39 pmChip *chip = cell->parent; // Parent chip 48 if (!chip) { 49 return false; 50 } 40 psAssert(chip, "cell is missing chip \n"); 41 51 42 item = psMetadataLookup(chip->concepts, name); 52 43 if (!item) { 53 44 pmFPA *fpa = chip->parent; // Parent FPA 54 if (!fpa) { 55 return false; 56 } 45 psAssert(fpa, "chip is missing fpa \n"); 46 57 47 item = psMetadataLookup(fpa->concepts, name); 58 48 if (!item) { 59 ps Warning("Unable to find concept %s in readout", name);49 psError(PM_ERR_CONFIG, true, "Unable to find concept %s in readout", name); 60 50 return false; 61 51 } … … 63 53 } 64 54 65 *value = psMetadataItemParseF 32(item); // Value of interest55 *value = psMetadataItemParseF64(item); // Value of interest 66 56 if (!isfinite(*value)) { 67 57 psWarning("Non-finite value (%f) of concept %s in readout", *value, name); 68 return false; 69 } 58 } 59 return true; 60 } 61 62 static 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 109 static 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 70 136 if (scale) { 71 137 if (*value < min || *value > max) { … … 82 148 { 83 149 psFree(ord->name); 150 psFree(ord->rule); 84 151 return; 85 152 } … … 91 158 92 159 ord->name = psStringCopy(name); 160 ord->rule = NULL; 93 161 ord->order = order; 94 162 ord->scale = false; … … 118 186 119 187 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); 123 195 roMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff; 124 196 norm->data.F32[i] = NAN; … … 140 212 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information 141 213 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); 143 215 psFree(values); 144 216 psFree(roMask); … … 157 229 158 230 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); 161 238 roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff; 162 239 val->data.F32[i] = NAN; … … 165 242 } 166 243 if (!inRange) { 244 psWarning("Value of DARK.ORDINATE %s for readout %d is out of range", ord->name, i); 167 245 roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff; 168 246 val->data.F32[i] = NAN; … … 309 387 return false; 310 388 } 389 390 pmDarkVisualInit(values); 311 391 312 392 pmReadout *outReadout = output->readouts->data[0]; … … 352 432 psVectorInit(poly->coeff, NAN); 353 433 } 434 435 pmDarkVisualPixelFit(pixels, mask); 436 pmDarkVisualPixelModel(poly, values); 437 354 438 for (int k = 0; k < poly->coeff->n; k++) { 355 439 pmReadout *ro = output->readouts->data[k]; // Readout of interest … … 447 531 for (int i = 0; i < numOrdinates; i++) { 448 532 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest 449 floatvalue = NAN; // Value for ordinate450 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); 452 536 psFree(values); 453 537 return false; 454 538 } 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 } 455 544 values->data.F32[i] = value; 456 545 } 457 floatnorm = NAN; // Normalisation value546 double norm = NAN; // Normalisation value 458 547 bool doNorm = false; // Do normalisation? 459 548 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)) { 461 550 psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", normConcept); 462 551 psFree(values); … … 470 559 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information 471 560 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); 473 562 psFree(values); 474 563 psFree(orders); … … 701 790 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest 702 791 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 704 801 psMetadataAddS32(row, PS_LIST_TAIL, PM_DARK_FITS_ORDER, 0, "Polynomial order", ord->order); 705 802 psMetadataAddBool(row, PS_LIST_TAIL, PM_DARK_FITS_SCALE, 0, "Scale values?", ord->scale); … … 878 975 ord->max = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MAX); 879 976 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 } 880 985 ordinates->data[i] = ord; 881 986 } … … 892 997 } 893 998 999 #if (HAVE_KAPA) 1000 #include <kapa.h> 1001 #include "pmKapaPlots.h" 1002 #include "pmVisual.h" 1003 1004 static int nKapa = 0; 1005 static int *kapa = NULL; 1006 static bool plotFlag = true; 1007 static psArray *xVectors = NULL; 1008 1009 // this init function only gets the ordinates for the first readout... 1010 bool 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 1051 bool 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 1099 bool 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 1131 bool 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 1143 bool pmDarkVisualInit(psArray *values) { return true; } 1144 bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) { return true; } 1145 bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) { return true; } 1146 bool pmDarkVisualCleanup() { return true; } 1147 1148 # endif
Note:
See TracChangeset
for help on using the changeset viewer.
