- Timestamp:
- Nov 20, 2009, 3:22:59 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20091113/psastro/src/psastroZeroPoint.c
r26167 r26224 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 psastroZeroPointAnalysis (header, dMag, zeropt, recipe); 99 97 psFree (dMag); 100 98 dMag = NULL; … … 141 139 } 142 140 143 bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, float edgeFraction, bool useMean) {141 bool psastroZeroPointAnalysis (psMetadata *header, psVector *dMag, float zeropt, psMetadata *recipe) { 144 142 145 143 // XXX make this depend on the mode? … … 148 146 return false; 149 147 } 148 149 bool status; 150 bool useMean = psMetadataLookupBool (&status, recipe, "ZERO.POINT.USE.MEAN"); 150 151 151 152 // the zero point analysis depends on the type of desired statistic. For comparisons … … 166 167 } 167 168 } else { 168 stats = psastroStatsPercentile (dMag, edgeFraction);169 stats = psastroStatsPercentile (dMag, recipe); 169 170 if (!stats) { 170 171 psError(PS_ERR_UNKNOWN, false, "failure to measure zero point by edge"); … … 233 234 // return results in stats->sampleMean, sampleStdev 234 235 // XXX this is a misuse of psStats -- make our own structure? 235 psStats *psastroStatsPercentile (psVector *myVector, float flimit) {236 psStats *psastroStatsPercentile (psVector *myVector, psMetadata *recipe) { 236 237 237 238 // search for the 'blue' edge of the dMag distribution: 238 239 // the distribution is not a normal population, but instead has a broad range with fairly hard edges. 239 240 // 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"); 240 246 241 247 // stats is first used to find the data range … … 245 251 float min = NAN, max = NAN; // Mimimum and maximum values 246 252 253 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); 254 247 255 // Get the minimum and maximum values 248 256 if (!psVectorStats(stats, myVector, NULL, NULL, 0)) goto escape; … … 250 258 max = stats->max; 251 259 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); 253 261 254 262 // If all data points have the same value, then we set the appropriate members of stats and return. … … 264 272 float binSize = MAG_RESOLUTION; 265 273 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 histogram274 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 270 278 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 279 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 312 309 stats->results |= PS_STAT_CLIPPED_MEAN; 313 310 stats->results |= PS_STAT_CLIPPED_STDEV; … … 317 314 psFree(histogram); 318 315 psFree(cumulative); 316 psFree(subset); 317 psFree(rng); 319 318 return stats; 320 319 … … 332 331 } 333 332 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? 337 float 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 } 334 379 335 380 # define ESCAPE(MSG) { \
Note:
See TracChangeset
for help on using the changeset viewer.
