Changeset 26259 for trunk/psastro/src/psastroZeroPoint.c
- Timestamp:
- Nov 22, 2009, 2:57:41 PM (16 years ago)
- File:
-
- 1 edited
-
trunk/psastro/src/psastroZeroPoint.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psastro/src/psastroZeroPoint.c
r25906 r26259 30 30 // recipe options 31 31 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");34 32 35 33 // select the input data sources … … 86 84 // calculate dMag for the matched stars just for this readout (well, chip) 87 85 psMetadata *header = psMetadataLookupMetadata (&status, readout->analysis, "PSASTRO.HEADER"); 88 psastroZeroPointAnalysis (header, dMag, zeropt, edgeFraction, useMean);86 psastroZeroPointAnalysis (header, dMag, zeropt, recipe); 89 87 psFree (dMag); 90 88 dMag = NULL; … … 96 94 if (byExposure) { 97 95 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); 99 102 psFree (dMag); 100 103 dMag = NULL; … … 113 116 114 117 // 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"); 116 119 if (rawstars == NULL) return dMag; 117 120 118 121 // 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"); 120 123 if (refstars == NULL) return dMag; 121 124 … … 141 144 } 142 145 143 bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, float edgeFraction, bool useMean) {146 bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, psMetadata *recipe) { 144 147 145 148 // XXX make this depend on the mode? … … 148 151 return false; 149 152 } 153 154 bool status; 155 bool useMean = psMetadataLookupBool (&status, recipe, "ZERO.POINT.USE.MEAN"); 150 156 151 157 // the zero point analysis depends on the type of desired statistic. For comparisons … … 166 172 } 167 173 } else { 168 stats = psastroStatsPercentile (dMag, edgeFraction);174 stats = psastroStatsPercentile (dMag, recipe); 169 175 if (!stats) { 170 176 psError(PS_ERR_UNKNOWN, false, "failure to measure zero point by edge"); … … 183 189 } 184 190 185 #define MAG_RESOLUTION 0.00 1191 #define MAG_RESOLUTION 0.0002 186 192 187 193 // set the bin closest to the corresponding value. if USE_END is +/- 1, … … 233 239 // return results in stats->sampleMean, sampleStdev 234 240 // XXX this is a misuse of psStats -- make our own structure? 235 psStats *psastroStatsPercentile (psVector *myVector, float flimit) {241 psStats *psastroStatsPercentile (psVector *myVector, psMetadata *recipe) { 236 242 237 243 // search for the 'blue' edge of the dMag distribution: 238 244 // the distribution is not a normal population, but instead has a broad range with fairly hard edges. 239 245 // 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"); 240 251 241 252 // stats is first used to find the data range … … 245 256 float min = NAN, max = NAN; // Mimimum and maximum values 246 257 258 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); 259 247 260 // Get the minimum and maximum values 248 261 if (!psVectorStats(stats, myVector, NULL, NULL, 0)) goto escape; … … 250 263 max = stats->max; 251 264 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); 253 266 254 267 // If all data points have the same value, then we set the appropriate members of stats and return. … … 264 277 float binSize = MAG_RESOLUTION; 265 278 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 histogram279 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 270 283 histogram = psHistogramAlloc(min, max, numBins); 271 if (!psVectorHistogram(histogram, myVector, NULL, NULL, 0)) {272 // if psVectorHistogram returns false, we have a programming error273 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 histogram284 // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1])285 284 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 312 314 stats->results |= PS_STAT_CLIPPED_MEAN; 313 315 stats->results |= PS_STAT_CLIPPED_STDEV; … … 317 319 psFree(histogram); 318 320 psFree(cumulative); 321 psFree(subset); 322 psFree(rng); 319 323 return stats; 320 324 … … 332 336 } 333 337 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? 342 float 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 } 334 384 335 385 # define ESCAPE(MSG) { \
Note:
See TracChangeset
for help on using the changeset viewer.
