Changeset 17227 for trunk/ppMerge/src/ppMergeMask.c
- Timestamp:
- Mar 28, 2008, 5:08:31 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/ppMerge/src/ppMergeMask.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppMerge/src/ppMergeMask.c
r15937 r17227 5 5 #include <stdio.h> 6 6 #include <string.h> 7 #include <unistd.h>8 7 #include <assert.h> 8 9 9 #include <pslib.h> 10 10 #include <psmodules.h> … … 12 12 13 13 #include "ppMerge.h" 14 #include "ppMergeData.h" 15 #include "ppMergeMask.h" 16 17 18 // Generate a mask 19 bool ppMergeMask(ppMergeData *data, // Data 20 ppMergeOptions *options, // Options 21 pmConfig *config // Configuration 22 ) 14 15 static bool mergeMask(pmConfig *config, // Configuration 16 const pmFPAview *view, // View to chip 17 bool writeOut, // Write output? 18 psRandom *rng, // Random number generator 19 psMetadata *stats // Statistics output 20 ) 23 21 { 24 for (int i = 0; i < 2; i++) { 25 if (!ppMergeMaskSuspect (data, options, config)) { 26 psError(PS_ERR_UNKNOWN, true, "failed on mask suspect.\n"); 27 return false; 28 } 29 30 if (!ppMergeMaskBad (data, options, config)) { 31 psError(PS_ERR_UNKNOWN, true, "failed on mask bad.\n"); 32 return false; 33 } 34 } 35 36 if (!ppMergeMaskAverageConcepts (data, options, config)) { 37 psError(PS_ERR_UNKNOWN, true, "failed on average concepts.\n"); 38 return false; 39 } 40 41 if (!ppMergeMaskGrow (data, options, config)) { 42 psError(PS_ERR_UNKNOWN, true, "failed on mask grow.\n"); 43 return false; 44 } 45 46 if (!ppMergeMaskWrite (data, options, config)) { 47 psError(PS_ERR_UNKNOWN, true, "failed on mask write.\n"); 48 return false; 49 } 22 assert(config); 23 assert(view); 24 assert(view->chip != -1 && view->cell == -1 && view->readout == -1); 25 26 bool mdok; // Status of MD lookup 27 int numFiles = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of input files 28 psStatsOptions meanStat = psMetadataLookupS32(NULL, config->arguments, "MEAN"); // Statistic for mean 29 psStatsOptions stdevStat = psMetadataLookupS32(NULL, config->arguments, "STDEV"); // Statistic for stdev 30 psMaskType maskVal = psMetadataLookupU8(NULL, config->arguments, "MASKVAL"); // Value to mask 31 int sample = psMetadataLookupS32(NULL, config->arguments, "SAMPLE"); // Size of sample for statistics 32 bool chipStats = psMetadataLookupBool(&mdok, config->arguments, "MASK.CHIPSTATS"); // Statistics on chip? 33 float maskSuspect = psMetadataLookupF32(NULL, config->arguments, "MASK.SUSPECT"); // Threshold for suspect pixels 34 float maskBad = psMetadataLookupF32(NULL, config->arguments, "MASK.BAD"); // Threshold for bad pixels 35 pmMaskIdentifyMode maskMode = psMetadataLookupS32(NULL, config->arguments, "MASK.MODE"); // Mode for identifying bad pixels 36 int maskGrow = psMetadataLookupS32(NULL, config->arguments, "MASK.GROW"); // Radius to grow mask 37 psMaskType maskGrowVal = psMetadataLookupU8(NULL, config->arguments, "MASK.GROWVAL"); // Value for grown mask 38 39 psStats *statistics = psStatsAlloc(meanStat | stdevStat); // Statistics for background 40 41 psString outName = ppMergeOutputFile(config); // Name of output file 42 pmChip *outChip = pmFPAfileThisChip(config->files, view, outName); // Output chip 43 psFree(outName); 44 45 // For each input file, get the statistics, which can be calculated at the chip or cell levels 46 psVector *values = psVectorAlloc(sample, PS_TYPE_F32); // Pixel values for statistics 47 pmFPAview *inView = pmFPAviewAlloc(0); // View for input 48 for (int i = 0; i < numFiles; i++) { 49 pmFPAfileActivate(config->files, false, NULL); 50 psArray *files = ppMergeFileActivateSingle(config, PPMERGE_FILES_INPUT, true, i); // Input files 51 pmFPAfile *input = files->data[0]; // Input file 52 psFree(files); 53 pmFPA *inFPA = input->fpa; // Input FPA 54 *inView = *view; 55 56 int valueIndex = 0; // Index for vector of pixel values 57 58 pmCell *inCell; // Input cell 59 while ((inCell = pmFPAviewNextCell(inView, inFPA, 1))) { 60 pmHDU *hdu = pmHDUFromCell(inCell); // HDU for cell 61 if (!hdu || hdu->blankPHU) { 62 // No data here 63 continue; 64 } 65 psTrace("ppMerge", 1, "Getting suspect pixels for file %d chip %d cell %d", 66 i, inView->chip, inView->cell); 67 68 if (!pmFPAfileIOChecks(config, inView, PM_FPA_BEFORE)) { 69 psFree(inView); 70 goto MERGE_MASK_ERROR; 71 } 72 73 if (!ppMergeFileOpenInput(config, view, i)) { 74 psError(PS_ERR_UNKNOWN, false, "Unable to open file %d", i); 75 psFree(inView); 76 goto MERGE_MASK_ERROR; 77 } 78 79 if (inCell->readouts->n > 1) { 80 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 81 "File %d chip %d cell %d contains more than one readout (%ld)", 82 i, inView->chip, inView->cell, inCell->readouts->n); 83 psFree(inView); 84 goto MERGE_MASK_ERROR; 85 } 86 87 pmReadout *readout; 88 if (inCell->readouts && inCell->readouts->n == 1) { 89 readout = psMemIncrRefCounter(inCell->readouts->data[0]); // Input readout 90 } else { 91 readout = pmReadoutAlloc(inCell); 92 } 93 94 if (!ppMergeFileReadInput(config, readout, i, 0)) { 95 psError(PS_ERR_UNKNOWN, false, "Unable to read readout %d", i); 96 psFree(inView); 97 psFree(readout); 98 goto MERGE_MASK_ERROR; 99 } 100 101 pmCell *outCell = pmFPAfileThisCell(config->files, inView, "PPMERGE.OUTPUT.MASK"); // Output cell 102 pmReadout *outRO = NULL; // Output readout 103 if (outCell->readouts && outCell->readouts->n == 1) { 104 outRO = psMemIncrRefCounter(outCell->readouts->data[0]); 105 } else { 106 outRO = pmReadoutAlloc(outCell); 107 } 108 psImage *outMask = outRO->mask; // Output mask image (for iterative generation of mask) 109 110 psImage *image = readout->image, *mask = readout->mask; // Image and mask 111 int numCols = readout->image->numCols, numRows = readout->image->numRows; // Image size 112 int numPix = numCols * numRows; // Number of pixels 113 int numCells = chipStats ? readout->parent->parent->cells->n : 1; // Number of cells 114 int num = PS_MIN(numPix, sample / numCells); // Number of values to add 115 if (!chipStats) { 116 valueIndex = 0; 117 } 118 for (int i = 0; i < num; i++) { 119 int pixel = numPix * psRandomUniform(rng); 120 int x = pixel % numCols; 121 int y = pixel / numCols; 122 if ((mask && (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal)) || 123 !isfinite(image->data.F32[y][x]) || 124 (outMask && (outMask->data.PS_TYPE_MASK_DATA[y][x] & maskVal))) { 125 continue; 126 } 127 128 values->data.F32[valueIndex++] = image->data.F32[y][x]; 129 } 130 131 if (!chipStats) { 132 values->n = valueIndex; 133 if (!psVectorStats(statistics, values, NULL, NULL, 0)) { 134 psError(PS_ERR_UNKNOWN, false, "Unable to do statistics on readout."); 135 psFree(inView); 136 psFree(readout); 137 goto MERGE_MASK_ERROR; 138 } 139 140 if (!pmMaskFlagSuspectPixels(outRO, readout, psStatsGetValue(statistics, meanStat), 141 psStatsGetValue(statistics, stdevStat), maskSuspect, maskVal)) { 142 psError(PS_ERR_UNKNOWN, false, "Unable to find suspect values in file %d", i); 143 psFree(inView); 144 psFree(readout); 145 goto MERGE_MASK_ERROR; 146 } 147 pmCellFreeData(inCell); 148 149 if (!pmFPAfileIOChecks(config, inView, PM_FPA_AFTER)) { 150 psFree(inView); 151 psFree(readout); 152 goto MERGE_MASK_ERROR; 153 } 154 } 155 psFree(readout); 156 psFree(outRO); 157 } 158 159 // Additional run through cells if we want chip-level statistics 160 if (chipStats && valueIndex > 0) { 161 values->n = valueIndex; 162 if (!psVectorStats(statistics, values, NULL, NULL, 0)) { 163 psError(PS_ERR_UNKNOWN, false, "Unable to do statistics on chip."); 164 goto MERGE_MASK_ERROR; 165 } 166 inView->cell = -1; 167 while ((inCell = pmFPAviewNextCell(inView, inFPA, 1))) { 168 pmHDU *hdu = pmHDUFromCell(inCell); // HDU for cell 169 if (!hdu || hdu->blankPHU) { 170 // No data here 171 continue; 172 } 173 pmReadout *readout = inCell->readouts->data[0]; // Readout of interest 174 175 inView->readout = 0; 176 pmReadout *outRO = pmFPAfileThisReadout(config->files, inView, "PPMERGE.OUTPUT.MASK"); 177 178 if (!pmMaskFlagSuspectPixels(outRO, readout, psStatsGetValue(statistics, meanStat), 179 psStatsGetValue(statistics, stdevStat), maskSuspect, maskVal)) { 180 psError(PS_ERR_UNKNOWN, false, "Unable to find suspect values in file %d", i); 181 goto MERGE_MASK_ERROR; 182 } 183 pmCellFreeData(inCell); 184 185 inView->readout = -1; 186 if (!pmFPAfileIOChecks(config, inView, PM_FPA_AFTER)) { 187 psFree(inView); 188 goto MERGE_MASK_ERROR; 189 } 190 } 191 } 192 } 193 psFree(inView); 194 psFree(statistics); statistics = NULL; 195 psFree(values); values = NULL; 196 197 198 // Another run through the chip to threshold on the suspects 199 pmFPAfileActivate(config->files, false, NULL); 200 if (writeOut) { 201 ppMergeFileActivate(config, PPMERGE_FILES_OUTPUT, true); 202 } 203 pmFPA *outFPA = outChip->parent; // Output FPA 204 pmCell *outCell; // Output cell 205 pmFPAview *outView = pmFPAviewAlloc(0); // View into output FPA 206 *outView = *view; 207 while ((outCell = pmFPAviewNextCell(outView, outFPA, 1))) { 208 pmHDU *hdu = pmHDUFromCell(outCell); // HDU for cell 209 if (!hdu || hdu->blankPHU) { 210 // No data here 211 continue; 212 } 213 214 psTrace("ppMerge", 1, "Getting bad pixels for chip %d cell %d", outView->chip, outView->cell); 215 216 assert(outCell->readouts && outCell->readouts->n == 1); 217 pmReadout *outRO = outCell->readouts->data[0]; // Output readout 218 if (!pmMaskIdentifyBadPixels(outRO, maskVal, maskBad, maskMode)) { 219 psError(PS_ERR_UNKNOWN, false, "Unable to mask bad pixels"); 220 goto MERGE_MASK_ERROR; 221 } 222 223 // Supplementary outputs 224 { 225 // The counts image is fairly useless, but it preserves the model 226 pmCell *countsCell = pmFPAfileThisCell(config->files, outView, "PPMERGE.OUTPUT.COUNT"); 227 pmReadout *countsRO = pmReadoutAlloc(countsCell); // Readout with count of inputs per pixel 228 countsRO->image = psImageAlloc(outRO->mask->numCols, outRO->mask->numRows, PS_TYPE_F32); 229 psImageInit(countsRO->image, numFiles); 230 countsRO->data_exists = countsCell->data_exists = countsCell->parent->data_exists = true; 231 psFree(countsRO); 232 233 pmCell *sigmaCell = pmFPAfileThisCell(config->files, outView, "PPMERGE.OUTPUT.SIGMA"); 234 pmReadout *sigmaRO = pmReadoutAlloc(sigmaCell); // Readout with suspect image 235 psImage *suspect = psMetadataLookupPtr(NULL, outRO->analysis, PM_MASK_ANALYSIS_SUSPECT); 236 sigmaRO->image = psImageCopy(sigmaRO->image, suspect, PS_TYPE_F32); 237 psMetadataRemoveKey(outRO->analysis, PM_MASK_ANALYSIS_SUSPECT); 238 sigmaRO->data_exists = sigmaCell->data_exists = sigmaCell->parent->data_exists = true; 239 psFree(sigmaRO); 240 } 241 242 if (maskGrowVal > 0) { 243 psImage *grown = psImageGrowMask(NULL, outRO->mask, maskVal, maskGrow, maskGrowVal); // Grown mask 244 psFree(outRO->mask); 245 outRO->mask = grown; 246 } 247 248 if (writeOut) { 249 if (!pmFPAfileIOChecks(config, outView, PM_FPA_BEFORE)) { 250 psFree(outView); 251 goto MERGE_MASK_ERROR; 252 } 253 254 outRO->data_exists = outCell->data_exists = outChip->data_exists = true; 255 256 // Average concepts 257 psList *cells = psListAlloc(NULL); // List of cells, for concept averaging 258 for (int i = 0; i < numFiles; i++) { 259 pmFPAfile *inFile = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); // Input file 260 pmCell *inCell = pmFPAviewThisCell(outView, inFile->fpa); // Input cell 261 psListAdd(cells, PS_LIST_TAIL, inCell); 262 } 263 if (!pmConceptsAverageCells(outCell, cells, NULL, NULL, true)) { 264 psError(PS_ERR_UNKNOWN, false, "Unable to average cell concepts."); 265 psFree(cells); 266 psFree(outRO); 267 psFree(outView); 268 return false; 269 } 270 psFree(cells); 271 272 // Statistics on the merged cell using a fake image 273 outRO->image = psImageAlloc(outRO->mask->numCols, outRO->mask->numRows, PS_TYPE_F32); 274 psImageInit(outRO->image, 1.0); 275 if (!ppStatsFPA(stats, outRO->parent->parent->parent, outView, 276 maskVal | pmConfigMask("BLANK", config), config)) { 277 psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to generate stats for image."); 278 psFree(outRO); 279 psFree(outView); 280 return false; 281 } 282 psFree(outRO->image); 283 outRO->image = NULL; 284 285 // Write 286 if (!pmFPAfileIOChecks(config, outView, PM_FPA_AFTER)) { 287 psFree(outView); 288 goto MERGE_MASK_ERROR; 289 } 290 } 291 } 292 psFree(outView); 293 294 ppMergeFileActivate(config, PPMERGE_FILES_ALL, true); 50 295 51 296 return true; 297 298 299 MERGE_MASK_ERROR: 300 psFree(statistics); 301 psFree(values); 302 return false; 52 303 } 53 304 54 bool ppMergeMaskReadoutStats(const pmReadout *readout, 55 const pmReadout *output, 56 ppMergeOptions *options, // Options 57 psRandom *rng) 305 306 307 308 309 bool ppMergeMask(pmConfig *config) 58 310 { 59 PS_ASSERT_PTR_NON_NULL(readout, false); 60 PS_ASSERT_IMAGE_NON_NULL(readout->image, false); 61 PS_ASSERT_IMAGE_NON_EMPTY(readout->image, false); 62 PS_ASSERT_IMAGE_TYPE(readout->image, PS_TYPE_F32, false); 63 if (readout->mask) { 64 PS_ASSERT_IMAGE_NON_EMPTY(readout->mask, false); 65 PS_ASSERT_IMAGES_SIZE_EQUAL(readout->image, readout->mask, false); 66 PS_ASSERT_IMAGE_TYPE(readout->mask, PS_TYPE_MASK, false); 67 } 68 69 psImage *mask = NULL; 70 psImage *image = readout->image; // Image of interest 71 72 if (output) { 73 mask = output->mask; // Corresponding mask 74 } 75 76 if (rng) { 77 psMemIncrRefCounter(rng); 78 } else { 79 rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 80 } 81 82 // XXX note that this now will accept any of several stats options 83 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 84 stats->nSubsample = options->sample; 85 86 if (!psImageBackground(stats, NULL, image, mask, options->combine->maskVal, rng)) { 87 psError(PS_ERR_UNKNOWN, false, "Failure to measure image statistics.\n"); 88 psFree(stats); 89 psFree(rng); 90 return false; 91 } 92 if (!isfinite(stats->robustMedian) || !isfinite(stats->robustUQ) || !isfinite(stats->robustLQ)) { 93 psError(PS_ERR_UNKNOWN, false, "invalide image statistics (nan).\n"); 94 psFree(stats); 95 psFree(rng); 96 return false; 97 } 98 99 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.MEDIAN", PS_META_REPLACE, "image stats", stats->robustMedian); 100 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.STDEV", PS_META_REPLACE, "image stats", stats->robustStdev); 101 311 assert(config); 312 313 bool mdok; // Status of MD lookup 314 int numFiles = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 315 bool haveMasks = psMetadataLookupBool(&mdok, config->arguments, "INPUTS.MASKS"); // Do we have masks? 316 bool haveWeights = psMetadataLookupBool(&mdok, config->arguments, "INPUTS.WEIGHTS"); // Do we have weights? 317 int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Number of rejection iterations 318 319 PS_ASSERT_INT_POSITIVE(iter, false); 320 321 pmFPAview *view = pmFPAviewAlloc(0); // View to component of interest 322 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator 323 324 psMetadata *stats = NULL; // Statistics for output 325 if (psMetadataLookup(config->arguments, "STATS.NAME")) { 326 stats = psMetadataAlloc(); 327 psMetadataAddMetadata(config->arguments, PS_LIST_TAIL, "STATS.DATA", 0, "Statistics output", stats); 328 } 329 330 psArray *inputs = ppMergeFileDataLevel(config, "PPMERGE.INPUT", PM_FPA_LEVEL_READOUT); // Input images 331 psFree(inputs); 332 if (haveMasks) { 333 psArray *masks = ppMergeFileDataLevel(config, "PPMERGE.INPUT.MASK", PM_FPA_LEVEL_READOUT); 334 psFree(masks); 335 } 336 if (haveWeights) { 337 psArray *weights = ppMergeFileDataLevel(config, "PPMERGE.INPUT.WEIGHT", PM_FPA_LEVEL_READOUT); 338 psFree(weights); 339 } 340 341 if (!ppMergeFileActivate(config, PPMERGE_FILES_INPUT, true)) { 342 psError(PS_ERR_UNKNOWN, false, "Unable to activate files."); 343 goto PPMERGE_MASK_ERROR; 344 } 345 if (!ppMergeFileActivate(config, PPMERGE_FILES_OUTPUT, true)) { 346 psError(PS_ERR_UNKNOWN, false, "Unable to activate files."); 347 goto PPMERGE_MASK_ERROR; 348 } 349 350 psString outName = ppMergeOutputFile(config); // Name of output file 351 pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, outName); // Output file 352 psFree(outName); 353 assert(output && output->fpa); 354 pmFPA *outFPA = output->fpa; // Output FPA 355 356 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 357 goto PPMERGE_MASK_ERROR; 358 } 359 pmChip *outChip; // Chip of interest 360 while ((outChip = pmFPAviewNextChip(view, outFPA, 1))) { 361 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 362 goto PPMERGE_MASK_ERROR; 363 } 364 365 for (int i = 0; i < iter; i++) { 366 if (!mergeMask(config, view, (i == iter - 1), rng, stats)) { 367 psError(PS_ERR_UNKNOWN, false, "Unable to merge chip %d", view->chip); 368 goto PPMERGE_MASK_ERROR; 369 } 370 } 371 372 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 373 goto PPMERGE_MASK_ERROR; 374 } 375 } 376 377 psList *fpaList = psListAlloc(NULL);// List of FPAs for concept averaging 378 for (int i = 0; i < numFiles; i++) { 379 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); // Input file 380 psListAdd(fpaList, PS_LIST_TAIL, file->fpa); 381 } 382 if (!pmConceptsAverageFPAs(outFPA, fpaList)) { 383 psError(PS_ERR_UNKNOWN, false, "Unable to average FPA concepts."); 384 psFree(fpaList); 385 goto PPMERGE_MASK_ERROR; 386 } 387 psFree(fpaList); 388 389 if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) { 390 goto PPMERGE_MASK_ERROR; 391 } 392 393 psFree(stats); 394 psFree(view); 102 395 psFree(rng); 396 103 397 return true; 398 399 PPMERGE_MASK_ERROR: 400 psFree(stats); 401 psFree(view); 402 psFree(rng); 403 return false; 104 404 } 105 405 106 bool ppMergeMaskChipStats (const pmChip *chip,107 const pmChip *output,108 ppMergeOptions *options,109 psRandom *rng)110 {111 PS_ASSERT_PTR_NON_NULL(chip, false);112 113 // XXX note that this now will accept any of several stats options114 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);115 116 if (rng) {117 psMemIncrRefCounter(rng);118 } else {119 rng = psRandomAlloc(PS_RANDOM_TAUS, 0);120 }121 122 // accumulate a vector of data values using options->sample per readout123 psVector *values = psVectorAllocEmpty(options->sample, PS_TYPE_F32); // Vector containing subsample124 125 for (int nCell = 0; nCell < chip->cells->n; nCell++) {126 pmCell *cell = chip->cells->data[nCell];127 if (cell->readouts->n == 0) continue;128 129 for (int nReadout = 0; nReadout < cell->readouts->n; nReadout++) {130 pmReadout *readout = cell->readouts->data[nReadout];131 if (!readout->image) continue;132 133 psTrace("ppMerge", 4, "Measure statistics for cell %d, readout %d\n", nCell, nReadout);134 135 psImage *image = readout->image; // Image of interest136 137 pmCell *cellOutput = output->cells->data[nCell];138 pmReadout *readoutOutput = NULL;139 psImage *mask = NULL;140 if (cellOutput->readouts->n > 0) {141 readoutOutput = cellOutput->readouts->data[0];142 mask = readoutOutput->mask; // Corresponding mask143 }144 145 // Size of image146 long nx = image->numCols;147 long ny = image->numRows;148 const int Npixels = nx*ny; // Total number of pixels149 const int Nsubset = PS_MIN(options->sample, Npixels); // Number of pixels in subset150 151 values = psVectorRealloc (values, values->n + Nsubset); // make sure we have enough space152 153 // select a subset of the image pixels to measure the stats154 for (long i = 0; i < Nsubset; i++) {155 double frnd = psRandomUniform(rng);156 int pixel = Npixels * frnd;157 int ix = pixel % nx;158 int iy = pixel / nx;159 160 if (!isfinite(image->data.F32[iy][ix])) continue;161 if (mask && (mask->data.U8[iy][ix] & options->combine->maskVal)) continue;162 163 float value = image->data.F32[iy][ix];164 values->data.F32[values->n] = value;165 values->n ++;166 }167 }168 }169 170 // no valid data, skip the chip171 if (!values->n) {172 psFree(values);173 psFree(stats);174 psFree(rng);175 return true;176 }177 178 // calculate the statistics179 if (!psVectorStats (stats, values, NULL, NULL, 0)) {180 psError(PS_ERR_UNKNOWN, false, "Unable to measure statistics for chip");181 psFree(values);182 psFree(stats);183 psFree(rng);184 return false;185 }186 if (!isfinite(stats->robustMedian) || !isfinite(stats->robustUQ) || !isfinite(stats->robustLQ)) {187 psError(PS_ERR_UNKNOWN, false, "invalid image statistics (nan).\n");188 psFree(values);189 psFree(stats);190 psFree(rng);191 return false;192 }193 194 // supply the stats to the readout analysis metadata195 for (int nCell = 0; nCell < chip->cells->n; nCell++) {196 pmCell *cell = chip->cells->data[nCell];197 if (cell->readouts->n == 0) continue;198 199 for (int nReadout = 0; nReadout < cell->readouts->n; nReadout++) {200 pmReadout *readout = cell->readouts->data[nReadout];201 if (!readout->image) continue;202 203 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.MEDIAN", PS_META_REPLACE, "image stats", stats->robustMedian);204 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "READOUT.STDEV", PS_META_REPLACE, "image stats", stats->robustStdev);205 }206 }207 208 psLogMsg ("ppMerge", PS_LOG_INFO, "statistics for chip: %f +/- %f\n", stats->robustMedian, stats->robustStdev);209 210 psFree(values);211 psFree(stats);212 psFree(rng);213 return true;214 }
Note:
See TracChangeset
for help on using the changeset viewer.
