Changeset 17227 for trunk/ppMerge/src/ppMergeScaleZero.c
- Timestamp:
- Mar 28, 2008, 5:08:31 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/ppMerge/src/ppMergeScaleZero.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppMerge/src/ppMergeScaleZero.c
r16842 r17227 10 10 11 11 #include "ppMerge.h" 12 #include "ppMergeScaleZero.h"13 12 14 13 // Get the scale and zero for each chip of each input 15 bool ppMergeScaleZero(psImage **scales, // The scales for each integration/cell 16 psImage **zeros, // The zeroes for each integration/cell 17 psArray **shutters, // The shutter correction data for each cell 18 ppMergeData *data,// The data 19 const ppMergeOptions *options, // The options 20 const pmConfig *config // The configuration 21 ) 14 bool ppMergeScaleZero(pmConfig *config) 22 15 { 23 assert(data);24 assert(options);25 16 assert(config); 26 17 27 if (!options->scale && !options->zero && !options->shutter) { 28 return true; // We did everything we were asked for 18 ppMergeType type = psMetadataLookupS32(NULL, config->arguments, "TYPE"); // Type of frame 19 int numInputs = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 20 int numCells = psMetadataLookupS32(NULL, config->arguments, "INPUTS.CELLS"); // Number of cells 21 psStatsOptions meanStat = psMetadataLookupS32(NULL, config->arguments, "MEAN"); // Statistic for mean 22 psStatsOptions stdevStat = psMetadataLookupS32(NULL, config->arguments, "STDEV"); // Statistic for stdev 23 psMaskType maskVal = psMetadataLookupU8(NULL, config->arguments, "MASKVAL"); // Value to mask 24 int shutterSize = psMetadataLookupS32(NULL, config->arguments, "SHUTTER.SIZE"); // Size of shutter region 25 26 psVector *gains = NULL; // Gains for each cell 27 psArray *shutters = NULL; // Shutter data for each cell 28 psStats *stats = NULL; // Statistics for background 29 psImage *background = NULL; // Background measurements per cell per file 30 31 switch (type) { 32 case PPMERGE_TYPE_BIAS: 33 case PPMERGE_TYPE_DARK: 34 // Nothing to measure 35 return true; 36 case PPMERGE_TYPE_FLAT: 37 case PPMERGE_TYPE_FRINGE: 38 gains = psVectorAlloc(numCells, PS_TYPE_F32); 39 background = psImageAlloc(numCells, numInputs, PS_TYPE_F32); 40 psImageInit(background, NAN); 41 stats = psStatsAlloc(meanStat); 42 break; 43 case PPMERGE_TYPE_SHUTTER: 44 shutters = psArrayAlloc(numCells); 45 break; 46 case PPMERGE_TYPE_MASK: 47 default: 48 break; 29 49 } 30 31 assert(config->camera); // Need the camera configuration 32 assert(config->arguments); // Need the list of files 33 34 psArray *filenames = psMetadataLookupPtr(NULL, config->arguments, "INPUT"); // The input file names 35 assert(filenames); // It should be here --- it's put here in ppMergeConfig 36 37 // Sanity checks 38 assert(!options->scale || scales); 39 assert(!scales || !*scales || ((*scales)->type.type == PS_TYPE_F32 && 40 (*scales)->numCols == data->numCells && 41 (*scales)->numRows == filenames->n)); 42 assert(!options->zero || zeros); 43 assert(!zeros || !*zeros || ((*zeros)->type.type == PS_TYPE_F32 && 44 (*zeros)->numCols == data->numCells && 45 (*zeros)->numRows == filenames->n)); 46 assert(!options->shutter || shutters); 47 assert(!shutters || !*shutters || (*shutters)->n == data->numCells); 48 49 // Allocate the outputs 50 if (options->scale) { 51 if (*scales) { 52 psFree(*scales); 53 } 54 *scales = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); 50 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator 51 pmFPAview *view = NULL; // View into FPA 52 53 for (int i = 0; i < numInputs; i++) { 54 pmFPAfileActivate(config->files, false, NULL); 55 psArray *files = ppMergeFileActivateSingle(config, PPMERGE_FILES_INPUT, true, i); // Activated files 56 pmFPAfile *input = files->data[0]; // Representative file; should be the image (not mask or weight) 57 pmFPA *fpa = input->fpa; // FPA of interest 58 view = pmFPAviewAlloc(0); // View to component of interest 59 int cellNum = 0; // Index for cell 60 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 61 goto ERROR; 62 } 63 pmChip *chip; // Chip of interest 64 while ((chip = pmFPAviewNextChip(view, fpa, 1))) { 65 if (!chip->file_exists) { 66 continue; 67 } 68 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 69 goto ERROR; 70 } 71 72 pmCell *cell; // Cell of interest 73 while ((cell = pmFPAviewNextCell(view, fpa, 1))) { 74 if (!cell->file_exists) { 75 continue; 76 } 77 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 78 goto ERROR; 79 } 80 81 if (!cell->data_exists) { 82 continue; 83 } 84 85 if (cell->readouts->n > 1) { 86 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 87 "File %d chip %d cell %d contains more than one readout (%ld)", 88 i, view->chip, view->cell, cell->readouts->n); 89 goto ERROR; 90 } 91 pmReadout *readout = cell->readouts->data[0]; // Readout of interest 92 93 switch (type) { 94 case PPMERGE_TYPE_FLAT: 95 case PPMERGE_TYPE_FRINGE: { 96 // Extract the gain 97 float gain = psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN"); // Cell gain 98 if (!isfinite(gain)) { 99 psError(PS_ERR_BAD_PARAMETER_VALUE, false, 100 "CELL.GAIN for file %d chip %d cell %d is not set.", 101 i, view->chip, view->cell); 102 goto ERROR; 103 } 104 gains->data.F32[cellNum] = gain; 105 106 // Measure the background 107 if (!psImageBackground(stats, NULL, readout->image, readout->mask, maskVal, rng)) { 108 psError(PS_ERR_UNKNOWN, false, 109 "Unable to get statistics for file %d chip %d cell %d", 110 i, view->chip, view->cell); 111 goto ERROR; 112 } 113 background->data.F32[i][cellNum] = psStatsGetValue(stats, meanStat); 114 break; 115 } 116 case PPMERGE_TYPE_SHUTTER: { 117 pmShutterCorrectionData *shutter = shutters->data[cellNum]; // Shutter correction data 118 if (!shutter) { 119 shutter = pmShutterCorrectionDataAlloc(readout->image->numCols, 120 readout->image->numRows, 121 shutterSize); 122 shutters->data[cellNum] = shutter; 123 } 124 if (!pmShutterCorrectionAddReadout(shutter, readout, meanStat, stdevStat, 125 maskVal, rng)) { 126 psError(PS_ERR_UNKNOWN, false, 127 "Can't add file %d chip %d cell %d to shutter correction.", 128 i, view->chip, view->cell); 129 goto ERROR; 130 } 131 break; 132 } 133 case PPMERGE_TYPE_MASK: 134 default: 135 psAbort("Should never get here."); 136 } 137 138 cellNum++; 139 140 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 141 goto ERROR; 142 } 143 } 144 145 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 146 goto ERROR; 147 } 148 } 149 150 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 151 goto ERROR; 152 } 153 154 psFree(view); 155 156 #if 0 157 // Reset files for reading again 158 for (int i = 0; i < files->n; i++) { 159 pmFPAfile *file = files->data[i]; // File of interest 160 } 161 #endif 162 psFree(files); 55 163 } 56 if (options->zero) { 57 if (*zeros) { 58 psFree(*zeros); 59 } 60 *zeros = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); 164 165 psFree(rng); rng = NULL; 166 psFree(stats); stats = NULL; 167 168 // Store results 169 switch (type) { 170 case PPMERGE_TYPE_FRINGE: 171 psMetadataAddImage(config->arguments, PS_LIST_TAIL, "ZEROS", 0, 172 "Zero to subtract from each input cell", background); 173 // Flow through 174 case PPMERGE_TYPE_FLAT: { 175 // Need to normalize over the focal plane 176 if (psTraceGetLevel("ppMerge") > 9) { 177 for (int i = 0; i < gains->n; i++) { 178 psTrace("ppMerge", 10, "Gain for cell %d is %f\n", i, gains->data.F32[i]); 179 } 180 } 181 psVector *fluxes = NULL; // Solution to fluxes 182 if (!pmFlatNormalize(&fluxes, &gains, background)) { 183 psError(PS_ERR_UNKNOWN, false, "Normalisation failed to converge --- continuing anyway."); 184 psFree(fluxes); 185 goto ERROR; 186 } 187 188 psMetadataAddVector(config->arguments, PS_LIST_TAIL, "SCALES", 0, 189 "Scale to divide into each input file", fluxes); 190 psFree(fluxes); // Drop reference 191 break; 192 } 193 case PPMERGE_TYPE_SHUTTER: 194 psMetadataAddArray(config->arguments, PS_LIST_TAIL, "SHUTTER", 0, 195 "Shutter data", shutters); 196 break; 197 case PPMERGE_TYPE_MASK: 198 default: 199 psAbort("Should never get here."); 61 200 } 62 psRandom *rng = NULL; // Random number generator 63 if (options->shutter) { 64 if (*shutters) { 65 psFree(*shutters); 66 } 67 *shutters = psArrayAlloc(data->numCells); 68 rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 69 } 70 71 bool fromConcepts = false; // Do we get the scale and zero points from the concepts? 72 bool first = true; // Are we on the first cell (that sets the standard for the rest)? 73 bool done = false; // Are we done going through the list? 74 bool mdok = true; // Status of MD lookup 75 for (long i = 0; i < data->in->n && !done; i++) { 76 pmFPA *fpa = data->in->data[i]; // The FPA 77 if (!fpa) { 78 continue; 79 } 80 long cellNum = -1; // Number of the cell 81 psArray *chips = fpa->chips; // The array of chips 82 for (long j = 0; j < chips->n && !done; j++) { 83 pmChip *chip = chips->data[j]; // The chip 84 if (!chip) { 85 continue; 86 } 87 psArray *cells = chip->cells; // The array of cells 88 for (long k = 0; k < cells->n && !done; k++) { 89 pmCell *cell = cells->data[k]; // The cell 90 if (!cell) { 91 continue; 92 } 93 cellNum++; 94 95 if (options->scale) { 96 float scale = psMetadataLookupF32(&mdok, cell->concepts, "PPMERGE.SCALE"); // The scale 97 if (mdok && !isnan(scale)) { 98 if (!first && !fromConcepts) { 99 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 100 "for some, but not all cells --- we will re-measure it for all cells."); 101 done = true; 102 continue; 103 } 104 fromConcepts = true; 105 (*scales)->data.F32[i][cellNum] = scale; 106 psTrace("ppMerge", 9, "Scale for input %ld, chip %ld, cell %ld: %f\n", 107 i, j, k, scale); 108 } else if (!first && fromConcepts) { 109 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 110 "for some, but not all cells --- we will re-measure it for all cells."); 111 fromConcepts = false; 112 done = true; 113 continue; 114 } 115 } 116 117 if (options->zero) { 118 float zero = psMetadataLookupF32(&mdok, cell->concepts, "PPMERGE.ZERO"); // The zero 119 if (mdok && !isnan(zero)) { 120 if (!first && !fromConcepts) { 121 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 122 "for some, but not all cells --- we will re-measure it for all cells."); 123 done = true; 124 continue; 125 } 126 fromConcepts = true; 127 (*zeros)->data.F32[i][cellNum] = zero; 128 psTrace("ppMerge", 9, "Zero for input %ld, chip %ld, cell %ld: %f\n", i, j, k, zero); 129 } else if (!first && fromConcepts) { 130 psWarning("PPMERGE.SCALE and PPMERGE.ZERO have been set " 131 "for some, but not all cells --- we will re-measure it for all cells."); 132 fromConcepts = false; 133 done = true; 134 continue; 135 } 136 } 137 138 first = false; 139 } 140 } 141 } 142 143 if (fromConcepts) { 144 // We've already done everything we need to 145 psFree(rng); 146 return true; 147 } 148 149 psImage *background = psImageAlloc(data->numCells, filenames->n, PS_TYPE_F32); // Background measurements 150 psImageInit(background, NAN); 151 psStats *bgStats = psStatsAlloc(options->mean); // Statistic to measure the background 152 psVector *gains = NULL; // The gains for each cell 153 if (options->scale) { 154 gains = psVectorAlloc(data->numCells, PS_TYPE_F32); 155 } 156 157 pmFPAview *view = pmFPAviewAlloc(0); 158 159 bool status = true; // Status of getting the scale and zero --- did everything go right? 160 for (int i = 0; i < filenames->n; i++) { 161 psString name = filenames->data[i]; // The name of the file 162 if (!name || strlen(name) == 0) { 163 continue; 164 } 165 psTrace("ppMerge", 9, "Opening %s to get background...\n", name); 166 psFits *inFile = data->files->data[i]; // The FITS file to read 167 pmFPA *fpa = data->in->data[i]; // The FPA for this input 168 int cellNum = -1; // Number of the cell 169 psArray *chips = fpa->chips; // Array of chips 170 for (int j = 0; j < chips->n; j++) { 171 pmChip *chip = chips->data[j]; // The chip of interest 172 if (!chip) { 173 continue; 174 } 175 psArray *cells = chip->cells; // Array of cells 176 for (int k = 0; k < cells->n; k++) { 177 pmCell *cell = cells->data[k]; // The cell of interest 178 if (!cell) { 179 continue; 180 } 181 cellNum++; 182 183 if (!pmCellReadHeader(cell, inFile)) { 184 continue; 185 } 186 187 // Scaling by the background 188 if (options->scale || options->zero) { 189 if (!pmCellRead(cell, inFile, config->database)) { 190 // Nothing here 191 pmCellFreeData(cell); 192 continue; 193 } 194 195 if (cell->readouts->n > 1) { 196 psWarning("File %s chip %d cell %d contains more than one " 197 "readout --- ignoring all but the first.\n", name, j, k); 198 status = false; 199 } 200 201 pmReadout *readout = cell->readouts->data[0]; // The readout of interest 202 psImage *image = readout->image; // The pixels of interest 203 if (!image) { 204 pmCellFreeData(cell); 205 continue; 206 } 207 208 // Get the gain 209 if (options->scale) { 210 bool mdok = true; // Status of MD lookup 211 gains->data.F32[cellNum] = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); 212 if (!mdok || isnan(gains->data.F32[cellNum])) { 213 psWarning("CELL.GAIN for file %s chip %d cell %d is not " 214 "set.\n", name, j, k); 215 gains->data.F32[cellNum] = NAN; 216 status = false; 217 } 218 } 219 220 // Get the background 221 int sampleSize = (image->numCols * image->numRows) / options->sample; // Size of sample 222 psVector *sample = psVectorAlloc(sampleSize, PS_TYPE_F32); // Sample of the image 223 psVector *sampleMask = NULL; // Mask for sample 224 if (readout->mask) { 225 sampleMask = psVectorAlloc(sampleSize, PS_TYPE_U8); 226 } 227 psImage *mask = readout->mask; // The mask image 228 for (long i = 0; i < sampleSize; i++) { 229 int j = i * options->sample; // Index into image 230 int x = j % image->numCols; // x index 231 int y = j / image->numCols; // y index 232 sample->data.F32[i] = image->data.F32[y][x]; 233 if (readout->mask) { 234 sampleMask->data.U8[i] = mask->data.U8[y][x]; 235 } 236 } 237 status = psVectorStats(bgStats, sample, sampleMask, NULL, options->combine->maskVal); 238 if (!status) { 239 psTrace("ppMerge", 3, "failed to get stats for for %s, cell %d is %f\n", name, cellNum, 240 background->data.F32[i][cellNum]); 241 psErrorClear(); 242 } 243 psFree(sample); 244 psFree(sampleMask); 245 background->data.F32[i][cellNum] = psStatsGetValue(bgStats, options->mean); 246 psTrace("ppMerge", 3, "Background for %s, cell %d is %f\n", name, cellNum, 247 background->data.F32[i][cellNum]); 248 } 249 250 // Shutter correction 251 if (options->shutter) { 252 if (!pmCellRead(cell, inFile, config->database)) { 253 // Nothing here 254 pmCellFreeData(cell); 255 continue; 256 } 257 258 if (cell->readouts->n > 1) { 259 psWarning("File %s chip %d cell %d contains more than one " 260 "readout --- ignoring all but the first.\n", name, j, k); 261 status = false; 262 } 263 pmReadout *readout = cell->readouts->data[0]; // The readout of interest 264 265 pmShutterCorrectionData *shutter = (*shutters)->data[cellNum]; // Shutter correction data 266 if (!shutter) { 267 shutter = pmShutterCorrectionDataAlloc(readout->image->numCols, 268 readout->image->numRows, 269 options->shutterSize); 270 (*shutters)->data[cellNum] = shutter; 271 } 272 if (!pmShutterCorrectionAddReadout(shutter, readout, options->mean, options->stdev, 273 options->combine->maskVal, rng)) { 274 psWarning("Can't add file %s chip %d cell %d to shutter correction --- ignored.", 275 name, j, k); 276 status = false; 277 } 278 } 279 280 281 pmCellFreeData(cell); 282 } 283 pmChipFreeData(chip); 284 } 285 pmFPAFreeData(fpa); 286 } 201 202 psFree(background); 203 psFree(shutters); 204 return true; 205 206 ERROR: 207 // Common path for errors 208 psFree(gains); 209 psFree(background); 210 psFree(shutters); 287 211 psFree(rng); 288 psFree( bgStats);212 psFree(stats); 289 213 psFree(view); 290 291 if (options->scale) { 292 // Need to normalize over the focal plane 293 if (psTraceGetLevel("ppMerge") > 9) { 294 for (int i = 0; i < gains->n; i++) { 295 psTrace("ppMerge", 10, "Gain for cell %d is %f\n", i, gains->data.F32[i]); 296 } 297 } 298 psVector *fluxes = NULL; // Solution to fluxes 299 if (!pmFlatNormalize(&fluxes, &gains, background)) { 300 psWarning("Normalisation failed to converge --- continuing anyway.\n"); 301 status = false; 302 } 303 psFree(gains); 304 305 psImage *scalesDeref = *scales; // Dereference the pointer 306 307 for (int i = 0; i < scalesDeref->numRows; i++) { 308 psF32 bg = fluxes->data.F32[i]; 309 for (int j = 0; j < scalesDeref->numCols; j++) { 310 scalesDeref->data.F32[i][j] = bg; 311 } 312 } 313 } 314 315 if (options->zero) { 316 if (!*zeros) { 317 // This is much faster than copying! 318 *zeros = psMemIncrRefCounter(background); 319 } else { 320 *zeros = psImageCopy(*zeros, background, PS_TYPE_F32); 321 } 322 } 323 324 // Diagnostic stuff 325 if (scales && *scales && psTraceGetLevel("ppMerge") > 9) { 326 psImage *scalesDeref = *scales; // Dereference the pointer 327 for (int i = 0; i < scalesDeref->numRows; i++) { 328 for (int j = 0; j < scalesDeref->numCols; j++) { 329 psTrace("ppMerge", 9, "Scale for exposure %d, cell %d is: %f\n", i, j, 330 scalesDeref->data.F32[i][j]); 331 } 332 } 333 } 334 if (zeros && *zeros && psTraceGetLevel("ppMerge") > 9) { 335 psImage *zerosDeref = *zeros; // Dereference the pointer 336 for (int i = 0; i < zerosDeref->numRows; i++) { 337 for (int j = 0; j < zerosDeref->numCols; j++) { 338 psTrace("ppMerge", 9, "Zero for exposure %d, cell %d is: %f\n", i, j, 339 zerosDeref->data.F32[i][j]); 340 } 341 } 342 } 343 344 psFree(background); 345 346 return status; 214 return false; 347 215 } 348 216
Note:
See TracChangeset
for help on using the changeset viewer.
