Changeset 41813 for branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.c
- Timestamp:
- Sep 27, 2021, 6:31:19 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.c
r41493 r41813 40 40 // XXX this is defined in pmPSFtry.h, which makes no sense 41 41 float psVectorSystematicError (psVector *residuals, psVector *errors, float clipFraction); 42 float pmAstrom2DSystematics (psVector *xPos, psVector *yPos, psVector *value); 42 43 43 44 #define PM_ASTROMETRYOBJECTS_DEBUG 1 … … 375 376 results->dXrange = pmAstromVectorRange (xResGood, 0.1, 0.9, results->xStats->clippedStdev); 376 377 results->dYrange = pmAstromVectorRange (yResGood, 0.1, 0.9, results->yStats->clippedStdev); 378 379 results->dXstdev = pmAstrom2DSystematics (xFit, yFit, xRes); 380 results->dYstdev = pmAstrom2DSystematics (xFit, yFit, yRes); 377 381 } 378 382 … … 395 399 396 400 return (results); 401 } 402 403 # define VAL_COUNT 9.0 404 # define MIN_COUNT 7.0 405 406 float pmAstrom2DSystematics (psVector *xPos, psVector *yPos, psVector *value) { 407 408 // pre-filter the values to ensure no NANs, other invalid 409 if (xPos->n < VAL_COUNT*2*2) { return NAN; } 410 411 // generate a grid covering the full range of x,y and measure the median value in each 412 // grid cell. calculate the stdev of those median values. 413 414 // VAL_COUNT (9) is the (min) goal density, but a single cell may have only MIN_COUNT (7) 415 // we have N points. require a min of 9 pts per cell (configurable?). grid is square. 416 // Ncell*Ncell*9 = Npts, Ncell = MIN(sqrt(Npts/9), 5) 417 418 int Ncell = PS_MIN(sqrt((float)(xPos->n / VAL_COUNT)), 2); // have to at least have a 2x2 grid 419 420 // find the range of x,y values 421 float xMin = 1e9, xMax = -1e9, yMin = 1e9, yMax = 1e9; 422 for (int i = 0; i < xPos->n; i++) { 423 xMin = PS_MIN(xPos->data.F32[i],xMin); 424 xMax = PS_MAX(xPos->data.F32[i],xMax); 425 yMin = PS_MIN(yPos->data.F32[i],yMin); 426 yMax = PS_MAX(yPos->data.F32[i],yMax); 427 } 428 429 float xStep = Ncell / (xMax - xMin); 430 float yStep = Ncell / (yMax - yMin); 431 432 if (isnan(xStep)) { return NAN; } 433 if (isnan(yStep)) { return NAN; } 434 435 psArray *xBin = psArrayAlloc (Ncell); 436 for (int ix = 0; ix < Ncell; ix++) { 437 psArray *yBin = psArrayAlloc (Ncell); 438 xBin->data[ix] = yBin; 439 for (int iy = 0; iy < Ncell; iy++) { 440 yBin->data[iy] = psVectorAllocEmpty(128, PS_TYPE_F32); 441 } 442 } 443 444 // xValue = ix/xStep + xMin -> ix = (xValue - xMin) * xStep; 445 446 for (int i = 0; i < xPos->n; i++) { 447 int ix = PS_MIN(PS_MAX(0, (xPos->data.F32[i] - xMin) * xStep), Ncell - 1); 448 int iy = PS_MIN(PS_MAX(0, (yPos->data.F32[i] - yMin) * yStep), Ncell - 1); 449 450 psArray *yBin = xBin->data[ix]; 451 psVector *Bin = yBin->data[iy]; 452 453 psVectorAppend(Bin, value->data.F32[i]); 454 } 455 456 psVector *sample = psVectorAllocEmpty (Ncell*Ncell, PS_TYPE_F32); 457 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 458 459 // calculate the median for each vector and save on a vector 460 for (int ix = 0; ix < Ncell; ix++) { 461 psArray *yBin = xBin->data[ix]; 462 for (int iy = 0; iy < Ncell; iy++) { 463 psVector *Bin = yBin->data[iy]; 464 465 // psVectorStats resets stats so we can call this repeatedly 466 psVectorStats (stats, Bin, NULL, NULL, 0); 467 if (isfinite(stats->sampleMedian)) { 468 psVectorAppend (sample, stats->sampleMedian); 469 } 470 } 471 } 472 473 stats->options = PS_STAT_SAMPLE_STDEV; 474 psVectorStats (stats, sample, NULL, NULL, 0); 475 float result = stats->sampleStdev; 476 477 // NOTE: the elements of xBin are freed automatically, which extends down to the vectors 478 psFree (xBin); 479 psFree (stats); 480 psFree (sample); 481 482 return result; 397 483 } 398 484
Note:
See TracChangeset
for help on using the changeset viewer.
