Changeset 10829 for trunk/psModules/src/astrom/pmAstrometryObjects.c
- Timestamp:
- Dec 24, 2006, 3:49:50 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/astrom/pmAstrometryObjects.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/astrom/pmAstrometryObjects.c
r10780 r10829 8 8 * @author EAM, IfA 9 9 * 10 * @version $Revision: 1. 19$ $Name: not supported by cvs2svn $11 * @date $Date: 2006-12- 17 09:45:20$10 * @version $Revision: 1.20 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2006-12-25 01:49:49 $ 12 12 * 13 13 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 121 121 122 122 /************************************************************************************************************/ 123 123 // macro to generate code for radius match function based on desired member 124 // radius is in units of matching member (eg, pixels for chip, microns for FP, etc) 124 125 #define MAKE_ASTROM_RADIUS(FUNC, MEMBER) \ 125 126 psArray *FUNC( \ 126 127 const psArray *st1, \ 127 128 const psArray *st2, \ 128 const psMetadata *config) \129 double RADIUS) \ 129 130 { \ 130 131 PS_ASSERT_PTR_NON_NULL(st1, NULL); \ 131 132 PS_ASSERT_PTR_NON_NULL(st2, NULL); \ 132 PS_ASSERT_PTR_NON_NULL(config, NULL); \133 133 \ 134 134 assert(st1->n == 0 || pmIsAstromObj(st1->data[0])); \ 135 135 assert(st2->n == 0 || pmIsAstromObj(st2->data[0])); \ 136 136 \ 137 bool status = false; \138 double RADIUS = psMetadataLookupF32 (&status, config, "PSASTRO.MATCH.RADIUS"); \139 if (!status) { \140 psError(PS_ERR_IO, false, "Failed to lookup matching radius"); \141 return NULL; \142 } \143 137 /* sort both lists by X coord; st1 first */ \ 144 138 psVector *x1 = psVectorAlloc(st1->n, PS_TYPE_F64); \ … … 186 180 */ 187 181 MAKE_ASTROM_RADIUS(pmAstromRadiusMatch, FP) 182 MAKE_ASTROM_RADIUS(pmAstromRadiusMatchFP, FP) 188 183 MAKE_ASTROM_RADIUS(pmAstromRadiusMatchTP, TP) 189 184 MAKE_ASTROM_RADIUS(pmAstromRadiusMatchChip, chip) 190 185 191 186 /****************************************************************************** 192 pmAstromMatchFit(map, raw, ref, match, config): take two matched star lists187 pmAstromMatchFit(map, raw, ref, match, stats): take two matched star lists 193 188 and fit a psPlaneTransform between them 194 189 ******************************************************************************/ 195 boolpmAstromMatchFit(190 pmAstromFitResults *pmAstromMatchFit( 196 191 psPlaneTransform *map, 197 192 psArray *raw, 198 193 psArray *ref, 199 194 psArray *match, 200 psMetadata *config, 201 psMetadata *updates) 195 psStats *stats) 202 196 { 203 197 PS_ASSERT_PTR_NON_NULL(map, NULL); … … 205 199 PS_ASSERT_PTR_NON_NULL(ref, NULL); 206 200 PS_ASSERT_PTR_NON_NULL(match, NULL); 207 PS_ASSERT_PTR_NON_NULL(config, NULL); 208 209 bool status; 210 pmAstromObj *rawStar, *refStar; 211 pmAstromMatch *pair; 212 213 // XXX EAM : clip fit seems to only work for F32! 214 // XXX EAM : clip fit fails to handle NULL error 201 PS_ASSERT_PTR_NON_NULL(stats, NULL); 202 203 // reassign values for clip fit 204 // XXX set wt based on mag error? 215 205 psVector *X = psVectorAlloc (match->n, PS_TYPE_F32); 216 206 psVector *Y = psVectorAlloc (match->n, PS_TYPE_F32); … … 220 210 // take the matched stars, first fit 221 211 for (int i = 0; i < match->n; i++) { 222 223 pair = match->data[i]; 224 rawStar = raw->data[pair->raw]; 225 refStar = ref->data[pair->ref]; 212 pmAstromMatch *pair = match->data[i]; 213 pmAstromObj *rawStar = raw->data[pair->raw]; 214 pmAstromObj *refStar = ref->data[pair->ref]; 226 215 227 216 X->data.F32[i] = rawStar->chip->x; … … 238 227 psVectorInit (mask, 0); 239 228 240 double dX, dY;241 242 psStats *stats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);243 stats->clipSigma = psMetadataLookupF32 (&status, config, "PSASTRO.CHIP.NSIGMA");244 stats->clipIter = 1;245 int clipIter = psMetadataLookupS32 (&status, config, "PSASTRO.CHIP.NITER");246 // we run 'clipIter' cycles clipping in each of x and y229 pmAstromFitResults *results = pmAstromFitResultsAlloc(); 230 results->xStats = psStatsAlloc (PS_STAT_NONE); 231 results->yStats = psStatsAlloc (PS_STAT_NONE); 232 *results->xStats = *stats; 233 *results->yStats = *stats; 234 results->xStats->clipIter = 1; 235 results->yStats->clipIter = 1; 247 236 248 237 // fit chip-to-FPA transformation 249 // XXX should force x->n and y->n to be the same 250 for (int i = 0; i < clipIter; i++) { 251 psVectorClipFitPolynomial2D (map->x, stats, mask, 0xff, x, wt, X, Y); 252 psLogMsg ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues, x->n); 253 dX = stats->clippedStdev; 254 255 psVectorClipFitPolynomial2D (map->y, stats, mask, 0xff, y, wt, X, Y); 256 psLogMsg ("psModules.astrom", 3, "y resid: %f +/- %f (%ld of %ld)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues, y->n); 257 dY = stats->clippedStdev; 258 } 259 260 // XXXX test dump output code 261 # if (0) 262 psVector *xfit = psPolynomial2DEvalVector(map->x, X, Y); 263 psVector *yfit = psPolynomial2DEvalVector(map->y, X, Y); 264 FILE *f = fopen ("match.dat", "w"); 265 for (int i = 0; i < x->n; i++) { 266 fprintf (f, "%3d %1d %1d %f %f %f %f %f %f\n", 267 i, mask->data.U8[i], mask->data.U8[i], 268 X->data.F32[i], Y->data.F32[i], 269 xfit->data.F32[i], yfit->data.F32[i], 270 x->data.F32[i], y->data.F32[i]); 271 } 272 fclose (f); 273 psFree (xfit); 274 psFree (yfit); 275 # endif 276 277 // XXX this is somewhat ad-hoc: we need to be sure these values are in arcsec 278 // and we need to set NASTRO = 0 if we have a failure, etc 279 // XXX this is a somewhat silly place to write these updates... 280 if (updates) { 281 psMetadataAddF32 (updates, PS_LIST_TAIL, "NASTRO", PS_META_REPLACE, "", stats->clippedNvalues); 282 psMetadataAddF32 (updates, PS_LIST_TAIL, "CERROR", PS_META_REPLACE, "", hypot(dX, dY)); 283 psMetadataAddF32 (updates, PS_LIST_TAIL, "CPRECISE", PS_META_REPLACE, "", hypot(dX, dY)/sqrt(PS_MIN(x->n, y->n))); 284 psMetadataAddF32 (updates, PS_LIST_TAIL, "EQUINOX", PS_META_REPLACE, "", 2000.0); // XXX this is bogus: must be defined somewhere 285 } 286 287 float maxError = psMetadataLookupF32 (&status, config, "PSASTRO.MAX.ERROR"); 288 float astError = hypot(dX, dY); 289 int minNstar = psMetadataLookupS32 (&status, config, "PSASTRO.MIN.NSTAR"); 290 int astNstar = stats->clippedNvalues; 291 292 if (astError > maxError) { 293 psError(PS_ERR_UNKNOWN, true, "residual error is too large, failed to find a solution: %f > %f", astError, maxError); 294 return NULL; 295 } 296 if (stats->clippedNvalues < minNstar) { 297 psError(PS_ERR_UNKNOWN, true, "solution uses too few stars: %d < %d", astNstar, minNstar); 298 return NULL; 299 } 300 psLogMsg ("psModules.astrom", 3, "astrometry solution: error: %f, Nstars: %d", astError, astNstar); 238 // we run 'clipIter' cycles clipping in each of x and y, with only one iteration each 239 for (int i = 0; i < stats->clipIter; i++) { 240 psVectorClipFitPolynomial2D (map->x, results->xStats, mask, 0xff, x, wt, X, Y); 241 psTrace ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues, x->n); 242 243 psVectorClipFitPolynomial2D (map->y, results->yStats, mask, 0xff, y, wt, X, Y); 244 psTrace ("psModules.astrom", 3, "y resid: %f +/- %f (%ld of %ld)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues, y->n); 245 } 246 results->xStats->clipIter = stats->clipIter; 247 results->yStats->clipIter = stats->clipIter; 301 248 302 249 psFree (x); … … 305 252 psFree (Y); 306 253 psFree (wt); 307 psFree (stats);308 254 psFree (mask); 309 255 310 return ( map);256 return (results); 311 257 } 312 258 … … 377 323 378 324 return (stats); 325 } 326 327 /****************************************************************************** 328 pmAstromFitResultsFree(stats) 329 ******************************************************************************/ 330 static void pmAstromFitResultsFree(pmAstromFitResults *results) 331 { 332 if (results == NULL) 333 return; 334 psFree (results->xStats); 335 psFree (results->yStats); 336 return; 337 } 338 339 /****************************************************************************** 340 pmAstromFitResultsAlloc() 341 ******************************************************************************/ 342 pmAstromFitResults *pmAstromFitResultsAlloc(void) 343 { 344 pmAstromFitResults *results = psAlloc (sizeof(pmAstromFitResults)); 345 psMemSetDeallocator (results, (psFreeFunc)pmAstromFitResultsFree); 346 347 results->xStats = NULL; 348 results->yStats = NULL; 349 results->nMatch = 0; 350 results->nSigma = 0; 351 352 return (results); 379 353 } 380 354
Note:
See TracChangeset
for help on using the changeset viewer.
