Changeset 42510
- Timestamp:
- Aug 17, 2023, 3:24:45 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20230313/psphot/src/psphotMakeResiduals.c
r42507 r42510 95 95 psVector *yC = psVectorAllocEmpty (100, PS_TYPE_F32); 96 96 97 # define TESTRESID 197 # define TESTRESID 0 98 98 # if (TESTRESID) 99 99 psArray *sourceRawCube = psArrayAllocEmpty (1); … … 101 101 psArray *sourceVarCube = psArrayAllocEmpty (1); 102 102 psArray *sourceMskCube = psArrayAllocEmpty (1); 103 104 psImage *refImage = NULL; 103 105 # endif 104 106 … … 121 123 # if (TESTRESID) 122 124 psImage *tmpImage = psImageCopy(NULL, image, PS_TYPE_F32); 123 psArrayAdd (sourceRawCube, 1, tmpImage); 124 psFree (tmpImage); 125 if (refImage == NULL) { 126 refImage = tmpImage; 127 psArrayAdd (sourceRawCube, 1, tmpImage); 128 } else { 129 if (tmpImage->numCols != refImage->numCols) { 130 fprintf (stderr, "mismatched image sizes (%d : %f, %f)\n", i, model->params->data.F32[PM_PAR_XPOS], model->params->data.F32[PM_PAR_YPOS]); 131 continue; 132 } 133 if (tmpImage->numRows != refImage->numRows) { 134 fprintf (stderr, "mismatched image sizes (%d : %f, %f)\n", i, model->params->data.F32[PM_PAR_XPOS], model->params->data.F32[PM_PAR_YPOS]); 135 continue; 136 } 137 psArrayAdd (sourceRawCube, 1, tmpImage); 138 psFree (tmpImage); 139 } 125 140 # endif 126 141 … … 199 214 psVector *fmasks = psVectorAlloc (input->n, PS_TYPE_VECTOR_MASK); 200 215 201 // statistic to use to determine baseline for clipping202 psStats *fluxClip = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);203 psStats *fluxClipDef = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);204 216 // statistic to use to determine output flux 205 217 // XXX make API to convert statOption for MEAN/MEDIAN in to corresponding STDEV? … … 207 219 psStats *fluxStatsDef = psStatsAlloc (statOption | PS_STAT_SAMPLE_STDEV); 208 220 221 // use this for the IRLS fitting below (defines niter) 222 psStats *statsIRLS = psStatsAlloc(PS_STAT_CLIPPED_MEAN); statsIRLS->clipIter = 10; // max number of iterations 223 psPolynomial2D *polyIRLS = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, 1, 1); 224 209 225 // Use psF64 to minimize overflow problems? 210 226 psImage *A = psImageAlloc(3, 3, PS_TYPE_F64); // Least-squares matrix … … 217 233 218 234 int nGoodPixel = 0; // pixel is off the image 235 236 // skip pixels outside of the requested radius 237 float radius = hypot((ox - 0.5*resid->Ro->numCols), (oy - 0.5*resid->Ro->numRows)); 238 if (radius > radiusMax) { 239 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = 1; 240 continue; 241 } 219 242 220 243 // build the vector of data values for this output pixel … … 268 291 269 292 // measure the robust median to determine a baseline reference value 270 *fluxClip = *fluxClipDef;293 psStats *fluxClip = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 271 294 if (!psVectorStats (fluxClip, fluxes, NULL, fmasks, fmaskVal)) { 272 295 psError(PSPHOT_ERR_CONFIG, false, "Error calculating residual stats"); 296 psFree (fluxClip); 273 297 return false; 274 298 } 275 if (isnan(fluxClip-> robustMedian)) {299 if (isnan(fluxClip->sampleMedian)) { 276 300 resid->Ro->data.F32[oy][ox] = 0.0; 277 301 resid->Rx->data.F32[oy][ox] = 0.0; 278 302 resid->Ry->data.F32[oy][ox] = 0.0; 279 303 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = badMask; 304 psFree (fluxClip); 280 305 continue; 281 306 } 282 307 283 if (fabs(fluxClip-> robustMedian) > 1.5) {284 fprintf (stderr, "warning: %d, %d : residual pixel has funny initial median value: %f\n", ox, oy, fluxClip-> robustMedian);308 if (fabs(fluxClip->sampleMedian) > 1.5) { 309 fprintf (stderr, "warning: %d, %d : residual pixel has funny initial median value: %f\n", ox, oy, fluxClip->sampleMedian); 285 310 } 286 311 … … 288 313 int nKeep = 0; 289 314 for (int i = 0; i < fluxes->n; i++) { 290 float delta = fluxes->data.F32[i] - fluxClip-> robustMedian;315 float delta = fluxes->data.F32[i] - fluxClip->sampleMedian; 291 316 float sigma = sqrt (dfluxes->data.F32[i]); 292 317 float swing = fabs(delta) / sigma; … … 298 323 if (!fmasks->data.PS_TYPE_VECTOR_MASK_DATA[i]) nKeep++; 299 324 } 325 psFree (fluxClip); 300 326 301 327 if (nKeep < 5) { … … 311 337 } 312 338 313 // XXX this test should go at the top of the loop 314 float radius = hypot((ox - 0.5*resid->Ro->numCols), (oy - 0.5*resid->Ro->numRows)); 315 if (radius > radiusMax) { 316 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = 1; 317 continue; 318 } 339 resid->Rx->data.F32[oy][ox] = resid->Ry->data.F32[oy][ox] = 0.0; 319 340 320 341 resid->Ro->data.F32[oy][ox] = psStatsGetValue(fluxStats, statOption); 321 resid->Rx->data.F32[oy][ox] = resid->Ry->data.F32[oy][ox] = 0.0;322 323 342 if (isnan(resid->Ro->data.F32[oy][ox])) { 324 343 resid->Ro->data.F32[oy][ox] = 0.0; 325 resid->Rx->data.F32[oy][ox] = 0.0;326 resid->Ry->data.F32[oy][ox] = 0.0;327 344 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = badMask; 328 345 continue; … … 335 352 assert (SPATIAL_ORDER == 1); 336 353 337 float radius = hypot((ox - 0.5*resid->Ro->numCols), (oy - 0.5*resid->Ro->numRows)); 338 if (radius > radiusMax) { 339 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = 1; 340 continue; 341 } 342 343 psImageInit(A, 0.0); 344 psVectorInit(B, 0.0); 345 for (int i = 0; i < fluxes->n; i++) { 346 if (fmasks->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; 347 B->data.F64[0] += fluxes->data.F32[i]/dfluxes->data.F32[i]; 348 B->data.F64[1] += fluxes->data.F32[i]*xC->data.F32[i]/dfluxes->data.F32[i]; 349 B->data.F64[2] += fluxes->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i]; 350 351 A->data.F64[0][0] += 1.0/dfluxes->data.F32[i]; 352 A->data.F64[1][0] += xC->data.F32[i]/dfluxes->data.F32[i]; 353 A->data.F64[2][0] += yC->data.F32[i]/dfluxes->data.F32[i]; 354 355 A->data.F64[1][1] += PS_SQR(xC->data.F32[i])/dfluxes->data.F32[i]; 356 A->data.F64[2][2] += PS_SQR(yC->data.F32[i])/dfluxes->data.F32[i]; 357 A->data.F64[1][2] += xC->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i]; 358 } 359 360 A->data.F64[0][1] = A->data.F64[1][0]; 361 A->data.F64[0][2] = A->data.F64[2][0]; 362 A->data.F64[2][1] = A->data.F64[1][2]; 363 364 if (!psMatrixGJSolve(A, B)) { 365 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = 1; 366 psWarning("Singular matrix solving for (y,x) = (%d,%d)'s residuals, masking", oy, ox); 367 continue; 368 } 369 370 resid->Ro->data.F32[oy][ox] = B->data.F64[0]; 371 resid->Rx->data.F32[oy][ox] = B->data.F64[1]; 372 resid->Ry->data.F32[oy][ox] = B->data.F64[2]; 373 374 float dRo = sqrt(A->data.F32[0][0]); 375 376 if (fabs(B->data.F64[0]) > 1.5) { 377 fprintf (stderr, "warning: %d, %d : residual pixel has funny fit value: %f\n", ox, oy, B->data.F64[0]); 354 // we have the following vectors to describe this pixel: 355 // fluxes, dfluxes, fmasks, xC, yC 356 357 psVectorIRLSFitPolynomial2D (polyIRLS, statsIRLS, fmasks, fmaskVal, fluxes, dfluxes, xC, yC); 358 359 resid->Ro->data.F32[oy][ox] = polyIRLS->coeff[0][0]; 360 resid->Rx->data.F32[oy][ox] = polyIRLS->coeff[1][0]; 361 resid->Ry->data.F32[oy][ox] = polyIRLS->coeff[0][1]; 362 363 // is the error well-defined? 364 float dRo = polyIRLS->coeffErr[0][0]; 365 366 if (fabs(resid->Ro->data.F32[oy][ox]) > 1.5) { 367 fprintf (stderr, "warning: %d, %d : residual pixel has funny fit value: %f\n", ox, oy, resid->Ro->data.F32[oy][ox]); 378 368 } 379 369 … … 442 432 psFree (fluxStats); 443 433 psFree (fluxStatsDef); 444 psFree (fluxClip);445 psFree (fluxClipDef);446 434 447 435 if (resid != NULL && psTraceGetLevel("psphot") > 5) { … … 453 441 } 454 442 443 psFree (statsIRLS); 444 psFree (polyIRLS); 445 455 446 psf->residuals = resid; 456 447 return (resid != NULL) ? true : false;
Note:
See TracChangeset
for help on using the changeset viewer.
