Changeset 42379 for trunk/psModules/src/detrend/pmPattern.c
- Timestamp:
- Feb 8, 2023, 11:54:08 AM (3 years ago)
- Location:
- trunk/psModules
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/detrend/pmPattern.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20220316/psModules (added) merged: 42145,42147,42160,42166,42168,42215,42227,42347,42352,42371,42375
- Property svn:mergeinfo changed
-
trunk/psModules/src/detrend/pmPattern.c
r42092 r42379 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 }
Note:
See TracChangeset
for help on using the changeset viewer.
