Changeset 42679 for branches/2dbias/ppImage/src/ppImageDetrendPattern.c
- Timestamp:
- May 21, 2024, 8:50:38 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2dbias/ppImage/src/ppImageDetrendPattern.c
r42382 r42679 5 5 #include "ppImage.h" 6 6 7 #define ESCAPE(STATUS,...) { \ 8 psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__); \ 9 psFree(view); \ 10 return false; \ 11 } 12 13 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue); 7 #define ESCAPE(STATUS, ...) \ 8 { \ 9 psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__); \ 10 psFree(view); \ 11 return false; \ 12 } 13 14 bool ppImageDoPatternForView(bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue); 14 15 15 16 bool ppImageDetrendPatternRowApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options); … … 26 27 assert(inputView->readout == -1); 27 28 28 if (!ppImageDetrendPatternRowApply (config, chip, inputView, options)) { 29 return false; 30 } 31 if (!ppImageDetrendPatternContinuityApply (config, chip, inputView, options)) { 32 return false; 33 } 34 if (!ppImageDetrendPatternCellApply (config, chip, inputView, options)) { 35 return false; 36 } 37 if (!ppImageDetrendPatternDeadCellsApply (config, chip, inputView, options)) { 38 return false; 39 } 40 return(true); 29 if (!ppImageDetrendPatternRowApply(config, chip, inputView, options)) 30 { 31 return false; 32 } 33 if (!ppImageDetrendPatternContinuityApply(config, chip, inputView, options)) 34 { 35 return false; 36 } 37 if (!ppImageDetrendPatternCellApply(config, chip, inputView, options)) 38 { 39 return false; 40 } 41 if (!ppImageDetrendPatternDeadCellsApply(config, chip, inputView, options)) 42 { 43 return false; 44 } 45 return (true); 41 46 } 42 47 … … 45 50 bool status; 46 51 47 if (!options->doPatternRow) return true; 48 52 if (!options->doPatternRow) 53 return true; 54 49 55 assert(inputView->chip != -1); 50 56 assert(inputView->cell == -1); … … 73 79 74 80 pmHDU *hdu = pmHDUFromChip(chip); 75 if (psMetadataLookupBool(&status, hdu->header, "PTRN_ROW")) { 76 psLogMsg("ppImage", PS_LOG_INFO, "Not performing row pattern correction as it has already been done."); 77 return true; 81 if (psMetadataLookupBool(&status, hdu->header, "PTRN_ROW")) 82 { 83 psLogMsg("ppImage", PS_LOG_INFO, "Not performing row pattern correction as it has already been done."); 84 return true; 78 85 } 79 86 … … 85 92 86 93 // grab the PATTERN.ROW.AMP file 87 pmFPAfile *PRAfile = psMetadataLookupPtr (&status, config->files, "PPIMAGE.PATTERN.ROW.AMP"); 88 if (!PRAfile) { 89 psLogMsg("ppImage", PS_LOG_INFO, "Pattern Row Amplitude file not found, applying to all (with limits from ROW.SUBSET) "); 90 } 91 94 pmFPAfile *PRAfile = psMetadataLookupPtr(&status, config->files, "PPIMAGE.PATTERN.ROW.AMP"); 95 if (!PRAfile) 96 { 97 psLogMsg("ppImage", PS_LOG_INFO, "Pattern Row Amplitude file not found, applying to all (with limits from ROW.SUBSET) "); 98 } 99 92 100 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 93 101 *view = *inputView; 94 102 95 103 pmCell *cell = NULL; 96 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) { 97 // const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 98 // const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); 99 // psWarning ("Looping through %s, %s\n", chipName, cellName); 100 101 if (!cell->process || !cell->file_exists) { 102 continue; 103 } 104 105 // this forces pmFPAfileRead of the PATTERN.ROW.AMP file (XXX but is this needed?) 106 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 107 ESCAPE(false, "load failure for Cell"); 108 } 109 110 if (!cell->data_exists) { 111 continue; 112 } 113 114 if (cell->readouts->n > 1) { 115 psWarning ("Skipping Video Cell for ppImageDetrendPatternApply"); 116 continue; 117 } 118 119 // grab the corresponding cell 120 if (PRAfile) { 121 pmCell *PRAcell = pmFPAviewThisCell (view, PRAfile->fpa); 122 psAssert (PRAcell, "found Pattern Row Amplitude file, but not cell?"); 123 124 // find the nominal signal amplitude (check the ghost and/or crosstalk recipe file) 125 float amplitude = psMetadataLookupF32 (&status, PRAcell->analysis, "PTN.ROW.AMP"); 126 if (!status) amplitude = NAN; 127 128 // put the value on the science cell 129 psMetadataAddF32 (cell->analysis, PS_LIST_TAIL, "PTN.ROW.AMP", PS_META_REPLACE, "", amplitude); 130 } 131 132 bool doPattern = false; 133 if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) { 134 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 135 } 136 if (!doPattern) continue; 137 138 // switch to test threaded version 139 if (true) { 140 // I need to allocate a view here to be freed by the 141 // called function below. 142 pmFPAview *myView = pmFPAviewAlloc(0); // View for local processing 143 *myView = *view; 144 145 // allocate a job, construct the arguments for this job 146 psThreadJob *job = psThreadJobAlloc("PPIMAGE_PATTERN_ROW_CELL"); 147 psArrayAdd(job->args, 1, config); 148 psArrayAdd(job->args, 1, input->fpa); 149 psArrayAdd(job->args, 1, chip); 150 psArrayAdd(job->args, 1, cell); 151 psArrayAdd(job->args, 1, myView); 152 psArrayAdd(job->args, 1, options); 153 if (!psThreadJobAddPending(job)) { 154 return false; 155 } 156 } else { 157 // bump the counter since it must be freed by the function below. 158 psMemIncrRefCounter (view); // View for local processing 159 if (!ppImageDetrendPatternApplyCell (config, input->fpa, chip, cell, view, options)) { 160 return false; 161 } 162 } 104 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) 105 { 106 // const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 107 // const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); 108 // psWarning ("Looping through %s, %s\n", chipName, cellName); 109 110 if (!cell->process || !cell->file_exists) 111 { 112 continue; 113 } 114 115 // this forces pmFPAfileRead of the PATTERN.ROW.AMP file (XXX but is this needed?) 116 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) 117 { 118 ESCAPE(false, "load failure for Cell"); 119 } 120 121 if (!cell->data_exists) 122 { 123 continue; 124 } 125 126 if (cell->readouts->n > 1) 127 { 128 psWarning("Skipping Video Cell for ppImageDetrendPatternApply"); 129 continue; 130 } 131 132 // grab the corresponding cell 133 if (PRAfile) 134 { 135 pmCell *PRAcell = pmFPAviewThisCell(view, PRAfile->fpa); 136 psAssert(PRAcell, "found Pattern Row Amplitude file, but not cell?"); 137 138 // find the nominal signal amplitude (check the ghost and/or crosstalk recipe file) 139 float amplitude = psMetadataLookupF32(&status, PRAcell->analysis, "PTN.ROW.AMP"); 140 if (!status) 141 amplitude = NAN; 142 143 // put the value on the science cell 144 psMetadataAddF32(cell->analysis, PS_LIST_TAIL, "PTN.ROW.AMP", PS_META_REPLACE, "", amplitude); 145 } 146 147 bool doPattern = false; 148 if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) 149 { 150 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 151 } 152 if (!doPattern) 153 continue; 154 155 // switch to test threaded version 156 if (true) 157 { 158 // I need to allocate a view here to be freed by the 159 // called function below. 160 pmFPAview *myView = pmFPAviewAlloc(0); // View for local processing 161 *myView = *view; 162 163 // allocate a job, construct the arguments for this job 164 psThreadJob *job = psThreadJobAlloc("PPIMAGE_PATTERN_ROW_CELL"); 165 psArrayAdd(job->args, 1, config); 166 psArrayAdd(job->args, 1, input->fpa); 167 psArrayAdd(job->args, 1, chip); 168 psArrayAdd(job->args, 1, cell); 169 psArrayAdd(job->args, 1, myView); 170 psArrayAdd(job->args, 1, options); 171 if (!psThreadJobAddPending(job)) 172 { 173 return false; 174 } 175 } 176 else 177 { 178 // bump the counter since it must be freed by the function below. 179 psMemIncrRefCounter(view); // View for local processing 180 if (!ppImageDetrendPatternApplyCell(config, input->fpa, chip, cell, view, options)) 181 { 182 return false; 183 } 184 } 163 185 } 164 186 165 187 // wait here for the threaded jobs to finish 166 // if no threads are allocated, this 167 if (!psThreadPoolWait(true, true)) { 168 psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction."); 169 return false; 170 } 171 172 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_ROW",PS_META_REPLACE,"PATTERN.ROW correction applied",true); 188 // if no threads are allocated, this 189 if (!psThreadPoolWait(true, true)) 190 { 191 psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction."); 192 return false; 193 } 194 195 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_ROW", PS_META_REPLACE, "PATTERN.ROW correction applied", true); 173 196 psFree(view); 174 197 175 198 return true; 176 199 } … … 180 203 bool status; 181 204 182 if (!options->doPatternContinuity) return true; 205 if (!options->doPatternContinuity) 206 return true; 183 207 184 208 assert(inputView->chip != -1); … … 188 212 // see the comment for PATTERN.ROW; the same rules apply for PATTERN.CELL 189 213 190 int numCells = chip->cells->n; // Number of cells214 int numCells = chip->cells->n; // Number of cells 191 215 psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell? 192 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing216 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 193 217 *view = *inputView; 194 218 195 219 pmHDU *hdu = pmHDUFromChip(chip); 196 if (psMetadataLookupBool(&status, hdu->header, "PTRN_CON")) { 197 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction as it has already been done."); 198 return true; 220 if (psMetadataLookupBool(&status, hdu->header, "PTRN_CON")) 221 { 222 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction as it has already been done."); 223 return true; 199 224 } 200 225 … … 202 227 psLogMsg("ppImage", PS_LOG_INFO, "Performing pattern continuity correction for %s\n", chipName); 203 228 204 for (int i = 0; i < chip->cells->n; i++) { 205 view->cell = i; 206 207 pmCell *cell = chip->cells->data[i]; // Cell of interest 208 209 if (cell->readouts->n > 1) { 210 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction on video cell."); 211 continue; 212 } 213 214 bool doPattern = false; 215 if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET")) { 216 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 217 } 218 219 if (doPattern) { 220 tweak->data.U8[i] = 0xFF; 221 } 229 for (int i = 0; i < chip->cells->n; i++) 230 { 231 view->cell = i; 232 233 pmCell *cell = chip->cells->data[i]; // Cell of interest 234 235 if (cell->readouts->n > 1) 236 { 237 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction on video cell."); 238 continue; 239 } 240 241 bool doPattern = false; 242 if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET")) 243 { 244 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 245 } 246 247 if (doPattern) 248 { 249 tweak->data.U8[i] = 0xFF; 250 } 222 251 } 223 252 224 253 // Tweak the cells 225 254 if (!pmPatternContinuity(chip, tweak, options->patternCellBG, options->patternCellMean, 226 options->maskValue, options->darkMask,options->patternContinuityEdgeWidth)) { 227 psFree(tweak); 228 psFree(view); 229 return false; 255 options->maskValue, options->darkMask, options->patternContinuityEdgeWidth)) 256 { 257 psFree(tweak); 258 psFree(view); 259 return false; 230 260 } 231 261 psFree(tweak); 232 262 psFree(view); 233 263 234 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CON", PS_META_REPLACE,"PATTERN.CONTINUITY correction applied",true);264 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CON", PS_META_REPLACE, "PATTERN.CONTINUITY correction applied", true); 235 265 return true; 236 266 } … … 240 270 bool status; 241 271 242 if (!options->doPatternCell) return true; 272 if (!options->doPatternCell) 273 return true; 243 274 244 275 assert(inputView->chip != -1); … … 246 277 assert(inputView->readout == -1); 247 278 248 int numCells = chip->cells->n; // Number of cells279 int numCells = chip->cells->n; // Number of cells 249 280 psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell? 250 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing281 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 251 282 *view = *inputView; 252 283 253 284 pmHDU *hdu = pmHDUFromChip(chip); 254 if (psMetadataLookupBool(&status, hdu->header, "PTRN_CEL")) { 255 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction as it has already been done."); 256 return true; 285 if (psMetadataLookupBool(&status, hdu->header, "PTRN_CEL")) 286 { 287 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction as it has already been done."); 288 return true; 257 289 } 258 290 … … 260 292 psLogMsg("ppImage", PS_LOG_INFO, "Performing cell pattern correction for %s\n", chipName); 261 293 262 for (int i = 0; i < chip->cells->n; i++) { 263 view->cell = i; 264 265 pmCell *cell = chip->cells->data[i]; // Cell of interest 266 267 if (cell->readouts->n > 1) { 268 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction on video cell."); 269 continue; 270 } 271 272 bool doPattern = false; 273 if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) { 274 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 275 } 276 if (doPattern) { 277 tweak->data.U8[i] = 0xFF; 278 } 294 for (int i = 0; i < chip->cells->n; i++) 295 { 296 view->cell = i; 297 298 pmCell *cell = chip->cells->data[i]; // Cell of interest 299 300 if (cell->readouts->n > 1) 301 { 302 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction on video cell."); 303 continue; 304 } 305 306 bool doPattern = false; 307 if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) 308 { 309 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 310 } 311 if (doPattern) 312 { 313 tweak->data.U8[i] = 0xFF; 314 } 279 315 } 280 316 281 317 // Tweak the cells 282 318 if (!pmPatternCell(chip, tweak, options->patternCellBG, options->patternCellMean, 283 options->maskValue, options->darkMask)) { 284 psFree(tweak); 285 psFree(view); 286 return false; 319 options->maskValue, options->darkMask)) 320 { 321 psFree(tweak); 322 psFree(view); 323 return false; 287 324 } 288 325 psFree(tweak); 289 326 psFree(view); 290 327 291 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CEL", PS_META_REPLACE,"PATTERN.CELL correction applied",true);328 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CEL", PS_META_REPLACE, "PATTERN.CELL correction applied", true); 292 329 return true; 293 330 } 294 331 295 bool ppImageDetrendPatternDeadCellsMask (pmChip *chip, psImageMaskType maskVal) { 296 297 int numCells = chip->cells->n; // Number of cells 332 bool ppImageDetrendPatternDeadCellsMask(pmChip *chip, psImageMaskType maskVal) 333 { 334 335 int numCells = chip->cells->n; // Number of cells 298 336 299 337 // now mask bad cells 300 for (int i = 0; i < numCells; i++) { 301 pmCell *cell = chip->cells->data[i]; // Cell of interest 338 for (int i = 0; i < numCells; i++) 339 { 340 pmCell *cell = chip->cells->data[i]; // Cell of interest 302 341 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 303 342 304 psImage *mask = ro->mask; // mask of interest 305 int numCols = mask->numCols, numRows = mask->numRows; // Size of image 306 307 for (int y = 0; y < numRows; y++) { 308 for (int x = 0; x < numCols; x++) { 309 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal; 310 } 311 } 343 psImage *mask = ro->mask; // mask of interest 344 int numCols = mask->numCols, numRows = mask->numRows; // Size of image 345 346 for (int y = 0; y < numRows; y++) 347 { 348 for (int x = 0; x < numCols; x++) 349 { 350 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal; 351 } 352 } 312 353 } 313 354 return true; 314 355 } 315 356 316 bool ppImageDetrendPatternDeadCellsXY42 (pmChip *chip, psImageMaskType maskVal) { 357 bool ppImageDetrendPatternDeadCellsXY42(pmChip *chip, psImageMaskType maskVal) 358 { 317 359 318 360 bool status; 319 361 320 362 // extract the MEDIAN_CELL_BACKGROUND values to check for problems 321 int numCells = chip->cells->n; // Number of cells 322 psVector *cellBackground = psVectorAllocEmpty (numCells, PS_DATA_F32); 323 324 for (int i = 0; i < numCells; i++) { 325 pmCell *cell = chip->cells->data[i];; 326 327 if (!cell->process || !cell->file_exists || !cell->data_exists) continue; 328 329 // select the HDU for this cell 330 pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest 331 332 psF32 BackValue = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL"); 333 if (!status) continue; 334 335 psF32 BackError = psMetadataLookupF32(&status, cellHDU->header, "BACK_ERR"); 336 if (!status) continue; 337 338 if (BackValue == 0.0) continue; 339 if (BackError == 0.0) continue; 340 341 psVectorAppend (cellBackground, BackValue / BackError); 342 } 343 344 if (cellBackground->n < 0.375*numCells) { 345 // Chip is bad, mask the whole thing 346 ppImageDetrendPatternDeadCellsMask (chip, maskVal); 347 psFree (cellBackground); 348 return true; 363 int numCells = chip->cells->n; // Number of cells 364 psVector *cellBackground = psVectorAllocEmpty(numCells, PS_DATA_F32); 365 366 for (int i = 0; i < numCells; i++) 367 { 368 pmCell *cell = chip->cells->data[i]; 369 ; 370 371 if (!cell->process || !cell->file_exists || !cell->data_exists) 372 continue; 373 374 // select the HDU for this cell 375 pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest 376 377 psF32 BackValue = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL"); 378 if (!status) 379 continue; 380 381 psF32 BackError = psMetadataLookupF32(&status, cellHDU->header, "BACK_ERR"); 382 if (!status) 383 continue; 384 385 if (BackValue == 0.0) 386 continue; 387 if (BackError == 0.0) 388 continue; 389 390 psVectorAppend(cellBackground, BackValue / BackError); 391 } 392 393 if (cellBackground->n < 0.375 * numCells) 394 { 395 // Chip is bad, mask the whole thing 396 ppImageDetrendPatternDeadCellsMask(chip, maskVal); 397 psFree(cellBackground); 398 return true; 349 399 } 350 400 351 401 // Second, calculate the median 352 psVectorSortInPlace (cellBackground);402 psVectorSortInPlace(cellBackground); 353 403 int midPt = cellBackground->n / 2.0; 354 float median = cellBackground->n % 2 ? cellBackground->data.F32[midPt] : 0.5 *(cellBackground->data.F32[midPt] + cellBackground->data.F32[midPt-1]);355 psFree (cellBackground);404 float median = cellBackground->n % 2 ? cellBackground->data.F32[midPt] : 0.5 * (cellBackground->data.F32[midPt] + cellBackground->data.F32[midPt - 1]); 405 psFree(cellBackground); 356 406 357 407 // XXX hardwired number 358 if (median < 3.0) { 359 // Chip is bad, mask the whole thing 360 ppImageDetrendPatternDeadCellsMask (chip, maskVal); 361 } 362 psFree (cellBackground); 408 if (median < 3.0) 409 { 410 // Chip is bad, mask the whole thing 411 ppImageDetrendPatternDeadCellsMask(chip, maskVal); 412 } 413 psFree(cellBackground); 363 414 return true; 364 415 } 365 416 366 417 // to apply the dead cell pattern, we need to transfer the pattern for this chip from the 367 // pmFPAfile for the pattern to the one for the image being processed. 418 // pmFPAfile for the pattern to the one for the image being processed. 368 419 bool ppImageDetrendPatternDeadCellsApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options) 369 420 { 370 421 bool status; 371 422 372 if (!options->doPatternDeadCells) return true; 423 if (!options->doPatternDeadCells) 424 return true; 373 425 374 426 assert(inputView->chip != -1); … … 380 432 381 433 pmHDU *hdu = pmHDUFromChip(chip); 382 if (psMetadataLookupBool(&status, hdu->header, "PTRN_DED")) { 383 psLogMsg("ppImage", PS_LOG_INFO, "Not performing dead cell pattern correction as it has already been done."); 384 return true; 385 } 386 387 if (!strcmp (chipName, "XY40") || !strcmp (chipName, "XY42")) { 388 // special case : check for BACK_VAL / BACK_ERR > 3 or < 3 389 psLogMsg("ppImage", PS_LOG_INFO, "Using special case for XY40 and XY42"); 390 ppImageDetrendPatternDeadCellsXY42 (chip, options->blankMask); 391 return true; 434 if (psMetadataLookupBool(&status, hdu->header, "PTRN_DED")) 435 { 436 psLogMsg("ppImage", PS_LOG_INFO, "Not performing dead cell pattern correction as it has already been done."); 437 return true; 438 } 439 440 if (!strcmp(chipName, "XY40") || !strcmp(chipName, "XY42")) 441 { 442 // special case : check for BACK_VAL / BACK_ERR > 3 or < 3 443 psLogMsg("ppImage", PS_LOG_INFO, "Using special case for XY40 and XY42"); 444 ppImageDetrendPatternDeadCellsXY42(chip, options->blankMask); 445 return true; 392 446 } 393 447 394 448 pmFPAfile *pattern = psMetadataLookupPtr(&status, config->files, "PPIMAGE.PATTERN.DEAD.CELLS"); 395 if (!pattern) { 396 psLogMsg("ppImage", PS_LOG_INFO, "Pattern Dead Cells file not found, skipping"); 397 return true; 449 if (!pattern) 450 { 451 psLogMsg("ppImage", PS_LOG_INFO, "Pattern Dead Cells file not found, skipping"); 452 return true; 398 453 } 399 454 … … 401 456 *view = *inputView; 402 457 403 pmChip *patternChip = pmFPAviewThisChip (view, pattern->fpa);458 pmChip *patternChip = pmFPAviewThisChip(view, pattern->fpa); 404 459 405 460 // grab the pattern from the input pattern file chip 406 psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&status, patternChip->analysis, "PTN.DEAD.CELL"); 407 if (!deadCellPattern) { 461 psImage *deadCellPattern = (psImage *)psMetadataLookupPtr(&status, patternChip->analysis, "PTN.DEAD.CELL"); 462 if (!deadCellPattern) 463 { 408 464 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n"); 409 psFree(view);410 return true;465 psFree(view); 466 return true; 411 467 } 412 468 413 469 // copy the pattern pointer to the chip of the image being processed 414 psMetadataAddImage (chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellPattern);470 psMetadataAddImage(chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellPattern); 415 471 416 472 // extract the MEDIAN_CELL_BACKGROUND values to check for problems 417 int numCells = chip->cells->n; // Number of cells418 psVector *cellBackground = psVectorAllocEmpty (numCells, PS_DATA_F32);473 int numCells = chip->cells->n; // Number of cells 474 psVector *cellBackground = psVectorAllocEmpty(numCells, PS_DATA_F32); 419 475 420 476 pmCell *cell = NULL; 421 while ((cell = pmFPAviewNextCell(view, chip->parent, 1)) != NULL) { 422 if (!cell->process || !cell->file_exists || !cell->data_exists) { 423 psVectorAppend (cellBackground, NAN); 424 continue; 425 } 426 427 // select the HDU for this cell 428 pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest 429 430 psF32 value = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL"); 431 if (!status) { 432 psVectorAppend (cellBackground, NAN); 433 continue; 434 } 435 psVectorAppend (cellBackground, value); 477 while ((cell = pmFPAviewNextCell(view, chip->parent, 1)) != NULL) 478 { 479 if (!cell->process || !cell->file_exists || !cell->data_exists) 480 { 481 psVectorAppend(cellBackground, NAN); 482 continue; 483 } 484 485 // select the HDU for this cell 486 pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest 487 488 psF32 value = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL"); 489 if (!status) 490 { 491 psVectorAppend(cellBackground, NAN); 492 continue; 493 } 494 psVectorAppend(cellBackground, value); 436 495 } 437 496 438 497 // match cellBackground pattern to registered patterns and mask as needed 439 if (!pmPatternDeadCells(chip, cellBackground, options->blankMask)) { 440 psFree(cellBackground); 441 psFree(view); 442 return false; 498 if (!pmPatternDeadCells(chip, cellBackground, options->blankMask)) 499 { 500 psFree(cellBackground); 501 psFree(view); 502 return false; 443 503 } 444 504 psFree(cellBackground); … … 449 509 } 450 510 451 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue) { 511 bool ppImageDoPatternForView(bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue) 512 { 452 513 453 514 *doit = false; … … 456 517 457 518 doPattern = pmConfigRecipeValueByView(config, recipeName, recipeValue, chip->parent, view); 458 459 if (!doPattern) { 519 520 if (!doPattern) 521 { 460 522 psError(PS_ERR_UNKNOWN, false, "Unable to determine whether row pattern matching should be applied."); 461 523 return false; 462 524 } 463 if (doPattern->type == PS_DATA_BOOL) { 525 if (doPattern->type == PS_DATA_BOOL) 526 { 464 527 *doit = doPattern->data.B; 465 528 return true; 466 529 } 467 if (doPattern->type == PS_DATA_STRING) { 530 if (doPattern->type == PS_DATA_STRING) 531 { 468 532 // expect a string of the form "000110001001" with at least view->cell entries 469 533 char *string = doPattern->data.str; 470 if (strlen(string) < view->cell) { 471 psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string (too few elements %d)", (int) strlen(string)); 534 if (strlen(string) < view->cell) 535 { 536 psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string (too few elements %d)", (int)strlen(string)); 472 537 return false; 473 538 } 474 switch (string[view->cell]) { 475 case '0': 476 case 'f': 477 case 'F': 478 case 'n': 479 case 'N': 539 switch (string[view->cell]) 540 { 541 case '0': 542 case 'f': 543 case 'F': 544 case 'n': 545 case 'N': 480 546 *doit = false; 481 547 return true; 482 case '1':483 case 't':484 case 'T':485 case 'y':486 case 'Y':548 case '1': 549 case 't': 550 case 'T': 551 case 'y': 552 case 'Y': 487 553 *doit = true; 488 554 return true; 489 default:555 default: 490 556 psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string %s (unknown value %c))", string, string[view->cell]); 491 557 return false; … … 497 563 } 498 564 499 // thread safety : 500 bool ppImageDetrendPatternApplyCell (pmConfig *config, pmFPA *fpa, pmChip *chip, pmCell *cell, pmFPAview *view, ppImageOptions *options) { 501 565 // thread safety : 566 bool ppImageDetrendPatternApplyCell(pmConfig *config, pmFPA *fpa, pmChip *chip, pmCell *cell, pmFPAview *view, ppImageOptions *options) 567 { 568 502 569 // process each of the readouts 503 pmReadout *readout; // Readout from cell 504 while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) { 505 if (!readout->data_exists) { 506 continue; 507 } 508 509 // Perform pattern correction 510 if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter, 511 options->patternRowRej, options->patternRowThresh, options->patternRowMean, 512 options->patternRowStdev, options->maskValue, options->darkMask)) { 513 psFree (view); 514 return false; 515 } 516 } 517 psFree (view); // supplied view must be freeable 570 pmReadout *readout; // Readout from cell 571 while ((readout = pmFPAviewNextReadout(view, fpa, 1)) != NULL) 572 { 573 if (!readout->data_exists) 574 { 575 continue; 576 } 577 578 // Perform pattern correction 579 if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter, 580 options->patternRowRej, options->patternRowThresh, options->patternRowMean, 581 options->patternRowStdev, options->maskValue, options->darkMask)) 582 { 583 psFree(view); 584 return false; 585 } 586 } 587 psFree(view); // supplied view must be freeable 518 588 return true; 519 589 } 520 590 521 psVector *ppImageDetrendPatternCellFailures(pmFPAfile *input, const pmFPAview *inputView) { 522 591 psVector *ppImageDetrendPatternCellFailures(pmFPAfile *input, const pmFPAview *inputView) 592 { 593 523 594 bool status = false; 524 595 pmCell *cell = NULL; 525 596 526 597 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 527 598 *view = *inputView; 528 599 529 600 // extract the MEDIAN_CELL_BACKGROUND values to check for problems 530 psVector *cellBackground = psVectorAllocEmpty (64, PS_DATA_F32); 531 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) { 532 if (!cell->process || !cell->file_exists || !cell->data_exists) { 533 psVectorAppend (cellBackground, NAN); 534 continue; 535 } 536 537 // select the HDU for this cell 538 pmHDU *hdu = pmHDUFromCell(cell); // HDU of interest 539 540 psF32 value = psMetadataLookupF32(&status, hdu->header, "BACK_VAL"); 541 psVectorAppend (cellBackground, value); 601 psVector *cellBackground = psVectorAllocEmpty(64, PS_DATA_F32); 602 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) 603 { 604 if (!cell->process || !cell->file_exists || !cell->data_exists) 605 { 606 psVectorAppend(cellBackground, NAN); 607 continue; 608 } 609 610 // select the HDU for this cell 611 pmHDU *hdu = pmHDUFromCell(cell); // HDU of interest 612 613 psF32 value = psMetadataLookupF32(&status, hdu->header, "BACK_VAL"); 614 psVectorAppend(cellBackground, value); 542 615 } 543 616 return cellBackground;
Note:
See TracChangeset
for help on using the changeset viewer.
