Changeset 42885
- Timestamp:
- May 29, 2025, 3:28:25 PM (14 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
tags/ipp-ops-20220906/psModules/src/detrend/pmPattern.c
r42092 r42885 239 239 # define READNOISE 10 /* arbitrary number */ 240 240 float sigma = sqrt(stats->robustMedian + PS_SQR(READNOISE)); 241 if(isnan(sigma)) sigma=20.; 241 242 float delta = PS_MIN (thresh * sigma, 2*nominalAmplitude); 242 243 float lower = stats->robustMedian - delta; // Lower bound for data … … 246 247 // if the noise from the background is too large 247 248 float significance = nominalAmplitude / sigma; 249 significance = abs(significance); 248 250 249 251 // XXX EAM : arbitrary number 250 252 if (isfinite(nominalAmplitude) && (significance < 1.0/6.0)) { 253 psLogMsg("ppImage", PS_LOG_INFO, "Skipping row pattern correction for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance); 254 return true; 255 } 256 //Add some safeties in case of bad fits 257 if (isnan(significance) || (background < 0.0)) { 251 258 psLogMsg("ppImage", PS_LOG_INFO, "Skipping row pattern correction for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance); 252 259 return true; … … 554 561 # define READNOISE 10 /* arbitrary number */ 555 562 float sigma = sqrt(stats->robustMedian + PS_SQR(READNOISE)); 563 if(isnan(sigma)) sigma=20.; // XXX EAM : somewhat arbitrary number 556 564 float delta = PS_MIN (thresh * sigma, 5*nominalAmplitude); 557 565 float lower = stats->robustMedian - delta; // Lower bound for data … … 561 569 // if the noise from the background is too large 562 570 float significance = nominalAmplitude / sigma; 563 571 significance = abs(significance); 572 564 573 // XXX EAM : arbitrary number 565 574 if (isfinite(nominalAmplitude) && (significance < 1.0/6.0)) { … … 569 578 return true; 570 579 } 580 //Add some safeties in case of bad fits 581 if (isnan(significance) || (background < 0.0)) { 582 psLogMsg("ppImage", PS_LOG_INFO, "Skipping row pattern correction due to bad fit for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance); 583 psFree(stats); 584 psFree(rng); 585 return true; 586 } 587 571 588 psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance); 572 589 # endif … … 1005 1022 psFree(meanMask); 1006 1023 1024 return true; 1025 } 1026 1027 // Compare the backs (cellBackgrounds) vector to each of the patterns loaded for this chip. 1028 // Choose the one that matches best & mask as appropriate 1029 // can we pass the backgrounds in using an image (8 x 8) 1030 bool pmPatternDeadCells(pmChip *chip, const psVector *backs, psImageMaskType maskVal) 1031 { 1032 PS_ASSERT_PTR_NON_NULL(chip, false); 1033 PS_ASSERT_VECTOR_NON_NULL(backs, false); 1034 PS_ASSERT_VECTOR_SIZE(backs, chip->cells->n, false); 1035 PS_ASSERT_VECTOR_TYPE(backs, PS_TYPE_F32, false); 1036 1037 // Look for the dead cell pattern cube in the analysis metadata. 1038 // NOTE: not all chips have the pattern, skip if not found. 1039 bool mdok; 1040 psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&mdok, chip->analysis, "PTN.DEAD.CELL"); 1041 if (!mdok) { 1042 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n"); 1043 return true; 1044 } 1045 1046 int numCells = backs->n; // Number of cells 1047 int numColsD = deadCellPattern->numCols; 1048 int numRowsD = deadCellPattern->numRows; 1049 1050 assert (backs->n == numRowsD); 1051 1052 // The background values need to be normalized (divide by the median). 1053 // First extract the valid data values 1054 psVector *valid = psVectorAllocEmpty(backs->n, PS_TYPE_F32); // Mean for each cell 1055 for (int i = 0; i < backs->n; i++) { 1056 float value = backs->data.F32[i]; 1057 if (!isfinite(value)) { backs->data.F32[i] = NAN; continue; } 1058 if (value > 50000.0) { backs->data.F32[i] = NAN; continue; } // XXX warning: hard-wired value 1059 psVectorAppend (valid, value); 1060 } 1061 if (valid->n == 0) { 1062 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n"); 1063 psFree (valid); 1064 return true; 1065 } 1066 1067 // Second, calculate the median 1068 psVectorSortInPlace (valid); 1069 int midPt = valid->n / 2.0; 1070 float median = valid->n % 2 ? valid->data.F32[midPt] : 0.5*(valid->data.F32[midPt] + valid->data.F32[midPt-1]); 1071 psFree (valid); 1072 1073 // Finally, renormalize: 1074 for (int i = 0; i < backs->n; i++) { 1075 if (!isfinite(backs->data.F32[i])) { continue; } 1076 backs->data.F32[i] /= median; 1077 } 1078 1079 // there are 2 columns (value & mask) for each mode, plus the constant mode 1080 int nModes = numColsD / 2 + 1; 1081 1082 psVector *stdev = psVectorAlloc(nModes, PS_TYPE_F32); // Mean for each cell 1083 1084 // measure stdev for each comparison 1085 for (int i = 0; i < nModes; i++) { 1086 float Sum1 = 0.0; 1087 float Sum2 = 0.0; 1088 int Npts = 0; 1089 1090 // choose the column with the background values for this mode 1091 int nModeColumn = 2*(i - 1); 1092 1093 for (int j = 0; j < backs->n; j++) { 1094 1095 float valObs = backs->data.F32[j]; 1096 float valRef = (i == 0) ? 0.0 : deadCellPattern->data.F32[j][nModeColumn]; 1097 1098 if (!isfinite(valObs)) continue; 1099 if (!isfinite(valRef)) continue; 1100 1101 float dS = valObs - valRef; 1102 Sum1 += dS; 1103 Sum2 += dS*dS; 1104 Npts ++; 1105 } 1106 if (Npts == 0) { 1107 // is this is an error? 1108 // no valid data, ignore this test 1109 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n"); 1110 psFree (stdev); 1111 return true; 1112 } 1113 1114 float mean = Sum1 / Npts; 1115 float sigma = sqrt(Sum2 / Npts - mean*mean); 1116 stdev->data.F32[i] = sigma; 1117 fprintf (stderr, "mode: %d, stdev: %f\n", i, sigma); 1118 } 1119 1120 // loop over stdev and choose the lowest one 1121 int minI = 0; 1122 float minV = stdev->data.F32[minI]; 1123 1124 for (int i = 1; i < nModes; i++) { 1125 if (stdev->data.F32[i] < minV) { 1126 minI = i; 1127 minV = stdev->data.F32[i]; 1128 } 1129 } 1130 psFree (stdev); 1131 1132 if (minI == 0) return true; 1133 1134 int nModeColumnMask = 2*(minI - 1) + 1; 1135 1136 // now mask bad cells 1137 for (int i = 0; i < numCells; i++) { 1138 if (deadCellPattern->data.F32[i][nModeColumnMask] > 0) continue; 1139 1140 pmCell *cell = chip->cells->data[i]; // Cell of interest 1141 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 1142 1143 psImage *mask = ro->mask; // mask of interest 1144 int numCols = mask->numCols, numRows = mask->numRows; // Size of image 1145 1146 for (int y = 0; y < numRows; y++) { 1147 for (int x = 0; x < numCols; x++) { 1148 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal; 1149 } 1150 } 1151 } 1007 1152 return true; 1008 1153 }
Note:
See TracChangeset
for help on using the changeset viewer.
