IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 26224


Ignore:
Timestamp:
Nov 20, 2009, 3:22:59 PM (17 years ago)
Author:
eugene
Message:

add bootstrap-resampling to get zero point error for edge

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20091113/psastro/src/psastroZeroPoint.c

    r26167 r26224  
    3030    // recipe options
    3131    bool byExposure = psMetadataLookupBool (&status, recipe, "ZERO.POINT.BY.EXPOSURE");
    32     bool useMean    = psMetadataLookupBool (&status, recipe, "ZERO.POINT.USE.MEAN");
    33     float edgeFraction = psMetadataLookupF32 (&status, recipe, "ZERO.POINT.EDGE.FRACTION");
    3432
    3533    // select the input data sources
     
    8684                    // calculate dMag for the matched stars just for this readout (well, chip)
    8785                    psMetadata *header = psMetadataLookupMetadata (&status, readout->analysis, "PSASTRO.HEADER");
    88                     psastroZeroPointAnalysis (header, dMag, zeropt, edgeFraction, useMean);
     86                    psastroZeroPointAnalysis (header, dMag, zeropt, recipe);
    8987                    psFree (dMag);
    9088                    dMag = NULL;
     
    9694    if (byExposure) {
    9795        psMetadata *header = psMetadataLookupMetadata (&status, fpa->analysis, "PSASTRO.HEADER");
    98         psastroZeroPointAnalysis (header, dMag, zeropt, edgeFraction, useMean);
     96        psastroZeroPointAnalysis (header, dMag, zeropt, recipe);
    9997        psFree (dMag);
    10098        dMag = NULL;
     
    141139}
    142140
    143 bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, float edgeFraction, bool useMean) {
     141bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, psMetadata *recipe) {
    144142
    145143    // XXX make this depend on the mode?
     
    148146      return false;
    149147    }
     148
     149    bool status;
     150    bool useMean = psMetadataLookupBool (&status, recipe, "ZERO.POINT.USE.MEAN");
    150151
    151152    // the zero point analysis depends on the type of desired statistic.  For comparisons
     
    166167        }
    167168    } else {
    168         stats = psastroStatsPercentile (dMag, edgeFraction);
     169        stats = psastroStatsPercentile (dMag, recipe);
    169170        if (!stats) {
    170171            psError(PS_ERR_UNKNOWN, false, "failure to measure zero point by edge");
     
    233234// return results in stats->sampleMean, sampleStdev
    234235// XXX this is a misuse of psStats -- make our own structure?
    235 psStats *psastroStatsPercentile (psVector *myVector, float flimit) {
     236psStats *psastroStatsPercentile (psVector *myVector, psMetadata *recipe) {
    236237
    237238    // search for the 'blue' edge of the dMag distribution:
    238239    // the distribution is not a normal population, but instead has a broad range with fairly hard edges.
    239240    // construct a histogram and look for the
     241
     242    bool status;
     243    float edgeFraction = psMetadataLookupF32 (&status, recipe, "ZERO.POINT.EDGE.FRACTION");
     244    int edgeSample = psMetadataLookupS32 (&status, recipe, "ZERO.POINT.EDGE.SAMPLE");
     245    float edgeSampleFraction = psMetadataLookupF32 (&status, recipe, "ZERO.POINT.EDGE.SAMPLE.FRACTION");
    240246
    241247    // stats is first used to find the data range
     
    245251    float min = NAN, max = NAN;         // Mimimum and maximum values
    246252
     253    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); 
     254
    247255    // Get the minimum and maximum values
    248256    if (!psVectorStats(stats, myVector, NULL, NULL, 0)) goto escape;
     
    250258    max = stats->max;
    251259    if (isnan(min) || isnan(max)) goto escape;
    252     psTrace("psastro", 6, "Data min/max is (%.2f, %.2f)\n", min, max);
     260    psTrace("psastro", 5, "Data min/max is (%.2f, %.2f)\n", min, max);
    253261
    254262    // If all data points have the same value, then we set the appropriate members of stats and return.
     
    264272    float binSize = MAG_RESOLUTION;
    265273    long numBins = (max - min) / binSize; // Number of bins
    266     psTrace("psastro", 6, "Numbins is %ld\n", numBins);
    267     psTrace("psastro", 6, "Creating a robust histogram from data range (%.2f - %.2f)\n", min, max);
    268 
    269     // Generate the histogram
     274    psTrace("psastro", 5, "Numbins is %ld\n", numBins);
     275    psTrace("psastro", 5, "Creating a robust histogram from data range (%.2f - %.2f)\n", min, max);
     276
     277    // allocate the histogram containers
    270278    histogram = psHistogramAlloc(min, max, numBins);
    271     if (!psVectorHistogram(histogram, myVector, NULL, NULL, 0)) {
    272       // if psVectorHistogram returns false, we have a programming error
    273       psError(PS_ERR_UNKNOWN, false, "Unable to generate histogram for psastroZeroPointAnalysis\n");
    274       psFree(histogram);
    275       psFree(stats);
    276       return NULL;
    277     }
    278     if (psTraceGetLevel("psastro") >= 8) {
    279       PS_VECTOR_PRINT_F32(histogram->bounds);
    280       PS_VECTOR_PRINT_F32(histogram->nums);
    281     }
    282 
    283     // Convert the specific histogram to a cumulative histogram
    284     // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1])
    285279    cumulative = psHistogramAlloc(min, max, numBins);
    286     cumulative->nums->data.F32[0] = histogram->nums->data.F32[0];
    287     for (long i = 1; i < histogram->nums->n; i++) {
    288       cumulative->nums->data.F32[i] = cumulative->nums->data.F32[i-1] + histogram->nums->data.F32[i];
    289       cumulative->bounds->data.F32[i-1] = histogram->bounds->data.F32[i];
    290     }
    291     if (psTraceGetLevel("psastro") >= 8) {
    292       PS_VECTOR_PRINT_F32(cumulative->bounds);
    293       PS_VECTOR_PRINT_F32(cumulative->nums);
    294     }
    295 
    296     // Find the bin which contains the first data point above the limit
    297     long totalDataPoints = cumulative->nums->data.F32[numBins - 1];
    298     psTrace("psastro", 6, "Total data points is %ld\n", totalDataPoints);
    299 
    300     // find bin which is the lower bound of the limit value (value[bin] < f < value[bin+1]
    301     long bin;
    302     PS_BIN_FOR_VALUE(bin, cumulative->nums, flimit * totalDataPoints, 0);
    303     psTrace("psastro", 6, "The bin is %ld (%.2f to %.2f)\n", bin, cumulative->bounds->data.F32[bin], cumulative->bounds->data.F32[bin+1]);
    304 
    305     // Linear interpolation to the limit value in bin units
    306     float value;
    307     PS_BIN_INTERPOLATE (value, cumulative->nums, cumulative->bounds, bin, totalDataPoints * flimit);
    308     psTrace("psastro", 6, "limit value is %f\n", value);
    309 
    310     stats->clippedMean = value;
    311     stats->clippedStdev = 0.0; // XXX derive correct error value
     280
     281    // find the mean value:
     282    stats->clippedMean = psastroStatsPercentileValue (histogram, cumulative, myVector, edgeFraction);
     283
     284    int nSubset = myVector->n * edgeSampleFraction;
     285    psVector *subset = psVectorAlloc (nSubset, PS_TYPE_F32);
     286
     287    float Sum = 0.0;
     288    float S2 = 0.0;
     289    for (int i = 0; i < edgeSample; i++) {
     290       
     291        // generate the subset vector
     292        for (long i = 0; i < nSubset; i++) {
     293            double frnd = psRandomUniform(rng);
     294            int entry = PS_MIN(myVector->n - 1, PS_MAX(0, myVector->n * frnd));
     295
     296            subset->data.F32[i] = myVector->data.F32[entry];
     297        }
     298
     299        float value = psastroStatsPercentileValue (histogram, cumulative, subset, edgeFraction);
     300
     301        Sum += value;
     302        S2 += value*value;
     303    }
     304    psTrace("psastro", 6, "subset stats: Sum: %f, S2: %f, Npts: %d\n", Sum, S2, edgeSample);
     305
     306    stats->clippedStdev = sqrt(S2 / edgeSample - PS_SQR(Sum/edgeSample));
     307    psTrace("psastro", 5, "percentile stats %f +/- %f\n", stats->clippedMean, stats->clippedStdev);
     308
    312309    stats->results |= PS_STAT_CLIPPED_MEAN;
    313310    stats->results |= PS_STAT_CLIPPED_STDEV;
     
    317314    psFree(histogram);
    318315    psFree(cumulative);
     316    psFree(subset);
     317    psFree(rng);
    319318    return stats;
    320319
     
    332331}
    333332
     333
     334// measure the edge of the sample at flimit
     335// return results in stats->sampleMean, sampleStdev
     336// XXX this is a misuse of psStats -- make our own structure?
     337float psastroStatsPercentileValue (psHistogram *histogram, psHistogram *cumulative, psVector *myVector, float flimit) {
     338
     339    // need to initialize the histogram on each pass
     340    psVectorInit (histogram->nums, 0);
     341    if (!psVectorHistogram(histogram, myVector, NULL, NULL, 0)) {
     342        // if psVectorHistogram returns false, we have a programming error
     343        psAbort ("Unable to generate histogram for psastroZeroPointAnalysis");
     344    }
     345    if (psTraceGetLevel("psastro") >= 8) {
     346        PS_VECTOR_PRINT_F32(histogram->bounds);
     347        PS_VECTOR_PRINT_F32(histogram->nums);
     348    }
     349
     350    // Convert the specific histogram to a cumulative histogram
     351    // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1])
     352    cumulative->nums->data.F32[0] = histogram->nums->data.F32[0];
     353    for (long i = 1; i < histogram->nums->n; i++) {
     354        cumulative->nums->data.F32[i] = cumulative->nums->data.F32[i-1] + histogram->nums->data.F32[i];
     355        cumulative->bounds->data.F32[i-1] = histogram->bounds->data.F32[i];
     356    }
     357    if (psTraceGetLevel("psastro") >= 8) {
     358        PS_VECTOR_PRINT_F32(cumulative->bounds);
     359        PS_VECTOR_PRINT_F32(cumulative->nums);
     360    }
     361
     362    // Find the bin which contains the first data point above the limit
     363    long numBins = cumulative->nums->n;
     364    long totalDataPoints = cumulative->nums->data.F32[numBins - 1];
     365    psTrace("psastro", 6, "Total data points is %ld\n", totalDataPoints);
     366
     367    // find bin which is the lower bound of the limit value (value[bin] < f < value[bin+1]
     368    long bin;
     369    PS_BIN_FOR_VALUE(bin, cumulative->nums, flimit * totalDataPoints, 0);
     370    psTrace("psastro", 6, "The bin is %ld (%.4f to %.4f)\n", bin, cumulative->bounds->data.F32[bin], cumulative->bounds->data.F32[bin+1]);
     371
     372    // Linear interpolation to the limit value in bin units
     373    float value;
     374    PS_BIN_INTERPOLATE (value, cumulative->nums, cumulative->bounds, bin, totalDataPoints * flimit);
     375    psTrace("psastro", 6, "limit value is %f\n", value);
     376
     377    return value;
     378}
    334379
    335380# define ESCAPE(MSG) { \
Note: See TracChangeset for help on using the changeset viewer.