Changeset 35769 for trunk/psphot/src/psphotModelBackground.c
- Timestamp:
- Jul 3, 2013, 2:43:13 PM (13 years ago)
- Location:
- trunk/psphot
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20130509/psphot (added) merged: 35594,35614,35630-35634,35640-35641,35650-35652,35654-35655,35659,35661,35701,35751
- Property svn:mergeinfo changed
-
trunk/psphot/src
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20130509/psphot/src (added) merged: 35594,35614,35630-35634,35640,35651,35654,35659,35661,35751
- Property svn:mergeinfo changed
-
trunk/psphot/src/psphotModelBackground.c
r34528 r35769 28 28 } 29 29 30 // track background cell failures for log reporting purposes 31 static int nFailures = 0; 30 32 31 33 // Generate the background model … … 33 35 // linear interpolation to generate full-scale model 34 36 // 35 // NOTE that the 'analysis' metedata pass in here is used to store the binning information.37 // NOTE that the 'analysis' metedata passed in here is used to store the binning information. 36 38 // This may be the analysis for this readout, but it may be the analysis for the pmFPAfile 37 39 // corresponding to the model. Other information about the background model is saved on the … … 109 111 110 112 const psStatsOptions statsOption = statsOptionLocation | statsOptionWidth; 111 psStats *stats = psStatsAlloc (statsOption);113 psStats *statsDefaults = psStatsAlloc (statsOption); 112 114 113 115 // set range for old-version of sky statistic 114 116 if (statsOptionLocation & PS_STAT_ROBUST_QUARTILE) { 115 stats ->min = 0.25;116 stats ->max = 0.75;117 statsDefaults->min = 0.25; 118 statsDefaults->max = 0.75; 117 119 } 118 120 119 121 // set user-option for number of pixels per region 120 stats ->nSubsample = psMetadataLookupF32 (&status, recipe, "IMSTATS_NPIX");122 statsDefaults->nSubsample = psMetadataLookupF32 (&status, recipe, "IMSTATS_NPIX"); 121 123 if (!status) { 122 stats ->nSubsample = 1000;124 statsDefaults->nSubsample = 1000; 123 125 } 124 126 125 127 // optionally set the binsize 126 stats ->binsize = psMetadataLookupF32 (&status, recipe, "SKY_HISTOGRAM_BINS");128 statsDefaults->binsize = psMetadataLookupF32 (&status, recipe, "SKY_HISTOGRAM_BINS"); 127 129 if (status) { 128 stats ->options |= PS_STAT_USE_BINSIZE;130 statsDefaults->options |= PS_STAT_USE_BINSIZE; 129 131 } 130 132 131 133 // optionally set the sigma clipping 132 stats ->clipSigma = psMetadataLookupF32 (&status, recipe, "SKY_CLIP_SIGMA");134 statsDefaults->clipSigma = psMetadataLookupF32 (&status, recipe, "SKY_CLIP_SIGMA"); 133 135 if (!status) { 134 if (stats ->options & PS_STAT_FITTED_MEAN) {135 stats ->clipSigma = 1.0;136 if (statsDefaults->options & PS_STAT_FITTED_MEAN) { 137 statsDefaults->clipSigma = 1.0; 136 138 } else { 137 stats ->clipSigma = 3.0;139 statsDefaults->clipSigma = 3.0; 138 140 } 139 141 } 140 141 // stats is not initialized by psStats??? use this to save the input options142 // XXX re-work this to use the new psStatsInit function143 psStats *statsDefaults = psStatsAlloc (statsOption);144 *statsDefaults = *stats;145 142 146 143 // we save the binning structure for use in psphotMagnitudes … … 154 151 155 152 // XXXX we can thread this here by running blocks in parallel 156 157 int nFailures = 0;158 153 psImageBackgroundInit(); 154 nFailures = 0; // reset for this pass 159 155 160 156 // we have Nx * Ny model points, but we can use a window which is larger (or smaller) than … … 163 159 164 160 // measure clipped median for subimages 165 psRegion ruffRegion = psRegionSet (0,0,0,0);166 psRegion fineRegion = psRegionSet (0,0,0,0);167 161 for (int iy = 0; iy < model->numRows; iy++) { 168 162 for (int ix = 0; ix < model->numCols; ix++) { 169 170 // convert the ruff grid cell to the equivalent fine grid cell 171 ruffRegion = psRegionSet (ix + 0.5 - 0.5*dXsample, ix + 0.5 + 0.5*dXsample, 172 iy + 0.5 - 0.5*dYsample, iy + 0.5 + 0.5*dYsample); 173 fineRegion = psImageBinningSetFineRegion (binning, ruffRegion); 174 fineRegion = psRegionForImage (image, fineRegion); 175 176 psImage *subset = psImageSubset (image, fineRegion); 177 if (!subset->numCols || !subset->numRows) { 178 psFree (subset); 179 continue; 163 164 // allocate a job -- if threads are not defined, this just runs the job 165 psThreadJob *job = psThreadJobAlloc ("PSPHOT_MODEL_BACKGROUND"); 166 167 psArrayAdd(job->args, 1, image); 168 psArrayAdd(job->args, 1, mask); 169 psArrayAdd(job->args, 1, binning); 170 psArrayAdd(job->args, 1, rng); 171 psArrayAdd(job->args, 1, statsDefaults); 172 173 psArrayAdd(job->args, 1, modelData); 174 psArrayAdd(job->args, 1, modelStdevData); 175 176 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK); 177 178 PS_ARRAY_ADD_SCALAR(job->args, ix, PS_TYPE_S32); 179 PS_ARRAY_ADD_SCALAR(job->args, iy, PS_TYPE_S32); 180 181 PS_ARRAY_ADD_SCALAR(job->args, dXsample, PS_TYPE_F32); 182 PS_ARRAY_ADD_SCALAR(job->args, dYsample, PS_TYPE_F32); 183 184 PS_ARRAY_ADD_SCALAR(job->args, statsOptionLocation, PS_TYPE_S32); 185 PS_ARRAY_ADD_SCALAR(job->args, statsOptionWidth, PS_TYPE_S32); 186 187 PS_ARRAY_ADD_SCALAR(job->args, NAN, PS_TYPE_F32); // this is used as a return value for dQvalue 188 189 # if (1) 190 if (!psThreadJobAddPending(job)) { 191 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 192 return NULL; 180 193 } 181 psImage *submask = psImageSubset (mask, fineRegion); 182 183 // reset the default values 184 *stats = *statsDefaults; 185 186 // Use the selected background statistic for the first pass 187 // If it fails, fall back on the "ROBUST_MEDIAN" version 188 // If both fail, set the pixel to NAN and (below) interpolate 189 // XXX psImageBackground will probably be renamed psImageStats 190 // XXX don't bother trying if there are no valid pixels... 191 192 psVector *sample = NULL; 193 194 // turn on stats tracing in desired cells 195 # if (0) 196 psMetadata *plots = psMetadataLookupPtr (&status, recipe, "DIAGNOSTIC.PLOTS"); 197 assert (plots); 198 199 int xPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.X"); 200 assert (status); 201 int yPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.Y"); 202 assert (status); 203 204 bool gotX = (xPlot < 0) || (xPlot == ix); 205 bool gotY = (yPlot < 0) || (yPlot == iy); 206 207 if (gotX && gotY) { 208 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 6); 209 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 6); 210 } else { 211 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 0); 212 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 0); 194 # else 195 if (!psphotModelBackground_Threaded(job)) { 196 psError(PS_ERR_UNKNOWN, false, "Failure to model background."); 197 return NULL; 213 198 } 214 # endif 215 216 if (psImageBackground(stats, &sample, subset, submask, maskVal, rng)) { 217 if (stats->options & PS_STAT_ROBUST_QUARTILE) { 218 modelData[iy][ix] = stats->robustMedian; 219 } else { 220 modelData[iy][ix] = psStatsGetValue(stats, statsOptionLocation); 221 } 222 modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth); 223 // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian); 224 psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian); 225 226 // supply sample to plotting routing 227 psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample); 228 } else { 229 psStatsOptions currentOptions = stats->options; 230 stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV; 231 if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) { 232 if ((nFailures < 3) || (nFailures % 100 == 0)) { 233 psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for " 234 "(%dx%d, (row0,col0) = (%d,%d)", 235 subset->numRows, subset->numCols, subset->row0, subset->col0); 236 } 237 nFailures ++; 238 modelData[iy][ix] = modelStdevData[iy][ix] = NAN; 239 } else { 240 modelData[iy][ix] = psStatsGetValue (stats, PS_STAT_ROBUST_MEDIAN); 241 modelStdevData[iy][ix] = psStatsGetValue(stats, PS_STAT_ROBUST_STDEV); 242 243 // supply sample to plotting routing 244 psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample); 245 } 246 // drop errors caused by psImageBackground failures 247 // XXX we probably should trap and exit on serious failures 248 psErrorClear(); 249 stats->options = currentOptions; 250 } 251 psFree(sample); 252 modelData[iy][ix] += SKY_BIAS; 253 psFree (subset); 254 psFree (submask); 199 if (job->args->n < 1) { 200 fprintf (stderr, "error with job\n"); 201 } else { 202 psScalar *scalar = job->args->data[14]; 203 float dQvalue = scalar->data.F32; 204 psVectorAppend (dQ, dQvalue); 205 } 206 psFree(job); 207 # endif 255 208 } 209 } 210 211 // wait for the threads to finish and manage results 212 if (!psThreadPoolWait (false, true)) { 213 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 214 return NULL; 215 } 216 217 // we have only supplied one type of job, so we can assume the types here 218 psThreadJob *job = NULL; 219 while ((job = psThreadJobGetDone()) != NULL) { 220 if (job->args->n < 1) { 221 fprintf (stderr, "error with job\n"); 222 } else { 223 psScalar *scalar = job->args->data[14]; 224 float dQvalue = scalar->data.F32; 225 psVectorAppend (dQ, dQvalue); 226 } 227 psFree(job); 256 228 } 257 229 … … 302 274 if (Count == 0) { 303 275 psError (PSPHOT_ERR_DATA, true, "failed to build background image"); 304 psFree(stats);305 276 psFree(statsDefaults); 306 277 psFree(binning); … … 318 289 modelData[iy][ix] = Value; 319 290 modelStdevData[iy][ix] = ValueStdev; 291 } 292 } 293 294 // apply artificial offset if desired 295 for (int iy = 0; iy < model->numRows; iy++) { 296 for (int ix = 0; ix < model->numCols; ix++) { 297 modelData[iy][ix] += SKY_BIAS; 320 298 } 321 299 } … … 364 342 psFree(dQ); 365 343 366 psFree(stats);367 344 psFree(statsDefaults); 368 345 psFree(binning); … … 433 410 return true; 434 411 } 412 413 bool psphotModelBackground_Threaded (psThreadJob *job) { 414 415 psImage *image = job->args->data[0]; 416 psImage *mask = job->args->data[1]; 417 418 psImageBinning *binning = job->args->data[2]; 419 420 psRandom *rng = job->args->data[3]; 421 psStats *statsDefaults = job->args->data[4]; 422 423 psF32 **modelData = job->args->data[5]; 424 psF32 **modelStdevData = job->args->data[6]; 425 426 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[7],PS_TYPE_IMAGE_MASK_DATA); 427 428 int ix = PS_SCALAR_VALUE(job->args->data[8],S32); 429 int iy = PS_SCALAR_VALUE(job->args->data[9],S32); 430 431 float dXsample = PS_SCALAR_VALUE(job->args->data[10],F32); 432 float dYsample = PS_SCALAR_VALUE(job->args->data[11],F32); 433 434 psStatsOptions statsOptionLocation = PS_SCALAR_VALUE(job->args->data[12],S32); 435 psStatsOptions statsOptionWidth = PS_SCALAR_VALUE(job->args->data[13],S32); 436 437 // convert the ruff grid cell to the equivalent fine grid cell 438 psRegion ruffRegion = psRegionSet (ix + 0.5 - 0.5*dXsample, ix + 0.5 + 0.5*dXsample, iy + 0.5 - 0.5*dYsample, iy + 0.5 + 0.5*dYsample); 439 psRegion fineRegion = psImageBinningSetFineRegion (binning, ruffRegion); 440 fineRegion = psRegionForImage (image, fineRegion); 441 442 psImage *subset = psImageSubset (image, fineRegion); 443 if (!subset->numCols || !subset->numRows) { 444 psFree (subset); 445 return false; // XXX do we / should we fail on this? 446 } 447 psImage *submask = psImageSubset (mask, fineRegion); 448 449 psStats *stats = psStatsAlloc (PS_STAT_NONE); 450 *stats = *statsDefaults; 451 452 // Use the selected background statistic for the first pass 453 // If it fails, fall back on the "ROBUST_MEDIAN" version 454 // If both fail, set the pixel to NAN and (later) interpolate 455 456 psVector *sample = NULL; 457 float dQvalue = NAN; 458 459 if (psImageBackground(stats, &sample, subset, submask, maskVal, rng)) { 460 if (stats->options & PS_STAT_ROBUST_QUARTILE) { 461 modelData[iy][ix] = stats->robustMedian; 462 } else { 463 modelData[iy][ix] = psStatsGetValue(stats, statsOptionLocation); 464 } 465 modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth); 466 467 // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian); 468 // XXX this operation is not thread safe -- move out somehow... 469 // psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian); 470 dQvalue = stats->robustUQ + stats->robustLQ - 2*stats->robustMedian; 471 // return dQvalue to main thread 472 473 // supply sample to plotting routing 474 // only allow in a non-threaded context -- can plot more than one cell 475 // psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample); 476 } else { 477 // psStatsOptions currentOptions = stats->options; 478 stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV; 479 if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) { 480 if ((nFailures < 3) || (nFailures % 100 == 0)) { 481 psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for " 482 "(%dx%d, (row0,col0) = (%d,%d)", 483 subset->numRows, subset->numCols, subset->row0, subset->col0); 484 } 485 nFailures ++; // static 486 modelData[iy][ix] = modelStdevData[iy][ix] = NAN; 487 } else { 488 modelData[iy][ix] = psStatsGetValue (stats, PS_STAT_ROBUST_MEDIAN); 489 modelStdevData[iy][ix] = psStatsGetValue(stats, PS_STAT_ROBUST_STDEV); 490 491 // supply sample to plotting routing 492 // only allow in a non-threaded context -- can plot more than one cell 493 // psphotDiagnosticPlots (config, "IMAGE.BACKGROUND.CELL.HISTOGRAM", ix, iy, modelData[iy][ix], modelStdevData[iy][ix], sample); 494 } 495 // drop errors caused by psImageBackground failures 496 // NOTE : psStats raises errors when it cannot find a solution; this 497 // probably should not be errors but exit stats info only, but c'est la code 498 // XXX we probably should trap and exit on serious failures 499 psErrorClear(); 500 // stats->options = currentOptions; // this is not needed (set by init above) 501 } 502 psFree (stats); 503 psFree (sample); 504 psFree (subset); 505 psFree (submask); 506 507 // return the dQvalue to the calling thread 508 psScalar *scalar = job->args->data[14]; 509 scalar->data.F32 = dQvalue; 510 511 return true; 512 } 513 514 // code for in-line plotting from above 515 // turn on stats tracing in desired cells 516 // XXX this code may need to be re-worked for a threaded context 517 # if (0) 518 psMetadata *plots = psMetadataLookupPtr (&status, recipe, "DIAGNOSTIC.PLOTS"); 519 assert (plots); 520 521 int xPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.X"); 522 assert (status); 523 int yPlot = psMetadataLookupS32 (&status, plots, "IMAGE.BACKGROUND.CELL.HISTOGRAM.Y"); 524 assert (status); 525 526 bool gotX = (xPlot < 0) || (xPlot == ix); 527 bool gotY = (yPlot < 0) || (yPlot == iy); 528 529 if (gotX && gotY) { 530 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 6); 531 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 6); 532 } else { 533 (void) psTraceSetLevel ("psLib.math.vectorFittedStats", 0); 534 (void) psTraceSetLevel ("psLib.math.vectorRobustStats", 0); 535 } 536 # endif
Note:
See TracChangeset
for help on using the changeset viewer.
