- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simtest_nebulous_branches/psModules/src/astrom/pmAstrometryObjects.c
r24034 r27840 38 38 #include "pmAstrometryVisual.h" 39 39 40 // XXX this is defined in pmPSFtry.h, which makes no sense 41 float psVectorSystematicError (psVector *residuals, psVector *errors, float clipFraction); 42 40 43 #define PM_ASTROMETRYOBJECTS_DEBUG 1 41 44 … … 105 108 } 106 109 107 if (found1->data.S8[i]) {108 i++;109 continue;110 }111 if (found2->data.S8[j]) {112 j++;113 continue;114 }110 if (found1->data.S8[i]) { 111 i++; 112 continue; 113 } 114 if (found2->data.S8[j]) { 115 j++; 116 continue; 117 } 115 118 116 119 jStart = j; … … 125 128 continue; 126 129 } 127 if (found2->data.S8[j]) {128 j++;129 continue;130 }130 if (found2->data.S8[j]) { 131 j++; 132 continue; 133 } 131 134 132 135 // got a match; add to output list … … 135 138 psFree (match); 136 139 137 found1->data.S8[i] = 1;138 found2->data.S8[j] = 1;140 found1->data.S8[i] = 1; 141 found2->data.S8[j] = 1; 139 142 140 143 j++; … … 193 196 psArray *matches = match_lists(x1, y1, x2, y2, sorted1, sorted2, RADIUS); \ 194 197 \ 195 psFree( (void *)sorted1); \196 psFree( (void *)sorted2); \198 psFree(sorted1); \ 199 psFree(sorted2); \ 197 200 psFree(x1); \ 198 201 psFree(y1); \ … … 283 286 return results; 284 287 } 285 psTrace ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", results->xStats->clippedMean, results->xStats->clippedStdev, results->xStats->clippedNvalues, x->n); 288 // psTrace ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", results->xStats->clippedMean, results->xStats->clippedStdev, results->xStats->clippedNvalues, x->n); 289 psTrace ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", results->xStats->robustMedian, results->xStats->robustStdev, results->xStats->clippedNvalues, x->n); 286 290 287 291 if (!psVectorClipFitPolynomial2D (map->y, results->yStats, mask, 0xff, y, wt, X, Y)) { … … 296 300 return results; 297 301 } 298 psTrace ("psModules.astrom", 3, "y resid: %f +/- %f (%ld of %ld)\n", results->yStats->clippedMean, results->yStats->clippedStdev, results->yStats->clippedNvalues, y->n); 302 // psTrace ("psModules.astrom", 3, "y resid: %f +/- %f (%ld of %ld)\n", results->yStats->clippedMean, results->yStats->clippedStdev, results->yStats->clippedNvalues, y->n); 303 psTrace ("psModules.astrom", 3, "y resid: %f +/- %f (%ld of %ld)\n", results->yStats->robustMedian, results->yStats->robustStdev, results->yStats->clippedNvalues, y->n); 299 304 } 300 305 results->xStats->clipIter = stats->clipIter; 301 306 results->yStats->clipIter = stats->clipIter; 307 308 // *** calculate the 90%-ile and the systematic scatter for each direction. 309 310 // generate the X residual vector 311 psVector *xFit = psPolynomial2DEvalVector (map->x, X, Y); 312 if (!xFit) abort(); 313 psVector *xRes = (psVector *) psBinaryOp (NULL, x, "-", xFit); 314 if (!xRes) abort(); 315 psFree (xFit); 316 317 psVector *yFit = psPolynomial2DEvalVector (map->y, X, Y); 318 if (!yFit) abort(); 319 psVector *yRes = (psVector *) psBinaryOp (NULL, y, "-", yFit); 320 if (!yRes) abort(); 321 psFree (yFit); 322 323 // extract a high-quality subset (unmasked, S/N > XXX) and position errors 324 // XXX for now, generate a position error based on the magnitude error 325 psVector *xErr = psVectorAllocEmpty (match->n, PS_TYPE_F32); 326 psVector *yErr = psVectorAllocEmpty (match->n, PS_TYPE_F32); 327 psVector *xResGood = psVectorAllocEmpty (match->n, PS_TYPE_F32); 328 psVector *yResGood = psVectorAllocEmpty (match->n, PS_TYPE_F32); 329 330 for (int i = 0; i < match->n; i++) { 331 if (mask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; 332 pmAstromMatch *pair = match->data[i]; 333 pmAstromObj *rawStar = raw->data[pair->raw]; 334 if (!isfinite(rawStar->dMag)) continue; 335 if (rawStar->dMag > 0.02) continue; 336 337 // two likely failure values: NAN or 0.0 --> use dMag in this case 338 float xErrValue, yErrValue; 339 if (isfinite(rawStar->chip->xErr) && (rawStar->chip->xErr > 0.0)) { 340 xErrValue = rawStar->chip->xErr; 341 } else { 342 xErrValue = PS_MAX(0.005, rawStar->dMag); 343 } 344 if (isfinite(rawStar->chip->yErr) && (rawStar->chip->yErr > 0.0)) { 345 yErrValue = rawStar->chip->yErr; 346 } else { 347 yErrValue = PS_MAX(0.005, rawStar->dMag); 348 } 349 350 psVectorAppend (xErr, xErrValue); 351 psVectorAppend (yErr, yErrValue); 352 psVectorAppend (xResGood, xRes->data.F32[i]); 353 psVectorAppend (yResGood, yRes->data.F32[i]); 354 } 355 356 results->dXsys = psVectorSystematicError (xResGood, xErr, 0.05); 357 results->dYsys = psVectorSystematicError (yResGood, yErr, 0.05); 358 359 results->dXrange = pmAstromVectorRange (xResGood, 0.1, 0.9, results->xStats->clippedStdev); 360 results->dYrange = pmAstromVectorRange (yResGood, 0.1, 0.9, results->yStats->clippedStdev); 361 362 psTrace ("psModules.astrom", 3, "dXsys: %f, dXrange: %f\n", results->dXsys, results->dXrange); 363 psTrace ("psModules.astrom", 3, "dYsys: %f, dYrange: %f\n", results->dYsys, results->dYrange); 364 365 psFree (xErr); 366 psFree (yErr); 367 psFree (xRes); 368 psFree (yRes); 369 psFree (xResGood); 370 psFree (yResGood); 302 371 303 372 psFree (x); … … 311 380 } 312 381 382 // set the bin closest to the corresponding value. if USE_END is +/- 1, 383 // out-of-range saturates on lower/upper bin REGARDLESS of actual value 384 #define PS_BIN_FOR_VALUE(RESULT, VECTOR, VALUE, USE_END) { \ 385 psVectorBinaryDisectResult result; \ 386 psScalar tmpScalar; \ 387 tmpScalar.type.type = PS_TYPE_F32; \ 388 tmpScalar.data.F32 = (VALUE); \ 389 RESULT = psVectorBinaryDisect (&result, VECTOR, &tmpScalar); \ 390 switch (result) { \ 391 case PS_BINARY_DISECT_PASS: \ 392 break; \ 393 case PS_BINARY_DISECT_OUTSIDE_RANGE: \ 394 psTrace("psModules.astrom", 6, "selected bin outside range"); \ 395 if (USE_END == -1) { RESULT = 0; } \ 396 if (USE_END == +1) { RESULT = VECTOR->n - 1; } \ 397 break; \ 398 case PS_BINARY_DISECT_INVALID_INPUT: \ 399 case PS_BINARY_DISECT_INVALID_TYPE: \ 400 psAbort ("programming error"); \ 401 break; \ 402 } } 403 404 # define PS_BIN_INTERPOLATE(RESULT, VECTOR, BOUNDS, BIN, VALUE) { \ 405 float dX, dY, Xo, Yo, Xt; \ 406 if (BIN == BOUNDS->n - 1) { \ 407 dX = 0.5*(BOUNDS->data.F32[BIN+1] - BOUNDS->data.F32[BIN-1]); \ 408 dY = VECTOR->data.F32[BIN] - VECTOR->data.F32[BIN-1]; \ 409 Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \ 410 Yo = VECTOR->data.F32[BIN]; \ 411 } else { \ 412 dX = 0.5*(BOUNDS->data.F32[BIN+2] - BOUNDS->data.F32[BIN]); \ 413 dY = VECTOR->data.F32[BIN+1] - VECTOR->data.F32[BIN]; \ 414 Xo = 0.5*(BOUNDS->data.F32[BIN+1] + BOUNDS->data.F32[BIN]); \ 415 Yo = VECTOR->data.F32[BIN]; \ 416 } \ 417 if (dY != 0) { \ 418 Xt = (VALUE - Yo)*dX/dY + Xo; \ 419 } else { \ 420 Xt = Xo; \ 421 } \ 422 Xt = PS_MIN (BOUNDS->data.F32[BIN+1], PS_MAX(BOUNDS->data.F32[BIN], Xt)); \ 423 psTrace("psModules.astrom", 6, "(Xo, Yo, dX, dY, Xt, Yt) is (%.2f %.2f %.2f %.2f %.2f %.2f)\n", \ 424 Xo, Yo, dX, dY, Xt, VALUE); \ 425 RESULT = Xt; } 426 427 float pmAstromVectorRange (psVector *myVector, float minFrac, float maxFrac, float stdevGuess) { 428 429 psStats *stats = psStatsAlloc(PS_STAT_MIN | PS_STAT_MAX); // Statistics for min and max 430 psHistogram *histogram = NULL; // Histogram of the data 431 psHistogram *cumulative = NULL; // Cumulative histogram of the data 432 float min = NAN, max = NAN; // Mimimum and maximum values 433 434 // Get the minimum and maximum values 435 if (!psVectorStats(stats, myVector, NULL, NULL, 0)) { 436 psFree(stats); 437 return NAN; 438 } 439 min = stats->min; 440 max = stats->max; 441 if (isnan(min) || isnan(max)) { 442 psFree(stats); 443 return NAN; 444 } 445 446 psTrace("psModules.astrom", 5, "Data min/max is (%.2f, %.2f)\n", min, max); 447 448 // If all data points have the same value, then we set the appropriate members of stats and return. 449 if (fabs(max - min) <= FLT_EPSILON) { 450 psFree (stats); 451 return 0.0; 452 } 453 454 // Define the histogram bin size. 455 float binSize = 0.001; 456 long numBins = PS_MAX(PS_MIN(100000, (max - min) / binSize), 2); // Number of bins 457 psTrace("psModules.astrom", 5, "Numbins is %ld\n", numBins); 458 psTrace("psModules.astrom", 5, "Creating a robust histogram from data range (%.2f - %.2f)\n", min, max); 459 460 // allocate the histogram containers 461 histogram = psHistogramAlloc(min, max, numBins); 462 cumulative = psHistogramAlloc(min, max, numBins); 463 464 if (!psVectorHistogram(histogram, myVector, NULL, NULL, 0)) { 465 // if psVectorHistogram returns false, we have a programming error 466 psAbort ("Unable to generate histogram"); 467 } 468 if (psTraceGetLevel("psModules.astrom") >= 8) { 469 PS_VECTOR_PRINT_F32(histogram->bounds); 470 PS_VECTOR_PRINT_F32(histogram->nums); 471 } 472 473 // Convert the specific histogram to a cumulative histogram 474 // The cumulative histogram data points correspond to the UPPER bound value (N < Bin[i+1]) 475 cumulative->nums->data.F32[0] = histogram->nums->data.F32[0]; 476 for (long i = 1; i < histogram->nums->n; i++) { 477 cumulative->nums->data.F32[i] = cumulative->nums->data.F32[i-1] + histogram->nums->data.F32[i]; 478 cumulative->bounds->data.F32[i-1] = histogram->bounds->data.F32[i]; 479 } 480 if (psTraceGetLevel("psModules.astrom") >= 8) { 481 PS_VECTOR_PRINT_F32(cumulative->bounds); 482 PS_VECTOR_PRINT_F32(cumulative->nums); 483 } 484 485 // Find the bin which contains the first data point above the limit 486 long totalDataPoints = cumulative->nums->data.F32[numBins - 1]; 487 psTrace("psModules.astrom", 6, "Total data points is %ld\n", totalDataPoints); 488 489 // find bin which is the lower bound of the limit value (value[bin] < f < value[bin+1] 490 long binMin; 491 PS_BIN_FOR_VALUE(binMin, cumulative->nums, minFrac * totalDataPoints, 0); 492 psTrace("psModules.astrom", 6, "The bin is %ld (%.4f to %.4f)\n", binMin, cumulative->bounds->data.F32[binMin], cumulative->bounds->data.F32[binMin+1]); 493 494 // Linear interpolation to the limit value in bin units 495 float valueMin; 496 PS_BIN_INTERPOLATE (valueMin, cumulative->nums, cumulative->bounds, binMin, totalDataPoints * minFrac); 497 psTrace("psModules.astrom", 6, "limit value is %f\n", valueMin); 498 499 // find bin which is the lower bound of the limit value (value[bin] < f < value[bin+1] 500 long binMax; 501 PS_BIN_FOR_VALUE(binMax, cumulative->nums, maxFrac * totalDataPoints, 0); 502 psTrace("psModules.astrom", 6, "The bin is %ld (%.4f to %.4f)\n", binMax, cumulative->bounds->data.F32[binMax], cumulative->bounds->data.F32[binMax+1]); 503 504 // Linear interpolation to the limit value in bin units 505 float valueMax; 506 PS_BIN_INTERPOLATE (valueMax, cumulative->nums, cumulative->bounds, binMax, totalDataPoints * maxFrac); 507 psTrace("psModules.astrom", 6, "limit value is %f\n", valueMax); 508 509 // Clean up 510 psFree(histogram); 511 psFree(cumulative); 512 psFree(stats); 513 514 return (valueMax - valueMin); 515 } 313 516 314 517 /****************************************************************************** … … 634 837 } 635 838 636 # if 0 637 char line[16]; 638 psFits *fits = psFitsOpen ("grid.image.fits", "w"); 639 psFitsWriteImage (fits, NULL, gridNP, 0, NULL); 640 psFitsClose (fits); 641 fprintf (stderr, "wrote grid image, press return to continue\n"); 642 fgets (line, 15, stdin); 643 # endif 839 if (psTraceGetLevel("psModules.astrom") >= 5) { 840 char line[16]; 841 psFits *fits = psFitsOpen ("grid.image.fits", "w"); 842 psFitsWriteImage (fits, NULL, gridNP, 0, NULL); 843 psFitsClose (fits); 844 fprintf (stderr, "wrote grid image, press return to continue\n"); 845 if (!fgets (line, 15, stdin)) { 846 fprintf(stderr, "Error waiting for RETURN."); 847 } 848 } 644 849 645 850 // only check bins with at least 1/2 of max bin 646 851 // XXX requiring at least 3 matches in bin 647 852 int minNpts = PS_MAX (0.5*imStats->max, 5); 648 psTrace("psModule.astrom", 5, "minNpts: %d, min: %d, max: %d, median: %f, stdev: %f", minNpts, (int)(imStats->min), (int)(imStats->max), imStats->sampleMedian, imStats->sampleStdev);853 psTrace("psModule.astrom", 4, "minNpts: %d, min: %d, max: %d, median: %f, stdev: %f", minNpts, (int)(imStats->min), (int)(imStats->max), imStats->sampleMedian, imStats->sampleStdev); 649 854 650 855 // find the 'best' bin … … 687 892 688 893 // XXX this function is crashing 689 // pmAstromVisualPlotGridMatch(raw, ref, gridNP, stats->offset.x, stats->offset.y, maxOffpix, Scale, Offset); 894 pmAstromVisualPlotGridMatch(raw, ref, gridNP, stats->offset.x, stats->offset.y, maxOffpix, Scale, Offset); 895 pmAstromVisualPlotGridMatchOverlay(raw, ref); 690 896 691 897 psFree (imStats); … … 962 1168 */ 963 1169 1170 /*****************************************************************************/ 1171 static void pmAstromMatchInfoFree (pmAstromMatchInfo *info) 1172 { 1173 if (info == NULL) return; 1174 return; 1175 } 1176 1177 1178 /*****************************************************************************/ 1179 pmAstromMatchInfo *pmAstromMatchInfoAlloc() 1180 { 1181 pmAstromMatchInfo *info = psAlloc (sizeof(pmAstromMatchInfo)); 1182 psMemSetDeallocator(info, (psFreeFunc) pmAstromMatchInfoFree); 1183 1184 info->match = NULL; 1185 info->radius = NAN; 1186 1187 return (info); 1188 } 1189 1190 // generate a unique set of matches (choose closest match) 1191 psArray *pmAstromRadiusMatchUniq (psArray *rawstars, psArray *refstars, psArray *matches) { 1192 1193 // I have the matches between the refstars and the rawstars. 1194 // For each refstar, find the single match which has the smallest radius and reject 1195 // all others. 1196 1197 // create an array of refstars->n arrays, each containing all of the matches for the 1198 // given refstar. 1199 1200 psArray *refstarMatches = psArrayAlloc (refstars->n); 1201 1202 for (int i = 0; i < matches->n; i++) { 1203 1204 pmAstromMatch *match = matches->data[i]; 1205 1206 // accumulate this refstar match on the array for this refstar (create if needed) 1207 psArray *refSet = refstarMatches->data[match->ref]; 1208 if (!refSet) { 1209 refstarMatches->data[match->ref] = psArrayAllocEmpty (8); 1210 refSet = refstarMatches->data[match->ref]; 1211 } 1212 1213 pmAstromMatchInfo *matchInfo = pmAstromMatchInfoAlloc(); 1214 1215 pmAstromObj *refStar = refstars->data[match->ref]; 1216 pmAstromObj *rawStar = rawstars->data[match->raw]; 1217 1218 matchInfo->match = match; // reference to the match of interest 1219 matchInfo->radius = hypot (refStar->FP->x - rawStar->FP->x, refStar->FP->y - rawStar->FP->y); 1220 1221 psArrayAdd (refSet, 8, matchInfo); // matchInfo->match is just a reference 1222 psFree (matchInfo); 1223 } 1224 1225 // we now have a set of matches for each refstar and their distances; create a new set 1226 // keeping only the closest entry for each match 1227 1228 psArray *unique = psArrayAllocEmpty (PS_MAX(16, matches->n / 2)); 1229 for (int i = 0; i < refstars->n; i++) { 1230 1231 psArray *refSet = refstarMatches->data[i]; 1232 if (!refSet) continue; 1233 if (refSet->n == 0) continue; // not certain how this can happen... 1234 1235 if (refSet->n == 1) { 1236 pmAstromMatchInfo *matchInfo = refSet->data[0]; 1237 psArrayAdd (unique, 32, matchInfo->match); 1238 continue; 1239 } 1240 1241 pmAstromMatchInfo *matchInfo = refSet->data[0]; 1242 float minRadius = matchInfo->radius; 1243 pmAstromMatch *minMatch = matchInfo->match; 1244 for (int j = 1; j < refSet->n; j++) { 1245 pmAstromMatchInfo *matchInfo = refSet->data[j]; 1246 if (minRadius < matchInfo->radius) continue; 1247 minMatch = matchInfo->match; 1248 minRadius = matchInfo->radius; 1249 } 1250 1251 psArrayAdd (unique, 32, minMatch); // minMatch is just a reference to a match on matches, 1252 } 1253 1254 psLogMsg ("psModules.astrom", 3, "generate unique matches to reference stars: %ld matches -> %ld matches\n", matches->n, unique->n); 1255 psFree (refstarMatches); 1256 1257 return unique; 1258 }
Note:
See TracChangeset
for help on using the changeset viewer.
