IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 41813


Ignore:
Timestamp:
Sep 27, 2021, 6:31:19 AM (5 years ago)
Author:
eugene
Message:

add function to calculate stdev of median residuals per bin

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-dev-20210817/psModules/src/astrom/pmAstrometryObjects.c

    r41493 r41813  
    4040// XXX this is defined in pmPSFtry.h, which makes no sense
    4141float psVectorSystematicError (psVector *residuals, psVector *errors, float clipFraction);
     42float pmAstrom2DSystematics (psVector *xPos, psVector *yPos, psVector *value);
    4243
    4344#define PM_ASTROMETRYOBJECTS_DEBUG 1
     
    375376      results->dXrange = pmAstromVectorRange (xResGood, 0.1, 0.9, results->xStats->clippedStdev);
    376377      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);
    377381    }
    378382
     
    395399
    396400    return (results);
     401}
     402
     403# define VAL_COUNT 9.0
     404# define MIN_COUNT 7.0
     405
     406float 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;
    397483}
    398484
Note: See TracChangeset for help on using the changeset viewer.