Changeset 41892 for trunk/psModules/src/astrom/pmAstrometryObjects.c
- Timestamp:
- Nov 4, 2021, 6:05:18 PM (5 years ago)
- Location:
- trunk/psModules
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/astrom/pmAstrometryObjects.c (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
-
trunk/psModules/src/astrom/pmAstrometryObjects.c
r41493 r41892 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 … … 339 340 psVector *yResGood = psVectorAllocEmpty (match->n, PS_TYPE_F32); 340 341 342 // we measure the stdev of the median residual in NxN bins. 343 // use only valid (not NAN) measurements 344 psVector *xPosValid = psVectorAllocEmpty (match->n, PS_TYPE_F32); 345 psVector *yPosValid = psVectorAllocEmpty (match->n, PS_TYPE_F32); 346 psVector *xResValid = psVectorAllocEmpty (match->n, PS_TYPE_F32); 347 psVector *yResValid = psVectorAllocEmpty (match->n, PS_TYPE_F32); 348 341 349 for (int i = 0; i < match->n; i++) { 342 350 if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; … … 344 352 pmAstromObj *rawStar = raw->data[pair->raw]; 345 353 if (!isfinite(rawStar->dMag)) continue; 354 355 bool isValid = true; 356 isValid = isValid & isfinite (x->data.F32[i]); 357 isValid = isValid & isfinite (y->data.F32[i]); 358 isValid = isValid & isfinite (xRes->data.F32[i]); 359 isValid = isValid & isfinite (yRes->data.F32[i]); 360 if (isValid) { 361 psVectorAppend (xPosValid, x->data.F32[i]); 362 psVectorAppend (yPosValid, y->data.F32[i]); 363 psVectorAppend (xResValid, xRes->data.F32[i]); 364 psVectorAppend (yResValid, yRes->data.F32[i]); 365 } 366 367 // for the systematic error, use only high S/N stars 346 368 if (rawStar->dMag > 0.02) continue; 347 369 … … 369 391 results->dXsys = results->dYsys = NAN; 370 392 results->dXrange = results->dYrange = NAN; 393 results->dXstdev = results->dYstdev = NAN; 371 394 } else { 372 395 results->dXsys = psVectorSystematicError (xResGood, xErr, 0.05); … … 375 398 results->dXrange = pmAstromVectorRange (xResGood, 0.1, 0.9, results->xStats->clippedStdev); 376 399 results->dYrange = pmAstromVectorRange (yResGood, 0.1, 0.9, results->yStats->clippedStdev); 377 } 378 379 psTrace ("psModules.astrom", 3, "dXsys: %f, dXrange: %f\n", results->dXsys, results->dXrange); 380 psTrace ("psModules.astrom", 3, "dYsys: %f, dYrange: %f\n", results->dYsys, results->dYrange); 400 401 results->dXstdev = pmAstrom2DSystematics (xPosValid, yPosValid, xResValid); 402 results->dYstdev = pmAstrom2DSystematics (xPosValid, yPosValid, yResValid); 403 } 404 405 psTrace ("psModules.astrom", 3, "dXsys: %f, dXrange: %f, dXstdev: %f\n", results->dXsys, results->dXrange, results->dXstdev); 406 psTrace ("psModules.astrom", 3, "dYsys: %f, dYrange: %f, dYstdev: %f\n", results->dYsys, results->dYrange, results->dYstdev); 381 407 382 408 psFree (xErr); … … 386 412 psFree (xResGood); 387 413 psFree (yResGood); 414 psFree (xPosValid); 415 psFree (yPosValid); 416 psFree (xResValid); 417 psFree (yResValid); 388 418 389 419 psFree (x); … … 395 425 396 426 return (results); 427 } 428 429 # define VAL_COUNT 9.0 430 # define MIN_COUNT 5.0 431 432 float pmAstrom2DSystematics (psVector *xPos, psVector *yPos, psVector *value) { 433 434 // pre-filter the values to ensure no NANs, other invalid 435 if (xPos->n < VAL_COUNT*2*2) { 436 return NAN; 437 } 438 439 // generate a grid covering the full range of x,y and measure the median value in each 440 // grid cell. calculate the stdev of those median values. 441 442 // VAL_COUNT (9) is the (min) goal density, but a single cell may have only MIN_COUNT (7) 443 // we have N points. require a min of 9 pts per cell (configurable?). grid is square. 444 // Ncell*Ncell*9 = Npts, Ncell = MIN(sqrt(Npts/9), 5) 445 446 int Ncell = PS_MIN(sqrt((float)(xPos->n / VAL_COUNT)), 2); // have to at least have a 2x2 grid 447 448 // find the range of x,y values 449 float xMin = 1e9, xMax = -1e9, yMin = 1e9, yMax = 1e9; 450 for (int i = 0; i < xPos->n; i++) { 451 xMin = PS_MIN(xPos->data.F32[i],xMin); 452 xMax = PS_MAX(xPos->data.F32[i],xMax); 453 yMin = PS_MIN(yPos->data.F32[i],yMin); 454 yMax = PS_MAX(yPos->data.F32[i],yMax); 455 } 456 457 float xStep = Ncell / (xMax - xMin); 458 float yStep = Ncell / (yMax - yMin); 459 460 if (isnan(xStep)) { 461 return NAN; 462 } 463 if (isnan(yStep)) { 464 return NAN; 465 } 466 467 psArray *xBin = psArrayAlloc (Ncell); 468 for (int ix = 0; ix < Ncell; ix++) { 469 psArray *yBin = psArrayAlloc (Ncell); 470 xBin->data[ix] = yBin; 471 for (int iy = 0; iy < Ncell; iy++) { 472 yBin->data[iy] = psVectorAllocEmpty(128, PS_TYPE_F32); 473 } 474 } 475 476 // xValue = ix/xStep + xMin -> ix = (xValue - xMin) * xStep; 477 478 for (int i = 0; i < xPos->n; i++) { 479 int ix = PS_MIN(PS_MAX(0, (xPos->data.F32[i] - xMin) * xStep), Ncell - 1); 480 int iy = PS_MIN(PS_MAX(0, (yPos->data.F32[i] - yMin) * yStep), Ncell - 1); 481 482 psArray *yBin = xBin->data[ix]; 483 psVector *Bin = yBin->data[iy]; 484 485 psVectorAppend(Bin, value->data.F32[i]); 486 } 487 488 psVector *sample = psVectorAllocEmpty (Ncell*Ncell, PS_TYPE_F32); 489 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 490 491 // calculate the median for each vector and save on a vector 492 for (int ix = 0; ix < Ncell; ix++) { 493 psArray *yBin = xBin->data[ix]; 494 for (int iy = 0; iy < Ncell; iy++) { 495 psVector *Bin = yBin->data[iy]; 496 if (Bin->n < MIN_COUNT) { continue; } 497 498 // psVectorStats resets stats so we can call this repeatedly 499 psVectorStats (stats, Bin, NULL, NULL, 0); 500 if (isfinite(stats->sampleMedian)) { 501 psVectorAppend (sample, stats->sampleMedian); 502 } 503 } 504 } 505 506 stats->options = PS_STAT_SAMPLE_STDEV; 507 psVectorStats (stats, sample, NULL, NULL, 0); 508 float result = stats->sampleStdev; 509 510 if (!isfinite(stats->sampleStdev)) { 511 fprintf (stderr, "*** bad solution ***\n"); 512 } 513 514 // NOTE: the elements of xBin are freed automatically, which extends down to the vectors 515 psFree (xBin); 516 psFree (stats); 517 psFree (sample); 518 519 return result; 397 520 } 398 521
Note:
See TracChangeset
for help on using the changeset viewer.
