Changeset 15201 for trunk/psastro/src/psastroOneChip.c
- Timestamp:
- Oct 3, 2007, 4:32:39 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psastro/src/psastroOneChip.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psastro/src/psastroOneChip.c
r13165 r15201 1 1 # include "psastroInternal.h" 2 2 3 # define REQUIRED_RECIPE_VALUE(VALUE, NAME, TYPE , MESSAGE)\3 # define REQUIRED_RECIPE_VALUE(VALUE, NAME, TYPE)\ 4 4 VALUE = psMetadataLookup##TYPE (&status, recipe, NAME); \ 5 5 if (!status) { \ 6 psError(PSASTRO_ERR_CONFIG, false, MESSAGE); \ 7 return false; } 6 psAbort ("Failed to find %s in recipe", NAME); } 8 7 9 8 bool psastroOneChip (pmFPA *fpa, pmChip *chip, psArray *refstars, psArray *rawstars, psMetadata *recipe, psMetadata *updates) { 10 9 11 10 bool status; 12 pmAstromStats *gridStats = NULL;13 11 pmAstromStats *stats = NULL; 14 12 15 // supplied radius is in pixels 16 REQUIRED_RECIPE_VALUE (double RADIUS, "PSASTRO.MATCH.RADIUS", F32, "Failed to lookup matching radius"); 13 // default value for match/fit : radius is in pixels 14 REQUIRED_RECIPE_VALUE (double RADIUS, "PSASTRO.MATCH.RADIUS", F32); 15 16 // run the match/fit sequence NITER times 17 REQUIRED_RECIPE_VALUE (int nIter, "PSASTRO.MATCH.FIT.NITER", S32); 17 18 18 19 // correct radius to FP units (physical pixel scale in microns per pixel) 19 REQUIRED_RECIPE_VALUE (double pixelScale, "PSASTRO.PIXEL.SCALE", F32 , "Failed to lookup pixel scale");20 REQUIRED_RECIPE_VALUE (double pixelScale, "PSASTRO.PIXEL.SCALE", F32); 20 21 RADIUS *= pixelScale; 21 22 22 23 // select the desired chip order 23 REQUIRED_RECIPE_VALUE (int order, "PSASTRO.CHIP.ORDER", S32 , "failed to find single-chip fit order\n");24 REQUIRED_RECIPE_VALUE (int order, "PSASTRO.CHIP.ORDER", S32); 24 25 25 26 // allowed limits for valid solutions 26 REQUIRED_RECIPE_VALUE (float maxError, "PSASTRO.MAX.ERROR", F32 , "failed to find single-chip max allowed error\n");27 REQUIRED_RECIPE_VALUE (int minNstar, "PSASTRO.MIN.NSTAR", S32 , "failed to find single-chip min allowed stars\n");27 REQUIRED_RECIPE_VALUE (float maxError, "PSASTRO.MAX.ERROR", F32); 28 REQUIRED_RECIPE_VALUE (int minNstar, "PSASTRO.MIN.NSTAR", S32); 28 29 29 30 // do we need to get a rough initial match? 30 REQUIRED_RECIPE_VALUE (bool gridSearch, "PSASTRO.GRID.SEARCH", Bool, "failed to find chip grid-search option\n"); 31 REQUIRED_RECIPE_VALUE (bool gridSearch, "PSASTRO.GRID.SEARCH", Bool); 32 33 // do we need to get a rough initial match? 34 REQUIRED_RECIPE_VALUE (int maxNstar, "PSASTRO.GRID.NSTAR.MAX", S32); 31 35 32 36 if (gridSearch) { 37 // generate the bright subset of maxNstar entries (note: rawstars is sorted by S/N) 38 psArray *gridStars = psArrayAlloc (PS_MIN (maxNstar, rawstars->n)); 39 for (int i = 0; (i < maxNstar) && (i < rawstars->n); i++) { 40 gridStars->data[i] = psMemIncrRefCounter (rawstars->data[i]); 41 } 42 33 43 // find initial offset / rotation 34 gridStats = pmAstromGridMatch (rawstars, refstars, recipe);44 pmAstromStats *gridStats = pmAstromGridMatch (gridStars, refstars, recipe); 35 45 if (gridStats == NULL) { 36 46 psLogMsg ("psastro", 3, "failed to find a grid match solution\n"); 47 psFree (gridStars); 37 48 return false; 38 49 } … … 40 51 41 52 // tweak the position by finding peak of matches stars 42 stats = pmAstromGridTweak ( rawstars, refstars, recipe, gridStats);53 stats = pmAstromGridTweak (gridStars, refstars, recipe, gridStats); 43 54 if (stats == NULL) { 44 55 psLogMsg ("psastro", 3, "failed to measure tweaked grid solution\n"); 45 56 psFree (gridStats); 57 psFree (gridStars); 46 58 return false; 47 59 } … … 51 63 pmAstromGridApply (chip->toFPA, stats); 52 64 psastroUpdateChipToFPA (fpa, chip, rawstars, refstars); 53 }54 55 // use small radius to match stars56 psArray *match = pmAstromRadiusMatchFP (rawstars, refstars, RADIUS);57 if (match == NULL) {58 psLogMsg ("psastro", 3, "failed to find radius-matched sources\n");59 psFree (stats);60 65 psFree (gridStats); 61 return false; 62 } 63 64 // modify the order to correspond to the actual number of matched stars: 65 if ((match->n < 11) && (order >= 3)) order = 2; 66 if ((match->n < 7) && (order >= 2)) order = 1; 67 if ((match->n < 4) && (order >= 1)) order = 0; 68 if (order < 1) { 69 psLogMsg ("psastro", 3, "insufficient stars or invalid order: %ld stars", match->n); 70 psFree (match); 71 psFree (stats); 72 psFree (gridStats); 73 return false; 74 } 75 76 // create output toFPA; set masks appropriate to the Elixir DVO astrometry format 77 psFree (chip->toFPA); 78 chip->toFPA = psPlaneTransformAlloc (order, order); 79 for (int i = 0; i <= chip->toFPA->x->nX; i++) { 80 for (int j = 0; j <= chip->toFPA->x->nY; j++) { 81 if (i + j > order) { 82 chip->toFPA->x->mask[i][j] = 1; 83 chip->toFPA->y->mask[i][j] = 1; 84 } 85 } 86 } 87 88 // XXX allow statitic to be set by the user 89 psStats *fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 90 // psStats *fitStats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 91 fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.CHIP.NSIGMA"); 92 fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.CHIP.NITER"); 93 94 // improved fit for astrometric terms 95 pmAstromFitResults *results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats); 96 if (!results) { 97 psLogMsg ("psastro", 3, "failed to perform the matched fit\n"); 98 psFree (match); 99 psFree (stats); 100 psFree (fitStats); 101 psFree (gridStats); 102 return false; 103 } 66 psFree (gridStars); 67 } 68 69 psArray *match = NULL; 70 psStats *fitStats = NULL; 71 pmAstromFitResults *results = NULL; 72 73 for (int iter = 0; iter < nIter; iter++) { 74 75 char name[128]; 76 77 sprintf (name, "PSASTRO.MATCH.RADIUS.N%d", iter); 78 float radius = psMetadataLookupF32 (&status, recipe, name); 79 radius *= pixelScale; 80 if (!status || (radius == 0.0)) { 81 radius = RADIUS; 82 } 83 84 85 // use small radius to match stars 86 match = pmAstromRadiusMatchFP (rawstars, refstars, radius); 87 if (match == NULL) { 88 psLogMsg ("psastro", 3, "failed to find radius-matched sources\n"); 89 psFree (stats); 90 return false; 91 } 92 93 // modify the order to correspond to the actual number of matched stars: 94 if ((match->n < 11) && (order >= 3)) order = 2; 95 if ((match->n < 7) && (order >= 2)) order = 1; 96 if ((match->n < 4) && (order >= 1)) order = 0; 97 if (order < 1) { 98 psLogMsg ("psastro", 3, "insufficient stars or invalid order: %ld stars", match->n); 99 psFree (match); 100 psFree (stats); 101 return false; 102 } 103 104 // create output toFPA; set masks appropriate to the Elixir DVO astrometry format 105 psFree (chip->toFPA); 106 chip->toFPA = psPlaneTransformAlloc (order, order); 107 for (int i = 0; i <= chip->toFPA->x->nX; i++) { 108 for (int j = 0; j <= chip->toFPA->x->nY; j++) { 109 if (i + j > order) { 110 chip->toFPA->x->mask[i][j] = 1; 111 chip->toFPA->y->mask[i][j] = 1; 112 } 113 } 114 } 115 116 // XXX allow statitic to be set by the user 117 // fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 118 fitStats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 119 fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.CHIP.NSIGMA"); 120 fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.CHIP.NITER"); 121 122 // improved fit for astrometric terms 123 results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats); 124 if (!results) { 125 psLogMsg ("psastro", 3, "failed to perform the matched fit\n"); 126 psFree (match); 127 psFree (stats); 128 psFree (fitStats); 129 return false; 130 } 104 131 132 // determine fromFPA transformation and apply new transformation to raw & ref stars 133 psastroUpdateChipToFPA (fpa, chip, rawstars, refstars); 134 135 if (iter < nIter - 1) { 136 psFree (fitStats); 137 psFree (results); 138 psFree (match); 139 } 140 141 // toSky converts from FPA & TPA units (microns) to sky units (radians) 142 float plateScale = 0.5*(fpa->toSky->Xs + fpa->toSky->Ys)*3600.0*PM_DEG_RAD; 143 // float astError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) * plateScale; 144 float astError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) * plateScale; 145 int astNstar = results->yStats->clippedNvalues; 146 psLogMsg ("psastro", PS_LOG_INFO, "pass %d, error: %f arcsec, Nstars: %d", iter, astError, astNstar); 147 } 148 149 150 105 151 // toSky converts from FPA & TPA units (microns) to sky units (radians) 106 152 float plateScale = 0.5*(fpa->toSky->Xs + fpa->toSky->Ys)*3600.0*PM_DEG_RAD; 107 153 108 154 // pixError is the average 1D scatter in pixels ('results' are in FPA units = microns) 109 float pixError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) / pixelScale;110 //float pixError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) / pixelScale;155 // float pixError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) / pixelScale; 156 float pixError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) / pixelScale; 111 157 112 158 // astError is the average 1D scatter in arcsec ('results' are in FPA units = microns) 113 float astError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) * plateScale;114 //float astError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) * plateScale;159 // float astError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) * plateScale; 160 float astError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) * plateScale; 115 161 int astNstar = results->yStats->clippedNvalues; 116 162 … … 140 186 psMetadataAddF32 (updates, PS_LIST_TAIL, "EQUINOX", PS_META_REPLACE, "equinox of ref catalog", 2000.0); // XXX this is bogus: should be defined based on equinox of refstars 141 187 142 // determine fromFPA transformation and apply new transformation to raw & ref stars143 psastroUpdateChipToFPA (fpa, chip, rawstars, refstars);188 // XXX drop from here : determine fromFPA transformation and apply new transformation to raw & ref stars 189 // psastroUpdateChipToFPA (fpa, chip, rawstars, refstars); 144 190 145 191 // XXX check if we correctly applied the new transformation: 146 192 if (psTraceGetLevel("psastro.dump") > 0) { 147 193 psastroDumpRawstars (rawstars, fpa, chip); 148 } 149 if (psTraceGetLevel("psastro.dump") > 0) { 194 psastroDumpMatchedStars ("match.dat", rawstars, refstars, match); 150 195 psastroDumpStars (refstars, "refstars.cal.dat"); 151 196 } 152 197 153 198 if (psTraceGetLevel("psastro.plot") > 0) { 154 psastroPlotOneChipFit (rawstars, refstars, match, re sults);199 psastroPlotOneChipFit (rawstars, refstars, match, recipe); 155 200 } 156 201 … … 159 204 psFree (results); 160 205 psFree (fitStats); 161 psFree (gridStats);162 206 return validSolution; 163 207 }
Note:
See TracChangeset
for help on using the changeset viewer.
