IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Nov 22, 2009, 2:57:41 PM (16 years ago)
Author:
eugene
Message:

various fixes to psastro:

1) added bootstrap resampling to zero point error analysis
2) added iterative clump removal from refstars and rawstars
3) added unique reference match option
4) some improved visualizations
5) improved mosaic iterations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psastro/src/psastroZeroPoint.c

    r25906 r26259  
    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        if (!header) {
     97          header = psMetadataAlloc ();
     98          psMetadataAddMetadata (fpa->analysis, PS_LIST_TAIL, "PSASTRO.HEADER",  PS_META_REPLACE, "psastro header stats", header);
     99          psFree (header);
     100        }
     101        psastroZeroPointAnalysis (header, dMag, zeropt, recipe);
    99102        psFree (dMag);
    100103        dMag = NULL;
     
    113116
    114117    // select the raw objects for this readout
    115     psArray *rawstars = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.RAWSTARS");
     118    psArray *rawstars = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.RAWSTARS.SUBSET");
    116119    if (rawstars == NULL) return dMag;
    117120
    118121    // select the raw objects for this readout
    119     psArray *refstars = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.REFSTARS");
     122    psArray *refstars = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.REFSTARS.SUBSET");
    120123    if (refstars == NULL) return dMag;
    121124
     
    141144}
    142145
    143 bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, float edgeFraction, bool useMean) {
     146bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, psMetadata *recipe) {
    144147
    145148    // XXX make this depend on the mode?
     
    148151      return false;
    149152    }
     153
     154    bool status;
     155    bool useMean = psMetadataLookupBool (&status, recipe, "ZERO.POINT.USE.MEAN");
    150156
    151157    // the zero point analysis depends on the type of desired statistic.  For comparisons
     
    166172        }
    167173    } else {
    168         stats = psastroStatsPercentile (dMag, edgeFraction);
     174        stats = psastroStatsPercentile (dMag, recipe);
    169175        if (!stats) {
    170176            psError(PS_ERR_UNKNOWN, false, "failure to measure zero point by edge");
     
    183189}
    184190
    185 #define MAG_RESOLUTION 0.001
     191#define MAG_RESOLUTION 0.0002
    186192
    187193// set the bin closest to the corresponding value.  if USE_END is +/- 1,
     
    233239// return results in stats->sampleMean, sampleStdev
    234240// XXX this is a misuse of psStats -- make our own structure?
    235 psStats *psastroStatsPercentile (psVector *myVector, float flimit) {
     241psStats *psastroStatsPercentile (psVector *myVector, psMetadata *recipe) {
    236242
    237243    // search for the 'blue' edge of the dMag distribution:
    238244    // the distribution is not a normal population, but instead has a broad range with fairly hard edges.
    239245    // construct a histogram and look for the
     246
     247    bool status;
     248    float edgeFraction = psMetadataLookupF32 (&status, recipe, "ZERO.POINT.EDGE.FRACTION");
     249    int edgeSample = psMetadataLookupS32 (&status, recipe, "ZERO.POINT.EDGE.SAMPLE");
     250    float edgeSampleFraction = psMetadataLookupF32 (&status, recipe, "ZERO.POINT.EDGE.SAMPLE.FRACTION");
    240251
    241252    // stats is first used to find the data range
     
    245256    float min = NAN, max = NAN;         // Mimimum and maximum values
    246257
     258    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); 
     259
    247260    // Get the minimum and maximum values
    248261    if (!psVectorStats(stats, myVector, NULL, NULL, 0)) goto escape;
     
    250263    max = stats->max;
    251264    if (isnan(min) || isnan(max)) goto escape;
    252     psTrace("psastro", 6, "Data min/max is (%.2f, %.2f)\n", min, max);
     265    psTrace("psastro", 5, "Data min/max is (%.2f, %.2f)\n", min, max);
    253266
    254267    // If all data points have the same value, then we set the appropriate members of stats and return.
     
    264277    float binSize = MAG_RESOLUTION;
    265278    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
     279    psTrace("psastro", 5, "Numbins is %ld\n", numBins);
     280    psTrace("psastro", 5, "Creating a robust histogram from data range (%.2f - %.2f)\n", min, max);
     281
     282    // allocate the histogram containers
    270283    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])
    285284    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
     285
     286    // find the mean value:
     287    stats->clippedMean = psastroStatsPercentileValue (histogram, cumulative, myVector, edgeFraction);
     288
     289    int nSubset = myVector->n * edgeSampleFraction;
     290    psVector *subset = psVectorAlloc (nSubset, PS_TYPE_F32);
     291
     292    float Sum = 0.0;
     293    float S2 = 0.0;
     294    for (int i = 0; i < edgeSample; i++) {
     295       
     296        // generate the subset vector
     297        for (long i = 0; i < nSubset; i++) {
     298            double frnd = psRandomUniform(rng);
     299            int entry = PS_MIN(myVector->n - 1, PS_MAX(0, myVector->n * frnd));
     300
     301            subset->data.F32[i] = myVector->data.F32[entry];
     302        }
     303
     304        float value = psastroStatsPercentileValue (histogram, cumulative, subset, edgeFraction);
     305
     306        Sum += value;
     307        S2 += value*value;
     308    }
     309    psTrace("psastro", 6, "subset stats: Sum: %f, S2: %f, Npts: %d\n", Sum, S2, edgeSample);
     310
     311    stats->clippedStdev = PS_MAX (sqrt(S2 / edgeSample - PS_SQR(Sum/edgeSample)), MAG_RESOLUTION);
     312    psTrace("psastro", 5, "percentile stats %f +/- %f\n", stats->clippedMean, stats->clippedStdev);
     313
    312314    stats->results |= PS_STAT_CLIPPED_MEAN;
    313315    stats->results |= PS_STAT_CLIPPED_STDEV;
     
    317319    psFree(histogram);
    318320    psFree(cumulative);
     321    psFree(subset);
     322    psFree(rng);
    319323    return stats;
    320324
     
    332336}
    333337
     338
     339// measure the edge of the sample at flimit
     340// return results in stats->sampleMean, sampleStdev
     341// XXX this is a misuse of psStats -- make our own structure?
     342float psastroStatsPercentileValue (psHistogram *histogram, psHistogram *cumulative, psVector *myVector, float flimit) {
     343
     344    // need to initialize the histogram on each pass
     345    psVectorInit (histogram->nums, 0);
     346    if (!psVectorHistogram(histogram, myVector, NULL, NULL, 0)) {
     347        // if psVectorHistogram returns false, we have a programming error
     348        psAbort ("Unable to generate histogram for psastroZeroPointAnalysis");
     349    }
     350    if (psTraceGetLevel("psastro") >= 8) {
     351        PS_VECTOR_PRINT_F32(histogram->bounds);
     352        PS_VECTOR_PRINT_F32(histogram->nums);
     353    }
     354
     355    // Convert the specific histogram to a cumulative histogram
     356    // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1])
     357    cumulative->nums->data.F32[0] = histogram->nums->data.F32[0];
     358    for (long i = 1; i < histogram->nums->n; i++) {
     359        cumulative->nums->data.F32[i] = cumulative->nums->data.F32[i-1] + histogram->nums->data.F32[i];
     360        cumulative->bounds->data.F32[i-1] = histogram->bounds->data.F32[i];
     361    }
     362    if (psTraceGetLevel("psastro") >= 8) {
     363        PS_VECTOR_PRINT_F32(cumulative->bounds);
     364        PS_VECTOR_PRINT_F32(cumulative->nums);
     365    }
     366
     367    // Find the bin which contains the first data point above the limit
     368    long numBins = cumulative->nums->n;
     369    long totalDataPoints = cumulative->nums->data.F32[numBins - 1];
     370    psTrace("psastro", 6, "Total data points is %ld\n", totalDataPoints);
     371
     372    // find bin which is the lower bound of the limit value (value[bin] < f < value[bin+1]
     373    long bin;
     374    PS_BIN_FOR_VALUE(bin, cumulative->nums, flimit * totalDataPoints, 0);
     375    psTrace("psastro", 6, "The bin is %ld (%.4f to %.4f)\n", bin, cumulative->bounds->data.F32[bin], cumulative->bounds->data.F32[bin+1]);
     376
     377    // Linear interpolation to the limit value in bin units
     378    float value;
     379    PS_BIN_INTERPOLATE (value, cumulative->nums, cumulative->bounds, bin, totalDataPoints * flimit);
     380    psTrace("psastro", 6, "limit value is %f\n", value);
     381
     382    return value;
     383}
    334384
    335385# define ESCAPE(MSG) { \
Note: See TracChangeset for help on using the changeset viewer.