Changeset 42168 for branches/eam_branches/ipp-20220316/psModules
- Timestamp:
- Apr 13, 2022, 10:54:54 AM (4 years ago)
- Location:
- branches/eam_branches/ipp-20220316/psModules/src
- Files:
-
- 10 edited
-
camera/pmFPAfile.c (modified) (2 diffs)
-
camera/pmFPAfile.h (modified) (1 diff)
-
camera/pmFPAfileFitsIO.c (modified) (1 diff)
-
camera/pmFPAfileIO.c (modified) (8 diffs)
-
detrend/pmDetrendDB.c (modified) (1 diff)
-
detrend/pmDetrendDB.h (modified) (1 diff)
-
detrend/pmPattern.c (modified) (1 diff)
-
detrend/pmPattern.h (modified) (1 diff)
-
detrend/pmPatternIO.c (modified) (2 diffs)
-
detrend/pmPatternIO.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20220316/psModules/src/camera/pmFPAfile.c
r41892 r42168 554 554 if (!strcasecmp(type, "PATTERN.ROW.AMP")) { 555 555 return PM_FPA_FILE_PATTERN_ROW_AMP; 556 } 557 if (!strcasecmp(type, "PATTERN.DEAD.CELLS")) { 558 return PM_FPA_FILE_PATTERN_DEAD_CELLS; 556 559 } 557 560 if (!strcasecmp(type, "SUBKERNEL")) { … … 611 614 case PM_FPA_FILE_PATTERN_ROW_AMP: 612 615 return ("PATTERN.ROW.AMP"); 616 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 617 return ("PATTERN.DEAD.CELLS"); 613 618 case PM_FPA_FILE_SUBKERNEL: 614 619 return ("SUBKERNEL"); -
branches/eam_branches/ipp-20220316/psModules/src/camera/pmFPAfile.h
r41892 r42168 53 53 PM_FPA_FILE_PATTERN, 54 54 PM_FPA_FILE_PATTERN_ROW_AMP, 55 PM_FPA_FILE_PATTERN_DEAD_CELLS, 55 56 PM_FPA_FILE_LINEARITY, 56 57 PM_FPA_FILE_EXPNUM, -
branches/eam_branches/ipp-20220316/psModules/src/camera/pmFPAfileFitsIO.c
r41892 r42168 153 153 case PM_FPA_FILE_KH_CORRECT: 154 154 case PM_FPA_FILE_PATTERN_ROW_AMP: 155 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 155 156 { 156 157 pmHDU *hdu = pmFPAviewThisHDU(view, fpa); -
branches/eam_branches/ipp-20220316/psModules/src/camera/pmFPAfileIO.c
r41892 r42168 256 256 status = pmPatternRowAmpRead(view, file, config); 257 257 break; 258 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 259 status = pmPatternDeadCellsRead(view, file, config); 260 break; 258 261 case PM_FPA_FILE_SX: 259 262 case PM_FPA_FILE_RAW: … … 367 370 case PM_FPA_FILE_KH_CORRECT: 368 371 case PM_FPA_FILE_PATTERN_ROW_AMP: 372 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 369 373 case PM_FPA_FILE_JPEG: 370 374 case PM_FPA_FILE_KAPA: … … 459 463 return true; 460 464 } 465 if (file->type == PM_FPA_FILE_PATTERN_DEAD_CELLS) { 466 psTrace("psModules.camera", 6, "skip write for %s, no write function defined", file->name); 467 return true; 468 } 461 469 462 470 // open the file if not yet opened … … 559 567 case PM_FPA_FILE_PATTERN_ROW_AMP: 560 568 psError(PS_ERR_IO, true, "cannot write type PATTERN.ROW.AMP (%s)", file->name); 569 break; 570 571 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 572 psError(PS_ERR_IO, true, "cannot write type PATTERN.DEAD.CELLS (%s)", file->name); 561 573 break; 562 574 … … 637 649 case PM_FPA_FILE_KH_CORRECT: 638 650 case PM_FPA_FILE_PATTERN_ROW_AMP: 651 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 639 652 case PM_FPA_FILE_LINEARITY: 640 653 case PM_FPA_FILE_EXPNUM: … … 716 729 case PM_FPA_FILE_KH_CORRECT: 717 730 case PM_FPA_FILE_PATTERN_ROW_AMP: 731 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 718 732 case PM_FPA_FILE_EXPNUM: 719 733 psTrace ("psModules.camera", 6, "NOT freeing %s (%s) : save for further analysis\n", file->filename, file->name); … … 880 894 case PM_FPA_FILE_KH_CORRECT: 881 895 case PM_FPA_FILE_PATTERN_ROW_AMP: 896 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 882 897 case PM_FPA_FILE_LINEARITY: 883 898 case PM_FPA_FILE_EXPNUM: … … 1085 1100 case PM_FPA_FILE_KH_CORRECT: 1086 1101 case PM_FPA_FILE_PATTERN_ROW_AMP: 1102 case PM_FPA_FILE_PATTERN_DEAD_CELLS: 1087 1103 case PM_FPA_FILE_SX: 1088 1104 case PM_FPA_FILE_RAW: -
branches/eam_branches/ipp-20220316/psModules/src/detrend/pmDetrendDB.c
r41892 r42168 113 113 DETREND_STRING_CASE(KH_CORRECT); 114 114 DETREND_STRING_CASE(PATTERN_ROW_AMP); 115 DETREND_STRING_CASE(PATTERN_DEAD_CELLS); 115 116 default: 116 117 return NULL; -
branches/eam_branches/ipp-20220316/psModules/src/detrend/pmDetrendDB.h
r41892 r42168 42 42 PM_DETREND_TYPE_KH_CORRECT, 43 43 PM_DETREND_TYPE_PATTERN_ROW_AMP, 44 PM_DETREND_TYPE_PATTERN_DEAD_CELLS, 44 45 } pmDetrendType; 45 46 -
branches/eam_branches/ipp-20220316/psModules/src/detrend/pmPattern.c
r42092 r42168 1005 1005 psFree(meanMask); 1006 1006 1007 return true; 1008 } 1009 1010 // Compare the backs (cellBackgrounds) vector to each of the patterns loaded for this chip. 1011 // Choose the one that matches best & mask as appropriate 1012 // can we pass the backgrounds in using an image (8 x 8) 1013 bool pmPatternDeadCells(pmChip *chip, const psVector *backs, psImageMaskType maskVal) 1014 { 1015 PS_ASSERT_PTR_NON_NULL(chip, false); 1016 PS_ASSERT_VECTOR_NON_NULL(backs, false); 1017 PS_ASSERT_VECTOR_SIZE(backs, chip->cells->n, false); 1018 PS_ASSERT_VECTOR_TYPE(backs, PS_TYPE_F32, false); 1019 1020 // Look for the dead cell pattern cube in the analysis metadata. 1021 // NOTE: not all chips have the pattern, skip if not found. 1022 bool mdok; 1023 psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&mdok, chip->analysis, "PTN.DEAD.CELL"); 1024 if (!mdok) { 1025 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n"); 1026 return true; 1027 } 1028 1029 int numCells = backs->n; // Number of cells 1030 int numColsD = deadCellPattern->numCols; 1031 int numRowsD = deadCellPattern->numRows; 1032 1033 assert (backs->n == numRowsD); 1034 1035 // The background values need to be normalized (divide by the median). 1036 // First extract the valid data values 1037 psVector *valid = psVectorAllocEmpty(backs->n, PS_TYPE_F32); // Mean for each cell 1038 for (int i = 0; i < backs->n; i++) { 1039 float value = backs->data.F32[i]; 1040 if (!isfinite(value)) { backs->data.F32[i] = NAN; continue; } 1041 if (value > 50000.0) { backs->data.F32[i] = NAN; continue; } // XXX warning: hard-wired value 1042 psVectorAppend (valid, value); 1043 } 1044 if (valid->n == 0) { 1045 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n"); 1046 psFree (valid); 1047 return true; 1048 } 1049 1050 // Second, calculate the median 1051 psVectorSortInPlace (valid); 1052 int midPt = valid->n / 2.0; 1053 float median = valid->n % 2 ? valid->data.F32[midPt] : 0.5*(valid->data.F32[midPt] + valid->data.F32[midPt-1]); 1054 psFree (valid); 1055 1056 // Finally, renormalize: 1057 for (int i = 0; i < backs->n; i++) { 1058 if (!isfinite(backs->data.F32[i])) { continue; } 1059 backs->data.F32[i] /= median; 1060 } 1061 1062 // there are 2 columns (value & mask) for each mode, plus the constant mode 1063 int nModes = numColsD / 2 + 1; 1064 1065 psVector *stdev = psVectorAlloc(nModes, PS_TYPE_F32); // Mean for each cell 1066 1067 // measure stdev for each comparison 1068 for (int i = 0; i < nModes; i++) { 1069 float Sum1 = 0.0; 1070 float Sum2 = 0.0; 1071 int Npts = 0; 1072 1073 // choose the column with the background values for this mode 1074 int nModeColumn = 2*(i - 1); 1075 1076 for (int j = 0; j < backs->n; j++) { 1077 1078 float valObs = backs->data.F32[j]; 1079 float valRef = (i == 0) ? 0.0 : deadCellPattern->data.F32[j][nModeColumn]; 1080 1081 if (!isfinite(valObs)) continue; 1082 if (!isfinite(valRef)) continue; 1083 1084 float dS = valObs - valRef; 1085 Sum1 += dS; 1086 Sum2 += dS*dS; 1087 Npts ++; 1088 } 1089 if (Npts == 0) { 1090 // is this is an error? 1091 // no valid data, ignore this test 1092 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n"); 1093 psFree (stdev); 1094 return true; 1095 } 1096 1097 float mean = Sum1 / Npts; 1098 float sigma = sqrt(Sum2 / Npts - mean*mean); 1099 stdev->data.F32[i] = sigma; 1100 fprintf (stderr, "mode: %d, stdev: %f\n", i, sigma); 1101 } 1102 1103 // loop over stdev and choose the lowest one 1104 int minI = 0; 1105 float minV = stdev->data.F32[minI]; 1106 1107 for (int i = 1; i < nModes; i++) { 1108 if (stdev->data.F32[i] < minV) { 1109 minI = i; 1110 minV = stdev->data.F32[i]; 1111 } 1112 } 1113 psFree (stdev); 1114 1115 if (minI == 0) return true; 1116 1117 int nModeColumnMask = 2*(minI - 1) + 1; 1118 1119 // now mask bad cells 1120 for (int i = 0; i < numCells; i++) { 1121 if (deadCellPattern->data.F32[i][nModeColumnMask] > 0) continue; 1122 1123 pmCell *cell = chip->cells->data[i]; // Cell of interest 1124 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 1125 1126 psImage *mask = ro->mask; // mask of interest 1127 int numCols = mask->numCols, numRows = mask->numRows; // Size of image 1128 1129 for (int y = 0; y < numRows; y++) { 1130 for (int x = 0; x < numCols; x++) { 1131 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal; 1132 } 1133 } 1134 } 1007 1135 return true; 1008 1136 } -
branches/eam_branches/ipp-20220316/psModules/src/detrend/pmPattern.h
r35081 r42168 86 86 87 87 88 bool pmPatternDeadCells(pmChip *chip, const psVector *backs, psImageMaskType maskVal); 89 88 90 /// @} 89 91 #endif -
branches/eam_branches/ipp-20220316/psModules/src/detrend/pmPatternIO.c
r41892 r42168 482 482 } 483 483 484 // read the set of tables, one for each chip 484 // Read the set of tables, one for each chip. The values are saved on the cell->analysis 485 // metadata of the pmFPAfile associated with the pattern file. Later, when this is used (e.g., 486 // ppImageDetrendPatternRowApply), the values are transferred to the cell->analysis metadata of 487 // the pmFPAfile for the image being processed. 485 488 bool pmPatternRowAmpReadChips (pmFPAfile *file) { 486 489 … … 560 563 return true; 561 564 } 565 566 /**************** PatternDeadCells I/O *************************/ 567 568 bool pmPatternDeadCellsRead (const pmFPAview *view, pmFPAfile *file, const pmConfig *config) 569 { 570 // read the full model in one pass: require the level to be FPA 571 if (view->chip != -1) { 572 psError(PS_ERR_IO, false, "Pattern Dead Cells must be read at the FPA level"); 573 return false; 574 } 575 576 if (!pmPatternDeadCellsReadFPA (file)) { 577 psError(PS_ERR_IO, false, "Failed to read Pattern Dead Cells for fpa"); 578 return false; 579 } 580 return true; 581 } 582 583 // read in all chip-level Pattern Dead Cells data for this FPA 584 bool pmPatternDeadCellsReadFPA (pmFPAfile *file) { 585 586 if (!pmPatternDeadCellsReadChips (file)) { 587 psError(PS_ERR_IO, false, "Failed to read Pattern Dead Cells for chips"); 588 return false; 589 } 590 591 return true; 592 } 593 594 // Read the set of dead cell image cubes, one for each chip. The values are saved on the 595 // chip->analysis metadata of the pmFPAfile associated with the pattern file. Later, when this 596 // is used (e.g., ppImageDetrendPatternDeadCellsApply), the values are transferred to the 597 // chip->analysis metadata of the pmFPAfile for the image being processed. 598 bool pmPatternDeadCellsReadChips (pmFPAfile *file) { 599 600 bool haveData, status; 601 602 // loop over the extensions 603 // for each extension, use the extname (eg, XY01.ded) to assign to a chip 604 605 // move to the start of the file 606 haveData = psFitsMoveExtNum (file->fits, 1, false); 607 if (!haveData) { 608 psError(PS_ERR_IO, false, "Failed to read even the first extension?"); 609 return false; 610 } 611 612 int nGood = 0; 613 while (haveData) { 614 615 // load the header 616 psMetadata *header = psFitsReadHeader(NULL, file->fits); // The FITS header 617 if (!header) psAbort("cannot read dead cell header"); 618 619 // load the full model in one shot 620 psImage *deadCellData = psFitsReadImage(file->fits, psRegionSet(0,0,0,0), 0); // dead cell patterns 621 if (!deadCellData) psAbort("cannot read dead cell pattern"); 622 623 // determine the chip (not all chips have DEAD CELL patterns) 624 char *extname = psMetadataLookupStr (&status, header, "EXTNAME"); 625 psLogMsg ("psModules.detrend", 8, "read dead cell pattern for extname %s\n", extname); 626 627 // I expect to find a name of the form: chipName.ded (eg, XY01.ded) 628 // where chipName like 'XY01' 629 psAssert (strlen(extname) == 8, "invalid extension %s", extname); 630 psAssert (extname[5] == 'd', "invalid extension %s", extname); 631 psAssert (extname[6] == 'e', "invalid extension %s", extname); 632 psAssert (extname[7] == 'd', "invalid extension %s", extname); 633 634 char chipName[5]; 635 strncpy (chipName, extname, 4); 636 chipName[4] = 0; 637 638 pmChip *chip = pmConceptsChipFromName (file->fpa, chipName); 639 if (!chip) psAbort ("invalid chip?"); 640 641 psMetadataAddImage (chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellData); 642 psFree (deadCellData); 643 psFree (header); 644 645 // move to the next extension 646 haveData = psFitsMoveExtNum (file->fits, 1, true); 647 nGood ++; 648 } 649 psLogMsg ("psModules.detrend", 4, "read patterns for %d chips from Pattern Dead Cells file\n", nGood); 650 651 return true; 652 } -
branches/eam_branches/ipp-20220316/psModules/src/detrend/pmPatternIO.h
r41892 r42168 40 40 bool pmPatternRowAmpReadChips (pmFPAfile *file); 41 41 42 bool pmPatternDeadCellsRead (const pmFPAview *view, pmFPAfile *file, const pmConfig *config); 43 bool pmPatternDeadCellsReadFPA (pmFPAfile *file); 44 bool pmPatternDeadCellsReadChips (pmFPAfile *file); 45 42 46 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
