Changeset 42167
- Timestamp:
- Apr 13, 2022, 10:53:25 AM (4 years ago)
- Location:
- branches/eam_branches/ipp-20220316/ppImage/src
- Files:
-
- 8 edited
-
ppImage.h (modified) (1 diff)
-
ppImageArguments.c (modified) (1 diff)
-
ppImageDetrendFringe.c (modified) (1 diff)
-
ppImageDetrendPattern.c (modified) (4 diffs)
-
ppImageDetrendReadout.c (modified) (2 diffs)
-
ppImageLoop.c (modified) (2 diffs)
-
ppImageOptions.c (modified) (1 diff)
-
ppImageParseCamera.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20220316/ppImage/src/ppImage.h
r41894 r42167 46 46 bool doPatternContinuity; // Cell continuity correction 47 47 bool doBackgroundContinuity; // Do mosaic continuity correction 48 bool doPatternDeadCells; // match dead cell background patterns 48 49 bool doFringe; // Fringe subtraction 49 50 bool doPhotom; // Source identification and photometry -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageArguments.c
r41894 r42167 117 117 pmConfigFileSetsMD (config->arguments, &argc, argv, "LINEARITY", "-linearity", "-linearlist"); 118 118 pmConfigFileSetsMD (config->arguments, &argc, argv, "PATTERN.ROW.AMP", "-pattern-row-amplitude", "-not-defined"); 119 pmConfigFileSetsMD (config->arguments, &argc, argv, "PATTERN.DEAD.CELLS", "-pattern-dead-cells", "-not-defined"); 119 120 120 121 if ((argnum = psArgumentGet(argc, argv, "-burntool"))) { -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendFringe.c
r37406 r42167 327 327 pmCell *cell = NULL; 328 328 329 // psTimerStart("apply.fringe"); 330 331 assert (options->doFringe); // do not call if not needed 329 if (!options->doFringe) return true; 330 332 331 assert (inputView->chip != -1); 333 332 assert (inputView->cell == -1); -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendPattern.c
r42166 r42167 5 5 #include "ppImage.h" 6 6 7 #define ESCAPE(STATUS,...) { \7 #define ESCAPE(STATUS,...) { \ 8 8 psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__); \ 9 9 psFree(view); \ … … 13 13 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue); 14 14 15 bool ppImageDetrendPatternApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, 16 ppImageOptions *options) 15 bool ppImageDetrendPatternRowApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options); 16 bool ppImageDetrendPatternContinuityApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options); 17 bool ppImageDetrendPatternCellApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options); 18 bool ppImageDetrendPatternDeadCellsApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options); 19 20 // Apply the desired pattern corrections (if any). This function is passed the chip for the 21 // image being processed, but may interact with pmFPAfiles containing the pattern reference information 22 bool ppImageDetrendPatternApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options) 17 23 { 18 pmCell *cell = NULL; 19 20 assert(options->doPatternRow || options->doPatternCell || options->doPatternContinuity); // do not call if not needed 24 assert(inputView->chip != -1); 25 assert(inputView->cell == -1); 26 assert(inputView->readout == -1); 27 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); 41 } 42 43 bool ppImageDetrendPatternRowApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options) 44 { 45 bool status; 46 47 if (!options->doPatternRow) return true; 48 21 49 assert(inputView->chip != -1); 22 50 assert(inputView->cell == -1); … … 35 63 // tables, one per chip. Each table lists the typical bias-drift amplitude for cell, 36 64 // measured from a collection of dark images. These values are passed (via 37 // cell->analysis) to pmPatternRow which choose dto apply the correction based on the65 // cell->analysis) to pmPatternRow which chooses to apply the correction based on the 38 66 // ratio of the poisson noise due to the median background (+ read noise) and the 39 67 // typical amplitude. Tests show that if the amplitude / noise < 1/6, then the … … 44 72 // chip. 45 73 46 // psTimerStart("apply.pattern"); 47 if (options->doPatternRow) { 48 49 //psLogMsg("ppImage", PS_LOG_INFO, "Log: entering pattern.row routine"); 50 //psWarning ("Entering pattern.row routine"); 51 52 bool status; 53 pmHDU *hdu = pmHDUFromChip(chip); 54 if (psMetadataLookupBool(NULL,hdu->header,"PTRN_ROW")) { 55 psLogMsg("ppImage", PS_LOG_INFO, "Not performing row pattern correction as it has already been done."); 56 goto pattern_continuity; 57 } 58 59 const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 60 psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s\n", chipName); 61 62 pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.INPUT"); 63 64 // grab the PATTERN.ROW.AMP file 65 pmFPAfile *PRAfile = psMetadataLookupPtr (NULL, config->files, "PPIMAGE.PATTERN.ROW.AMP"); 66 if (!PRAfile) { 67 psLogMsg("ppImage", PS_LOG_INFO, "Pattern Row Amplitude file not found, applying to all (with limits from ROW.SUBSET) "); 68 } 69 70 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 71 *view = *inputView; 72 while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) { 73 //const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 74 //const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); 75 //psWarning ("Looping through %s, %s\n", chipName, cellName); 76 77 if (!cell->process || !cell->file_exists) { 78 continue; 79 } 80 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) { 81 ESCAPE(false, "load failure for Cell"); 82 } 74 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; 78 } 79 80 const char *chipName = psMetadataLookupStr(&status, chip->concepts, "CHIP.NAME"); 81 psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s\n", chipName); 82 83 // XXX we use input->fpa below, but could we just use chip->parent? 84 pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.INPUT"); 85 86 // 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 92 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 93 *view = *inputView; 94 95 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 } 83 109 84 if (!cell->data_exists) {85 continue;86 }87 88 if (cell->readouts->n > 1) {89 psWarning ("Skipping Video Cell for ppImageDetrendPatternApply");90 continue;91 }92 93 // grab the corresponding cell94 if (PRAfile) {95 pmCell *PRAcell = pmFPAviewThisCell (view, PRAfile->fpa);96 psAssert (PRAcell, "found Pattern Row Amplitude file, but not cell?");97 98 // find the nominal signal amplitude (check the ghost and/or crosstalk recipe file)99 float amplitude = psMetadataLookupF32 (&status, PRAcell->analysis, "PTN.ROW.AMP");100 if (!status) amplitude = NAN;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; 101 127 102 // put the value on the science cell 103 psMetadataAddF32 (cell->analysis, PS_LIST_TAIL, "PTN.ROW.AMP", PS_META_REPLACE, "", amplitude); 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; 104 155 } 105 106 bool doPattern = false; 107 if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) { 108 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 109 } 110 if (!doPattern) continue; 111 112 // switch to test threaded version 113 if (true) { 114 // I need to allocate a view here to be freed by the 115 // called function below. 116 pmFPAview *myView = pmFPAviewAlloc(0); // View for local processing 117 *myView = *view; 118 119 // allocate a job, construct the arguments for this job 120 psThreadJob *job = psThreadJobAlloc("PPIMAGE_PATTERN_ROW_CELL"); 121 psArrayAdd(job->args, 1, config); 122 psArrayAdd(job->args, 1, input->fpa); 123 psArrayAdd(job->args, 1, chip); 124 psArrayAdd(job->args, 1, cell); 125 psArrayAdd(job->args, 1, myView); 126 psArrayAdd(job->args, 1, options); 127 if (!psThreadJobAddPending(job)) { 128 return false; 129 } 130 } else { 131 // bump the counter since it must be freed by the function below. 132 psMemIncrRefCounter (view); // View for local processing 133 if (!ppImageDetrendPatternApplyCell (config, input->fpa, chip, cell, view, options)) { 134 return false; 135 } 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; 136 161 } 137 138 } 139 140 // wait here for the threaded jobs to finish 141 // if no threads are allocated, this 142 if (!psThreadPoolWait(true, true)) { 143 psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction."); 144 return false; 145 } 146 147 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_ROW",PS_META_REPLACE,"PATTERN.ROW correction applied",true); 148 psFree(view); 149 } 150 151 pattern_continuity: 162 } 163 } 164 165 // 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); 173 psFree(view); 174 175 return true; 176 } 177 178 bool ppImageDetrendPatternContinuityApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options) 179 { 180 bool status; 181 182 if (!options->doPatternContinuity) return true; 183 184 assert(inputView->chip != -1); 185 assert(inputView->cell == -1); 186 assert(inputView->readout == -1); 152 187 153 188 // see the comment for PATTERN.ROW; the same rules apply for PATTERN.CELL 154 189 155 if (options->doPatternContinuity) { 156 int numCells = chip->cells->n; // Number of cells 157 psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell? 158 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 159 *view = *inputView; 160 161 pmHDU *hdu = pmHDUFromChip(chip); 162 if (psMetadataLookupBool(NULL,hdu->header,"PTRN_CON")) { 163 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction as it has already been done."); 164 goto pattern_cell; 165 } 166 167 const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 168 psLogMsg("ppImage", PS_LOG_INFO, "Performing pattern continuity correction for %s\n", chipName); 169 170 for (int i = 0; i < chip->cells->n; i++) { 171 view->cell = i; 172 173 pmCell *cell = chip->cells->data[i]; // Cell of interest 174 175 if (cell->readouts->n > 1) { 176 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction on video cell."); 177 continue; 178 } 179 180 bool doPattern = false; 181 if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET")) { 182 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 183 } 184 185 if (doPattern) { 186 tweak->data.U8[i] = 0xFF; 187 } 188 } 189 190 // Tweak the cells 191 if (!pmPatternContinuity(chip, tweak, options->patternCellBG, options->patternCellMean, 192 options->maskValue, options->darkMask,options->patternContinuityEdgeWidth)) { 193 psFree(tweak); 194 psFree(view); 195 return false; 196 } 190 int numCells = chip->cells->n; // Number of cells 191 psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell? 192 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 193 *view = *inputView; 194 195 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; 199 } 200 201 const char *chipName = psMetadataLookupStr(&status, chip->concepts, "CHIP.NAME"); 202 psLogMsg("ppImage", PS_LOG_INFO, "Performing pattern continuity correction for %s\n", chipName); 203 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 } 222 } 223 224 // Tweak the cells 225 if (!pmPatternContinuity(chip, tweak, options->patternCellBG, options->patternCellMean, 226 options->maskValue, options->darkMask,options->patternContinuityEdgeWidth)) { 197 227 psFree(tweak); 198 228 psFree(view); 199 200 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CON",PS_META_REPLACE,"PATTERN.CONTINUITY correction applied",true); 201 } 202 203 pattern_cell: 204 205 if (options->doPatternCell) { 206 int numCells = chip->cells->n; // Number of cells 207 psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell? 208 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 209 *view = *inputView; 210 211 pmHDU *hdu = pmHDUFromChip(chip); 212 if (psMetadataLookupBool(NULL,hdu->header,"PTRN_CEL")) { 213 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction as it has already been done."); 214 goto pattern_done; 215 } 216 217 const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME"); 218 psLogMsg("ppImage", PS_LOG_INFO, "Performing cell pattern correction for %s\n", chipName); 219 220 for (int i = 0; i < chip->cells->n; i++) { 221 view->cell = i; 222 223 pmCell *cell = chip->cells->data[i]; // Cell of interest 224 225 if (cell->readouts->n > 1) { 226 psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction on video cell."); 227 continue; 228 } 229 230 bool doPattern = false; 231 if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) { 232 ESCAPE(false, "Unable to determine whether row pattern matching should be applied."); 233 } 234 if (doPattern) { 235 tweak->data.U8[i] = 0xFF; 236 } 237 } 238 239 // Tweak the cells 240 if (!pmPatternCell(chip, tweak, options->patternCellBG, options->patternCellMean, 241 options->maskValue, options->darkMask)) { 242 psFree(tweak); 243 psFree(view); 244 return false; 245 } 229 return false; 230 } 231 psFree(tweak); 232 psFree(view); 233 234 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CON",PS_META_REPLACE,"PATTERN.CONTINUITY correction applied",true); 235 return true; 236 } 237 238 bool ppImageDetrendPatternCellApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options) 239 { 240 bool status; 241 242 if (!options->doPatternCell) return true; 243 244 assert(inputView->chip != -1); 245 assert(inputView->cell == -1); 246 assert(inputView->readout == -1); 247 248 int numCells = chip->cells->n; // Number of cells 249 psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell? 250 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 251 *view = *inputView; 252 253 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; 257 } 258 259 const char *chipName = psMetadataLookupStr(&status, chip->concepts, "CHIP.NAME"); 260 psLogMsg("ppImage", PS_LOG_INFO, "Performing cell pattern correction for %s\n", chipName); 261 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 } 279 } 280 281 // Tweak the cells 282 if (!pmPatternCell(chip, tweak, options->patternCellBG, options->patternCellMean, 283 options->maskValue, options->darkMask)) { 246 284 psFree(tweak); 247 285 psFree(view); 248 249 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CEL",PS_META_REPLACE,"PATTERN.CELL correction applied",true); 250 } 251 252 pattern_done: 253 254 // psLogMsg ("ppImage", 5, "apply pattern: %f sec\n", psTimerMark ("apply.pattern")); 255 256 return(true); 286 return false; 287 } 288 psFree(tweak); 289 psFree(view); 290 291 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CEL",PS_META_REPLACE,"PATTERN.CELL correction applied",true); 292 return true; 293 } 294 295 bool ppImageDetrendPatternDeadCellsMask (pmChip *chip, psImageMaskType maskVal) { 296 297 int numCells = chip->cells->n; // Number of cells 298 299 // now mask bad cells 300 for (int i = 0; i < numCells; i++) { 301 pmCell *cell = chip->cells->data[i]; // Cell of interest 302 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 303 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 } 312 } 313 314 } 315 316 bool ppImageDetrendPatternDeadCellsXY42 (pmChip *chip, psImageMaskType maskVal) { 317 318 bool status; 319 320 // 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; 349 } 350 351 // Second, calculate the median 352 psVectorSortInPlace (cellBackground); 353 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); 356 357 if (median < 3.0) { 358 // Chip is bad, mask the whole thing 359 ppImageDetrendPatternDeadCellsMask (chip, maskVal); 360 } 361 psFree (cellBackground); 362 return true; 363 } 364 365 // to apply the dead cell pattern, we need to transfer the pattern for this chip from the 366 // pmFPAfile for the pattern to the one for the image being processed. 367 bool ppImageDetrendPatternDeadCellsApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options) 368 { 369 bool status; 370 371 if (!options->doPatternDeadCells) return true; 372 373 assert(inputView->chip != -1); 374 assert(inputView->cell == -1); 375 assert(inputView->readout == -1); 376 377 const char *chipName = psMetadataLookupStr(&status, chip->concepts, "CHIP.NAME"); 378 psLogMsg("ppImage", PS_LOG_INFO, "Performing cell pattern correction for %s\n", chipName); 379 380 pmHDU *hdu = pmHDUFromChip(chip); 381 if (psMetadataLookupBool(&status, hdu->header, "PTRN_DED")) { 382 psLogMsg("ppImage", PS_LOG_INFO, "Not performing dead cell pattern correction as it has already been done."); 383 return true; 384 } 385 386 if (!strcmp (chipName, "XY40") || !strcmp (chipName, "XY42")) { 387 // special case : check for BACK_VAL / BACK_ERR > 3 or < 3 388 psLogMsg("ppImage", PS_LOG_INFO, "Using special case for XY40 and XY42"); 389 ppImageDetrendPatternDeadCellsXY42 (chip, options->blankMask); 390 return true; 391 } 392 393 pmFPAfile *pattern = psMetadataLookupPtr(&status, config->files, "PPIMAGE.PATTERN.DEAD.CELLS"); 394 if (!pattern) { 395 psLogMsg("ppImage", PS_LOG_INFO, "Pattern Dead Cells file not found, skipping"); 396 return true; 397 } 398 399 pmFPAview *view = pmFPAviewAlloc(0); // View for local processing 400 *view = *inputView; 401 402 pmChip *patternChip = pmFPAviewThisChip (view, pattern->fpa); 403 404 // grab the pattern from the input pattern file chip 405 psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&status, patternChip->analysis, "PTN.DEAD.CELL"); 406 if (!deadCellPattern) { 407 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n"); 408 psFree (view); 409 return true; 410 } 411 412 // copy the pattern pointer to the chip of the image being processed 413 psMetadataAddImage (chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellPattern); 414 415 // extract the MEDIAN_CELL_BACKGROUND values to check for problems 416 int numCells = chip->cells->n; // Number of cells 417 psVector *cellBackground = psVectorAllocEmpty (numCells, PS_DATA_F32); 418 419 pmCell *cell = NULL; 420 while ((cell = pmFPAviewNextCell(view, chip->parent, 1)) != NULL) { 421 if (!cell->process || !cell->file_exists || !cell->data_exists) { 422 psVectorAppend (cellBackground, NAN); 423 continue; 424 } 425 426 // select the HDU for this cell 427 pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest 428 429 psF32 value = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL"); 430 if (!status) { 431 psVectorAppend (cellBackground, NAN); 432 continue; 433 } 434 psVectorAppend (cellBackground, value); 435 } 436 437 // match cellBackground pattern to registered patterns and mask as needed 438 if (!pmPatternDeadCells(chip, cellBackground, options->blankMask)) { 439 psFree(cellBackground); 440 psFree(view); 441 return false; 442 } 443 psFree(cellBackground); 444 psFree(view); 445 446 psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_DED", PS_META_REPLACE, "PATTERN.DEADCELLS applied", true); 447 return true; 257 448 } 258 449 -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageDetrendReadout.c
r42158 r42167 126 126 127 127 // measure the overscan-subtracted readoutBackground here (or subtract the overscan value?) 128 if (1) { 129 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN); 128 // XXX this is the measurements and should be independent of the pattern masking 129 if (options->doPatternDeadCells) { 130 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 130 131 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); 131 132 psImageBackground (stats, NULL, input->image, NULL, 0xffff, rng); … … 134 135 pmHDU *hdu = pmHDUFromReadout(input); // HDU of interest 135 136 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "BACK_VAL", PS_META_REPLACE, "Median cell background", stats->robustMedian); 137 psMetadataAddF32(hdu->header, PS_LIST_TAIL, "BACK_ERR", PS_META_REPLACE, "Stdev of cell background", stats->robustStdev); 136 138 psFree (stats); 137 139 psFree (rng); -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageLoop.c
r42166 r42167 171 171 } 172 172 173 // Apply the pattern correction174 // XX if (options->checkCellFailures) {175 // XX if (!ppImageDetrendPatternCellFailures(config,chip,view,options)) {176 // XX ESCAPE("Unable to apply pattern corrections");177 // XX }178 // XX }179 180 181 173 // Apply the fringe correction 182 if (options->doFringe) { 183 if (!ppImageDetrendFringeApply(config, chip, view, options)) { 184 ESCAPE("Unable to defringe"); 185 } 174 if (!ppImageDetrendFringeApply(config, chip, view, options)) { 175 ESCAPE("Unable to defringe"); 186 176 } 187 177 … … 191 181 } 192 182 193 // Apply the pattern correction 194 if (options->doPatternRow || options->doPatternCell || options->doPatternContinuity) { 195 if (!ppImageDetrendPatternApply(config,chip,view,options)) { 196 ESCAPE("Unable to apply pattern corrections"); 197 } 183 // Apply the pattern correction (only done if requested) 184 if (!ppImageDetrendPatternApply(config,chip,view,options)) { 185 ESCAPE("Problem applying pattern corrections"); 198 186 } 199 187 -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageOptions.c
r42161 r42167 290 290 options->doPatternCell = psMetadataLookupBool(NULL, recipe, "PATTERN.CELL"); 291 291 options->doPatternContinuity = psMetadataLookupBool(NULL, recipe, "PATTERN.CONTINUITY"); 292 options->doPatternDeadCells = psMetadataLookupBool(NULL, recipe, "PATTERN.DEAD.CELLS"); 292 293 293 294 options->doMaskStats = psMetadataLookupBool(NULL, recipe, "MASK.STATS"); -
branches/eam_branches/ipp-20220316/ppImage/src/ppImageParseCamera.c
r41894 r42167 190 190 // an empty or invalid file may have been generated -- we want to skip, not raise an error 191 191 pmFPAfile *PRAfile = psMetadataLookupPtr (NULL, config->files, "PPIMAGE.PATTERN.ROW.AMP"); 192 if (PRAfile) { 193 PRAfile->state |= PM_FPA_STATE_INACTIVE; 194 } 195 } 196 } 197 if (options->doPatternDeadCells) { 198 if (!ppImageDefineFile(config, input->fpa, "PPIMAGE.PATTERN.DEAD.CELLS", "PATTERN.DEAD.CELLS", 199 PM_FPA_FILE_PATTERN_DEAD_CELLS, PM_DETREND_TYPE_PATTERN_DEAD_CELLS)) { 200 psWarning ("Can't find a pattern dead cells source"); 201 // an empty or invalid file may have been generated -- we want to skip, not raise an error 202 pmFPAfile *PRAfile = psMetadataLookupPtr (NULL, config->files, "PPIMAGE.PATTERN.DEAD.CELLS"); 192 203 if (PRAfile) { 193 204 PRAfile->state |= PM_FPA_STATE_INACTIVE;
Note:
See TracChangeset
for help on using the changeset viewer.
