Changeset 26893 for trunk/psModules/src/detrend/pmPattern.c
- Timestamp:
- Feb 10, 2010, 7:34:39 PM (16 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/detrend/pmPattern.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/detrend/pmPattern.c
r24905 r26893 1 1 #include <stdio.h> 2 #include <string.h> 2 3 #include <pslib.h> 3 4 … … 9 10 // Mask a row as bad 10 11 static void patternMaskRow(pmReadout *ro, // Readout to mask 11 int y, // Row to mask12 int y, // Row to mask 12 13 psImageMaskType bad // Mask value to give 13 14 ) … … 17 18 psAssert(y < image->numRows, "Row not in image"); 18 19 19 int numCols = image->numCols; // Size of image20 int numCols = image->numCols; // Number of columns 20 21 for (int x = 0; x < numCols; x++) { 21 22 image->data.F32[y][x] = NAN; … … 29 30 return; 30 31 } 32 33 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 34 // Measurement and application 35 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 31 36 32 37 bool pmPatternRow(pmReadout *ro, int order, int iter, float rej, float thresh, … … 63 68 float lower = stats->robustMedian - thresh * stats->robustStdev; // Lower bound for data 64 69 float upper = stats->robustMedian + thresh * stats->robustStdev; // Upper bound for data 70 float background = stats->robustMedian; 65 71 psFree(stats); 66 72 psFree(rng); … … 79 85 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, order); // Polynomial to fit 80 86 psVector *data = psVectorAlloc(numCols, PS_TYPE_F32); // Data to fit 87 88 psImage *corr = psImageAlloc(order + 1, numRows, PS_TYPE_F64); // Corrections applied 89 psImageInit(corr, NAN); 81 90 82 91 for (int y = 0; y < numRows; y++) { … … 104 113 continue; 105 114 } 115 116 poly->coeff[0] -= background; 117 memcpy(corr->data.F64[y], poly->coeff, (order + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F64)); 106 118 psVector *solution = psPolynomial1DEvalVector(poly, indices); // Solution vector 107 119 if (!solution) { … … 117 129 psFree(solution); 118 130 } 131 132 psMetadataAddImage(ro->analysis, PS_LIST_TAIL, PM_PATTERN_ROW_CORRECTION, PS_META_REPLACE, 133 "Pattern row correction", corr); 134 psFree(corr); 119 135 120 136 psFree(indices); … … 126 142 return true; 127 143 } 144 145 bool pmPatternRowApply(pmReadout *ro, psImageMaskType maskBad) 146 { 147 PM_ASSERT_READOUT_NON_NULL(ro, false); 148 PM_ASSERT_READOUT_IMAGE(ro, false); 149 150 bool mdok; // Status of MD lookup 151 psImage *corr = psMetadataLookupPtr(&mdok, ro->analysis, PM_PATTERN_ROW_CORRECTION); // Correction 152 if (!mdok) { 153 // No correction to apply 154 return true; 155 } 156 157 psImage *image = ro->image; // Image of interest 158 int numCols = image->numCols, numRows = image->numRows; // Size of image 159 160 if (corr->numRows != numRows) { 161 psError(PS_ERR_BAD_PARAMETER_SIZE, true, 162 "Number of rows of image (%d) does not match number of rows of pattern correction (%d)\n", 163 numRows, corr->numRows); 164 return false; 165 } 166 167 int order = corr->numCols - 1; // Polynomial order 168 psPolynomial1D *poly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, order); // Polynomial to apply 169 psVector *indices = psVectorAlloc(numCols, PS_TYPE_F32); // Indices for polynomial 170 float norm = 2.0 / (float)numCols; // Normalisation for indices 171 for (int x = 0; x < numCols; x++) { 172 indices->data.F32[x] = x * norm - 1.0; 173 } 174 175 for (int y = 0; y < numRows; y++) { 176 memcpy(poly->coeff, corr->data.F64[y], (order + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F64)); 177 psVector *solution = psPolynomial1DEvalVector(poly, indices); // Solution vector 178 if (!solution) { 179 psWarning("Unable to evaluate polynomial for row %d", y); 180 psErrorClear(); 181 patternMaskRow(ro, y, maskBad); 182 continue; 183 } 184 185 for (int x = 0; x < numCols; x++) { 186 image->data.F32[y][x] -= solution->data.F32[x]; 187 } 188 psFree(solution); 189 } 190 191 psFree(poly); 192 psFree(indices); 193 194 return true; 195 } 196 197 198 bool pmPatternCell(pmChip *chip, const psVector *tweak, psStatsOptions bgStat, psStatsOptions cellStat, 199 psImageMaskType maskVal, psImageMaskType maskBad) 200 { 201 PS_ASSERT_PTR_NON_NULL(chip, false); 202 PS_ASSERT_VECTOR_NON_NULL(tweak, false); 203 PS_ASSERT_VECTOR_SIZE(tweak, chip->cells->n, false); 204 PS_ASSERT_VECTOR_TYPE(tweak, PS_TYPE_U8, false); 205 206 int numCells = tweak->n; // Number of cells 207 208 psVector *mean = psVectorAlloc(numCells, PS_TYPE_F32); // Mean for each cell 209 psVector *meanMask = psVectorAlloc(numCells, PS_TYPE_VECTOR_MASK); // Mask for means 210 psVectorInit(mean, NAN); 211 psVectorInit(meanMask, 0); 212 213 // Mask bits 214 enum { 215 PM_PATTERN_IGNORE = 0x01, // Ignore this cell 216 PM_PATTERN_TWEAK = 0x02, // Tweak this cell 217 PM_PATTERN_ERROR = 0x04, // Error in calculating background 218 PM_PATTERN_ALL = 0xFF, // All causes 219 }; 220 221 // Count number of cells to tweak 222 int numTweak = 0; // Number of cells to tweak 223 int numIgnore = 0; // Number of cells to ignore 224 for (int i = 0; i < numCells; i++) { 225 pmCell *cell = chip->cells->data[i]; // Cell of interest 226 if (!cell || !cell->data_exists || !cell->process || 227 cell->readouts->n == 0 || cell->readouts->n > 1 || !cell->readouts->data[0]) { 228 numIgnore++; 229 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_IGNORE; 230 continue; 231 } 232 if (tweak->data.U8[i]) { 233 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_TWEAK; 234 numTweak++; 235 } 236 } 237 if (numTweak == 0) { 238 // Nothing to do 239 psFree(mean); 240 psFree(meanMask); 241 return true; 242 } 243 if (numTweak >= numCells - numIgnore) { 244 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot pattern-correct all cells within a chip."); 245 psFree(mean); 246 psFree(meanMask); 247 return false; 248 } 249 250 // Measure mean of each cell 251 // This is not really the perfect thing to do, which would be to take a common mean for the set of cells 252 // which aren't being tweaked (because some cells will be heavily masked, so shouldn't be weighted the 253 // same as pure cells), but it's simple and fast. 254 psStats *bgStats = psStatsAlloc(bgStat); // Statistics on background 255 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 256 for (int i = 0; i < numCells; i++) { 257 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) { 258 continue; 259 } 260 pmCell *cell = chip->cells->data[i]; // Cell of interest 261 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 262 263 psStatsInit(bgStats); 264 #if 1 265 if (!psImageBackground(bgStats, NULL, ro->image, ro->mask, maskVal, rng)) { 266 psWarning("Unable to measure background for cell %d\n", i); 267 psErrorClear(); 268 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR; 269 continue; 270 } 271 #else 272 if (!psImageStats(bgStats, ro->image, ro->mask, maskVal)) { 273 psWarning("Unable to measure background for cell %d\n", i); 274 psErrorClear(); 275 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR; 276 continue; 277 } 278 #endif 279 mean->data.F32[i] = psStatsGetValue(bgStats, bgStat); 280 if (!isfinite(mean->data.F32[i])) { 281 psWarning("Non-finite background for cell %d\n", i); 282 psErrorClear(); 283 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR; 284 continue; 285 } 286 } 287 psFree(bgStats); 288 psFree(rng); 289 290 psStats *cellStats = psStatsAlloc(cellStat); // Statistics on cells 291 if (!psVectorStats(cellStats, mean, NULL, meanMask, PM_PATTERN_ALL)) { 292 psError(PS_ERR_UNKNOWN, false, "Unable to calculate mean cell background."); 293 psFree(mean); 294 psFree(meanMask); 295 psFree(cellStats); 296 return false; 297 } 298 299 float background = psStatsGetValue(cellStats, cellStat); // Background value for chip 300 psFree(cellStats); 301 if (!isfinite(background)) { 302 psError(PS_ERR_UNKNOWN, false, "Non-finite mean cell background."); 303 psFree(mean); 304 psFree(meanMask); 305 return false; 306 } 307 308 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Mean chip background is %f", background); 309 310 for (int i = 0; i < numCells; i++) { 311 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) { 312 continue; 313 } 314 if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_TWEAK)) { 315 continue; 316 } 317 pmCell *cell = chip->cells->data[i]; // Cell of interest 318 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 319 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_ERROR) { 320 psImageInit(ro->image, NAN); 321 psBinaryOp(ro->mask, ro->mask, "|", psScalarAlloc(maskBad, PS_TYPE_IMAGE_MASK)); 322 psMetadataAddF32(ro->analysis, PS_LIST_TAIL, PM_PATTERN_CELL_CORRECTION, PS_META_REPLACE, 323 "Pattern cell correction solution", NAN); 324 continue; 325 } 326 float correction = background - mean->data.F32[i]; // Correction to apply 327 const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell 328 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Correcting background of cell %s by %f", 329 cellName, correction); 330 psBinaryOp(ro->image, ro->image, "+", psScalarAlloc(correction, PS_TYPE_F32)); 331 psMetadataAddF32(ro->analysis, PS_LIST_TAIL, PM_PATTERN_CELL_CORRECTION, PS_META_REPLACE, 332 "Pattern cell correction solution", correction); 333 } 334 335 psFree(mean); 336 psFree(meanMask); 337 338 return true; 339 } 340 341 bool pmPatternCellApply(pmReadout *ro, psImageMaskType maskBad) 342 { 343 PM_ASSERT_READOUT_NON_NULL(ro, false); 344 PM_ASSERT_READOUT_IMAGE(ro, false); 345 346 bool mdok; // Status of MD lookup 347 float corr = psMetadataLookupF32(&mdok, ro->analysis, PM_PATTERN_CELL_CORRECTION); // Correction to apply 348 if (!mdok) { 349 // No correction to apply 350 return true; 351 } 352 353 psImage *image = ro->image, *mask = ro->mask; // Image and mask of interest 354 int numCols = image->numCols, numRows = image->numRows; // Size of image 355 356 if (!isfinite(corr)) { 357 for (int y = 0; y < numRows; y++) { 358 for (int x = 0; x < numCols; x++) { 359 image->data.F32[y][x] = NAN; 360 } 361 } 362 if (mask) { 363 for (int y = 0; y < numRows; y++) { 364 for (int x = 0; x < numCols; x++) { 365 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskBad; 366 } 367 } 368 } 369 } else { 370 for (int y = 0; y < numRows; y++) { 371 for (int x = 0; x < numCols; x++) { 372 image->data.F32[y][x] += corr; 373 } 374 } 375 } 376 377 return true; 378 } 379 380
Note:
See TracChangeset
for help on using the changeset viewer.
