- Timestamp:
- Oct 9, 2008, 2:39:01 PM (18 years ago)
- Location:
- branches/cnb_branch_20080830/psastro/src
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
psastroAstromGuess.c (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/cnb_branch_20080830/psastro/src
- Property svn:ignore
-
old new 15 15 psastroModel 16 16 gpcModel 17 psastroModelFit
-
- Property svn:ignore
-
branches/cnb_branch_20080830/psastro/src/psastroAstromGuess.c
r17933 r20033 1 1 # include "psastroInternal.h" 2 # define DEBUG 0 2 3 3 4 // this function loads the header WCS astrometry terms into the fpa terms and applies the … … 28 29 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSASTRO_RECIPE); 29 30 if (!recipe) { 30 psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe!");31 return false;31 psError(PSASTRO_ERR_CONFIG, true, "Can't find PSASTRO recipe!"); 32 return false; 32 33 } 33 34 … … 35 36 bool useModel = psMetadataLookupBool (&status, config->arguments, "PSASTRO.USE.MODEL"); 36 37 if (!status) { 37 useModel = psMetadataLookupBool (&status, recipe, "PSASTRO.USE.MODEL");38 useModel = psMetadataLookupBool (&status, recipe, "PSASTRO.USE.MODEL"); 38 39 } 39 40 … … 41 42 pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSASTRO.INPUT"); 42 43 if (!input) { 43 psError(PSASTRO_ERR_CONFIG, true, "Can't find input data");44 return false;44 psError(PSASTRO_ERR_CONFIG, true, "Can't find input data"); 45 return false; 45 46 } 46 47 … … 48 49 double pixelScale = psMetadataLookupF32 (&status, recipe, "PSASTRO.PIXEL.SCALE"); 49 50 if (!status) { 50 psError(PS_ERR_IO, true, "Failed to lookup pixel scale"); 51 return false; 52 } 51 psError(PS_ERR_IO, true, "Failed to lookup pixel scale"); 52 return false; 53 } 54 55 psVector *cornerL = psVectorAllocEmpty (100, PS_TYPE_F32); 56 psVector *cornerM = psVectorAllocEmpty (100, PS_TYPE_F32); 57 psVector *cornerP = psVectorAllocEmpty (100, PS_TYPE_F32); 58 psVector *cornerQ = psVectorAllocEmpty (100, PS_TYPE_F32); 59 psVector *cornerR = psVectorAllocEmpty (100, PS_TYPE_F32); 60 psVector *cornerD = psVectorAllocEmpty (100, PS_TYPE_F32); 53 61 54 62 pmFPA *fpa = input->fpa; 63 64 if (DEBUG) psastroDumpCorners ("corners.up.guess1.dat", "corners.dn.guess1.dat", fpa); 55 65 56 66 // load mosaic-level astrometry? 57 67 bool bilevelAstrometry = false; 58 68 if (!useModel) { 59 psastroAstromGuessSetFPA (fpa, &bilevelAstrometry);69 psastroAstromGuessSetFPA (fpa, &bilevelAstrometry); 60 70 } 61 71 … … 65 75 if (!chip->process || !chip->file_exists || !chip->data_exists) { continue; } 66 76 67 if (!useModel) {68 if (!psastroAstromGuessSetChip (fpa, chip, view, pixelScale, bilevelAstrometry)) continue;69 }77 if (!useModel) { 78 if (!psastroAstromGuessSetChip (fpa, chip, view, pixelScale, bilevelAstrometry)) continue; 79 } 70 80 71 81 if (newFPA) { 72 82 newFPA = false; 73 while (fpa->toSky->R < 0) fpa->toSky->R += 2.0*M_PI;74 while (fpa->toSky->R > 2.0*M_PI) fpa->toSky->R -= 2.0*M_PI;83 while (fpa->toSky->R < 0) fpa->toSky->R += 2.0*M_PI; 84 while (fpa->toSky->R > 2.0*M_PI) fpa->toSky->R -= 2.0*M_PI; 75 85 RAminSky = fpa->toSky->R - M_PI; 76 86 RAmaxSky = fpa->toSky->R + M_PI; 87 } 88 89 // report and save the current best guess for the chip 0,0 pixel coordinates 90 { 91 psPlane ptCH, ptFP, ptTP; 92 psSphere ptSky; 93 94 ptCH.x = 0; 95 ptCH.y = 0; 96 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 97 psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP); 98 psDeproject (&ptSky, &ptTP, fpa->toSky); 99 psLogMsg ("psastro", 3, "0,0 pix for chip %3d = %f,%f\n", view->chip, DEG_RAD*ptSky.r, DEG_RAD*ptSky.d); 100 101 psVectorAppend (cornerL, ptFP.x); 102 psVectorAppend (cornerM, ptFP.y); 103 psVectorAppend (cornerP, ptTP.x); 104 psVectorAppend (cornerQ, ptTP.y); 105 psVectorAppend (cornerR, ptSky.r); 106 psVectorAppend (cornerD, ptSky.d); 77 107 } 78 108 … … 86 116 if (! readout->data_exists) { continue; } 87 117 88 // report the current best guess for the cell 0,0 pixel coordinate89 {90 psPlane ptCH, ptFP, ptTP;91 psSphere ptSky;92 93 ptCH.x = 0;94 ptCH.y = 0;95 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH);96 psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP);97 psDeproject (&ptSky, &ptTP, fpa->toSky);98 psLogMsg ("psastro", 2, "0,0 pix for chip,cell %d,%d = %f,%f\n", view->chip, view->cell, DEG_RAD*ptSky.r, DEG_RAD*ptSky.d);99 }100 101 118 psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS"); 102 119 if (rawstars == NULL) { continue; } 103 120 104 *nStars += rawstars->n;121 *nStars += rawstars->n; 105 122 for (int i = 0; i < rawstars->n; i++) { 106 123 pmAstromObj *raw = rawstars->data[i]; … … 121 138 } 122 139 123 // dump or plot the resulting projected positions124 if (psTraceGetLevel("psastro.dump") > 0) {125 psastroDumpRawstars (rawstars, fpa, chip);126 }127 128 if (psTraceGetLevel("psastro.plot") > 0) {129 psastroPlotRawstars (rawstars, fpa, chip, recipe);130 }140 // dump or plot the resulting projected positions 141 if (psTraceGetLevel("psastro.dump") > 0) { 142 psastroDumpRawstars (rawstars, fpa, chip); 143 } 144 145 if (psTraceGetLevel("psastro.plot") > 0) { 146 psastroPlotRawstars (rawstars, fpa, chip, recipe); 147 } 131 148 } 132 149 } 133 150 } 151 152 if (DEBUG) psastroDumpCorners ("corners.up.guess2.dat", "corners.dn.guess2.dat", fpa); 134 153 135 154 // how many total sources are available to us? 136 155 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NTOTSTAR", PS_META_REPLACE, "", *nStars); 137 156 if (*nStars == 0) { 138 psLogMsg ("psastro", 2, "no sources available for astrometry\n");139 psFree (view);140 return true;141 } 142 143 psLogMsg ("psastro", 2, "loaded raw data from %f,%f to %f,%f\n", 144 DEG_RAD*RAmin, DEG_RAD*DECmin, 145 DEG_RAD*RAmax, DEG_RAD*DECmax);157 psLogMsg ("psastro", 2, "no sources available for astrometry\n"); 158 psFree (view); 159 return true; 160 } 161 162 psLogMsg ("psastro", 2, "loaded raw data from %f,%f to %f,%f\n", 163 DEG_RAD*RAmin, DEG_RAD*DECmin, 164 DEG_RAD*RAmax, DEG_RAD*DECmax); 146 165 147 166 psMetadataAddF32 (recipe, PS_LIST_TAIL, "RA_MIN", PS_META_REPLACE, "", RAmin); … … 149 168 psMetadataAddF32 (recipe, PS_LIST_TAIL, "DEC_MIN", PS_META_REPLACE, "", DECmin); 150 169 psMetadataAddF32 (recipe, PS_LIST_TAIL, "DEC_MAX", PS_META_REPLACE, "", DECmax); 170 171 psMetadataAddVector (input->fpa->analysis, PS_LIST_TAIL, "CORNER.L", PS_META_REPLACE, "corner pixel", cornerL); 172 psMetadataAddVector (input->fpa->analysis, PS_LIST_TAIL, "CORNER.M", PS_META_REPLACE, "corner pixel", cornerM); 173 psMetadataAddVector (input->fpa->analysis, PS_LIST_TAIL, "CORNER.P", PS_META_REPLACE, "corner pixel", cornerP); 174 psMetadataAddVector (input->fpa->analysis, PS_LIST_TAIL, "CORNER.Q", PS_META_REPLACE, "corner pixel", cornerQ); 175 psMetadataAddVector (input->fpa->analysis, PS_LIST_TAIL, "CORNER.R", PS_META_REPLACE, "corner pixel", cornerR); 176 psMetadataAddVector (input->fpa->analysis, PS_LIST_TAIL, "CORNER.D", PS_META_REPLACE, "corner pixel", cornerD); 177 178 psFree (cornerL); 179 psFree (cornerM); 180 psFree (cornerP); 181 psFree (cornerQ); 182 psFree (cornerR); 183 psFree (cornerD); 151 184 152 185 psFree (view); … … 168 201 pmHDU *hdu = pmFPAviewThisHDU (view, fpa); 169 202 if (bilevelAstrometry) { 170 if (!pmAstromReadBilevelChip (chip, hdu->header)) {171 psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 172 return false;173 } 203 if (!pmAstromReadBilevelChip (chip, hdu->header)) { 204 psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 205 return false; 206 } 174 207 } else { 175 if (!pmAstromReadWCS (fpa, chip, hdu->header, pixelScale)) {176 psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 177 return false;178 } 208 if (!pmAstromReadWCS (fpa, chip, hdu->header, pixelScale)) { 209 psWarning("Could not get WCS information from header for chip %d, skipping", view->chip); 210 return false; 211 } 179 212 } 180 213 return true; … … 190 223 // load mosaic-level astrometry? 191 224 if (phu) { 192 char *ctype = psMetadataLookupStr (NULL, phu->header, "CTYPE1");193 if (ctype) {194 *bilevelAstrometry = !strcmp (&ctype[4], "-DIS");195 }225 char *ctype = psMetadataLookupStr (NULL, phu->header, "CTYPE1"); 226 if (ctype) { 227 *bilevelAstrometry = !strcmp (&ctype[4], "-DIS"); 228 } 196 229 } 197 230 if (*bilevelAstrometry) { 198 pmAstromReadBilevelMosaic (fpa, phu->header);199 } 231 pmAstromReadBilevelMosaic (fpa, phu->header); 232 } 200 233 psFree (view); 201 234 return true; 202 235 } 236 237 // we made a guess at the beginning; how does the guess compare with the result? 238 bool psastroAstromGuessCheck (pmConfig *config) { 239 240 bool status; 241 242 // select the input data sources 243 pmFPAfile *input = psMetadataLookupPtr (NULL, config->files, "PSASTRO.INPUT"); 244 if (!input) { 245 psError(PSASTRO_ERR_CONFIG, true, "Can't find input data"); 246 return false; 247 } 248 249 pmFPA *fpa = input->fpa; 250 251 psVector *cornerLo = psMetadataLookupPtr (&status, input->fpa->analysis, "CORNER.L"); 252 psVector *cornerMo = psMetadataLookupPtr (&status, input->fpa->analysis, "CORNER.M"); 253 psVector *cornerPo = psMetadataLookupPtr (&status, input->fpa->analysis, "CORNER.P"); 254 psVector *cornerQo = psMetadataLookupPtr (&status, input->fpa->analysis, "CORNER.Q"); 255 psVector *cornerRo = psMetadataLookupPtr (&status, input->fpa->analysis, "CORNER.R"); 256 psVector *cornerDo = psMetadataLookupPtr (&status, input->fpa->analysis, "CORNER.D"); 257 258 if (cornerLo->n < 3) return true; 259 260 psVector *cornerLn = psVectorAllocEmpty (100, PS_TYPE_F32); 261 psVector *cornerMn = psVectorAllocEmpty (100, PS_TYPE_F32); 262 psVector *cornerPn = psVectorAllocEmpty (100, PS_TYPE_F32); 263 psVector *cornerQn = psVectorAllocEmpty (100, PS_TYPE_F32); 264 psVector *cornerRn = psVectorAllocEmpty (100, PS_TYPE_F32); 265 psVector *cornerDn = psVectorAllocEmpty (100, PS_TYPE_F32); 266 267 if (DEBUG) psastroDumpCorners ("corners.up.guess3.dat", "corners.dn.guess3.dat", fpa); 268 269 pmChip *chip = NULL; 270 pmFPAview *view = pmFPAviewAlloc (0); 271 272 while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) { 273 if (!chip->process || !chip->file_exists || !chip->data_exists) { continue; } 274 275 psPlane ptCH, ptFP, ptTP; 276 psSphere ptSky; 277 278 ptCH.x = 0; 279 ptCH.y = 0; 280 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 281 psPlaneTransformApply (&ptTP, fpa->toTPA, &ptFP); 282 psDeproject (&ptSky, &ptTP, fpa->toSky); 283 psLogMsg ("psastro", 3, "0,0 pix for chip %3d = %f,%f\n", view->chip, DEG_RAD*ptSky.r, DEG_RAD*ptSky.d); 284 285 // new corner locations based on the calibrated astrometry 286 psVectorAppend (cornerLn, ptFP.x); 287 psVectorAppend (cornerMn, ptFP.y); 288 psVectorAppend (cornerPn, ptTP.x); 289 psVectorAppend (cornerQn, ptTP.y); 290 psVectorAppend (cornerRn, ptSky.r); 291 psVectorAppend (cornerDn, ptSky.d); 292 } 293 294 // compare the old R,D values projected to the same tangent plane as the new R,D values: 295 296 psVector *cornerPs = psVectorAllocEmpty (100, PS_TYPE_F32); 297 psVector *cornerQs = psVectorAllocEmpty (100, PS_TYPE_F32); 298 299 for (int i = 0; i < cornerRo->n; i++) { 300 301 psPlane ptTP; 302 psSphere ptSky; 303 304 ptSky.r = cornerRo->data.F32[i]; 305 ptSky.d = cornerDo->data.F32[i]; 306 307 psProject (&ptTP, &ptSky, fpa->toSky); 308 psVectorAppend (cornerPs, ptTP.x); 309 psVectorAppend (cornerQs, ptTP.y); 310 } 311 312 psPlaneTransform *map = psPlaneTransformAlloc (1, 1); 313 map->x->coeffMask[1][1] = PS_POLY_MASK_SET; 314 map->y->coeffMask[1][1] = PS_POLY_MASK_SET; 315 316 psVectorFitPolynomial2D (map->x, NULL, 0, cornerPn, NULL, cornerPs, cornerQs); 317 psVectorFitPolynomial2D (map->y, NULL, 0, cornerQn, NULL, cornerPs, cornerQs); 318 319 // apply the linear fit... 320 psVector *cornerPf = psPolynomial2DEvalVector (map->x, cornerPs, cornerQs); 321 psVector *cornerQf = psPolynomial2DEvalVector (map->y, cornerPs, cornerQs); 322 323 // ...and calculate the residual between Pn,Qn and Pf,Qf 324 psVector *cornerPd = (psVector *) psBinaryOp (NULL, cornerPn, "-", cornerPf); 325 psVector *cornerQd = (psVector *) psBinaryOp (NULL, cornerQn, "-", cornerQf); 326 327 psStats *statsP = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 328 psStats *statsQ = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 329 330 psVectorStats (statsP, cornerPd, NULL, NULL, 0); 331 psVectorStats (statsQ, cornerQd, NULL, NULL, 0); 332 333 float angle = atan2 (map->y->coeff[1][0], map->x->coeff[1][0]); 334 float scale = hypot (map->y->coeff[1][0], map->x->coeff[1][0]); 335 336 psLogMsg ("psastro", 3, "boresite offset : %f,%f\n", map->x->coeff[0][0], map->y->coeff[0][0]); 337 psLogMsg ("psastro", 3, "boresite angle : %f, scale: %f", angle*PS_DEG_RAD, scale); 338 psLogMsg ("psastro", 3, "boresite scatter : %f,%f\n", statsP->sampleStdev, statsQ->sampleStdev); 339 340 // write the elapsed time here; this will be updated in psastroMosaicAstrometry, if called 341 psMetadata *header = psMetadataLookupMetadata (&status, input->fpa->analysis, "PSASTRO.HEADER"); 342 if (!header) { 343 header = psMetadataAlloc(); 344 psMetadataAddMetadata (input->fpa->analysis, PS_LIST_TAIL, "PSASTRO.HEADER", PS_META_REPLACE, "psastro header stats", header); 345 psFree (header); // drop this reference 346 } 347 348 psMetadataAddF32 (header, PS_LIST_TAIL, "AST_R0", PS_META_REPLACE, "boresite offset in RA (TP units)", map->x->coeff[0][0]); 349 psMetadataAddF32 (header, PS_LIST_TAIL, "AST_D0", PS_META_REPLACE, "boresite offset in DEC (TP units)", map->y->coeff[0][0]); 350 psMetadataAddF32 (header, PS_LIST_TAIL, "AST_T0", PS_META_REPLACE, "boresite angle (degrees)", angle*PS_DEG_RAD); 351 psMetadataAddF32 (header, PS_LIST_TAIL, "AST_S0", PS_META_REPLACE, "boresite scale correction", scale); 352 psMetadataAddF32 (header, PS_LIST_TAIL, "AST_RS", PS_META_REPLACE, "boresite scatter in RA (TP units)", statsP->sampleStdev); 353 psMetadataAddF32 (header, PS_LIST_TAIL, "AST_DS", PS_META_REPLACE, "boresite scatter in DEC (TP units)", statsQ->sampleStdev); 354 355 if (0) { 356 FILE *f = fopen ("corners.dat", "w"); 357 for (int i = 0; i < cornerRo->n; i++) { 358 fprintf (f, "%10.6f %10.6f %9.2f %9.2f %9.2f %9.2f | %10.6f %10.6f %9.2f %9.2f %9.2f %9.2f\n", 359 cornerRn->data.F32[i], cornerDn->data.F32[i], cornerPn->data.F32[i], cornerQn->data.F32[i], cornerLn->data.F32[i], cornerMn->data.F32[i], 360 cornerRo->data.F32[i], cornerDo->data.F32[i], cornerPo->data.F32[i], cornerQo->data.F32[i], cornerLo->data.F32[i], cornerMo->data.F32[i]); 361 } 362 fclose (f); 363 } 364 365 psFree (cornerPf); 366 psFree (cornerQf); 367 psFree (cornerPd); 368 psFree (cornerQd); 369 370 psFree (statsP); 371 psFree (statsQ); 372 373 psFree (cornerLn); 374 psFree (cornerMn); 375 psFree (cornerPn); 376 psFree (cornerQn); 377 psFree (cornerRn); 378 psFree (cornerDn); 379 psFree (cornerPs); 380 psFree (cornerQs); 381 psFree (map); 382 psFree (view); 383 384 385 return true; 386 }
Note:
See TracChangeset
for help on using the changeset viewer.
