Changeset 5560 for trunk/psastro/src/psastroUtils.c
- Timestamp:
- Nov 21, 2005, 11:03:53 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/psastro/src/psastroUtils.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psastro/src/psastroUtils.c
r5510 r5560 1 1 # include "psastro.h" 2 3 // crude function to load CMP data (header + ascii) 4 // XXX EAM : assumes fixed line, expects NSTARS entries 5 psArrray *pmSourcesReadCMP (psMetadata **header, char *filename) { 6 7 psMetadata *myHeader; 8 char line[80]; 9 10 psFits *fits = psFitsAlloc (filename); 11 myHeader = psFitsReadHeader (fits); 12 psFree (fits); 13 14 // how many lines in the header? 15 // XXX EAM : is this calculation robust? 16 nLines = myHeader->list->n; 17 nBytes = nLines * 80; 18 if (nBytes % 2880) { 19 nBlock = 1 + (int)(nBytes / 2880); 20 nBytes = nBlock * 2880; 21 } 22 23 // re-open, seek to end of header 24 FILE *f = fopen (filename, "r"); 25 if (f == NULL) { 26 psLogMsg ("pmSourcesReadCMP", 3, "can't open output file for input %s\n", filename); 27 return NULL; 28 } 29 fseek (f, nBytes, SEEK_SET); 30 31 // prepare array to store data 32 nStars = psMetadataLookupS32 (&status, myHeader, "NSTARS"); 33 psArray *stars = psArrayAlloc (nStars); 34 stars->n = 0; 35 36 // we have fixed bytes / line : use that info 37 for (i = 0; i < nStars; i++) { 38 fread (line, 1, 67, f); 39 sscanf (line, "%lf %lf %lf %lf", &X, &Y, &Mag, &dMag); 40 41 pmAstromObj *obj = pmAstromObjAlloc (); 42 obj->pix.X = X; 43 obj->pix.Y = Y; 44 obj->pix.Mag = Mag; 45 obj->pix.dMag = dMag; 46 psArrayAdd (stars, obj, 100); 47 } 48 fclose (f); 49 50 *header = myHeader; 51 return (stars); 2 # define RENORM 0 3 4 bool testWriteRaw (char *filename, psArray *sources); 5 6 void psastroDumpStars (psArray *sources) { 7 8 for (int i = 0; i < sources->n; i++) { 9 pmAstromObj *star = sources->data[i]; 10 11 fprintf (stderr, "%8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %10.6f %10.6f %8.2f %8.2f\n", 12 star->pix.x, star->pix.y, 13 star->cell.x, star->cell.y, 14 star->chip.x, star->chip.y, 15 star->FP.x, star->FP.y, 16 star->TP.x, star->TP.y, 17 star->sky.r*DEG_RAD, star->sky.d*DEG_RAD, 18 star->Mag, star->dMag); 19 } 52 20 } 53 21 54 22 // sort by mag (descending) 55 int p sastroSortByMag (const void **a, const void **b)23 int pmAstromObjSortByMag (const void **a, const void **b) 56 24 { 57 pmSource *A = *(pmSource **)a; 58 pmSource *B = *(pmSource **)b; 59 60 psF32 fA = (A->moments == NULL) ? 0 : A->moments->SN; 61 psF32 fB = (B->moments == NULL) ? 0 : B->moments->SN; 62 if (isnan (fA)) fA = 0; 63 if (isnan (fB)) fB = 0; 64 65 psF32 diff = fA - fB; 25 pmAstromObj *A = *(pmAstromObj **)a; 26 pmAstromObj *B = *(pmAstromObj **)b; 27 28 psF32 diff = A->Mag - B->Mag; 66 29 if (diff > FLT_EPSILON) return (-1); 67 30 if (diff < FLT_EPSILON) return (+1); … … 69 32 } 70 33 71 psArray *psastroSelectBrightStars (pmFPA *inFPA, psMetadata *config) {72 73 pmFPA *sbFPA = pmFPACopy (fpa);34 bool psastroSelectBrightStars (pmFPA *fpa, psMetadata *config) { 35 36 bool status; 74 37 75 38 // add exclusions for objects on some basis? 76 int MAX_NSTARS = pmMetadataLookupS32 (&status, config, "MAX_NSTARS"); 77 78 for (int i = 0; i < inFPA->chips->n; i++) { 79 pmChip *inChip = inFPA->chips->data[i]; 80 pmChip *sbChip = sbFPA->chips->data[i]; 81 for (int j = 0; j < Ncells; j++) { 82 pmCell *inCell = inChip->cells->data[j]; 83 o pmCell *sbCell = sbChip->cells->data[j]; 84 for (int k = 0; k < Nreadouts; k++) { 85 pmReadout *inReadout = inCell->readouts->data[k]; 86 pmReadout *sbReadout = sbCell->readouts->data[k]; 87 88 inReadout->stars = psArraySort (inReadout->stars, psastroSortByMag); 89 90 nSubset = PS_MIN (MAX_NSTARS, stars->n); 91 92 psArray *subset = psArrayAlloc (nSubset); 93 94 for (int i = 0; i < nSubset; i++) { 95 subset->data[i] = inReadout->stars->data[i]; 96 } 97 sbReadout->stars = subset; 98 } 99 } 100 } 101 return (subset); 102 } 103 104 // fake this by loading from a text file 105 psArray *psastroLoadReference (char *filename) { 106 107 psMetadata *myHeader; 108 char line[80]; 109 110 psFits *fits = psFitsAlloc (filename); 111 myHeader = psFitsReadHeader (fits); 112 psFree (fits); 113 114 // how many lines in the header? 115 // XXX EAM : is this calculation robust? 116 nLines = header->list->n; 117 nBytes = nLines * 80; 118 if (nBytes % 2880) { 119 nBlock = 1 + (int)(nBytes / 2880); 120 nBytes = nBlock * 2880; 121 } 122 123 // re-open, seek to end of header 124 FILE *f = fopen (filename, "r"); 125 if (f == NULL) { 126 psLogMsg ("pmSourcesReadCMP", 3, "can't open output file for input %s\n", filename); 127 return NULL; 128 } 129 fseek (f, nBytes, SEEK_SET); 130 131 // prepare array to store data 132 nStars = psMetadataLookupS32 (&status, myHeader, "NSTARS"); 133 psArray *stars = psArrayAlloc (nStars); 134 stars->n = 0; 135 136 // we have fixed bytes / line : use that info 137 for (i = 0; i < nStars; i++) { 138 fread (line, 1, 67, f); 139 sscanf (line, "%lf %lf %lf %lf", &X, &Y, &Mag, &dMag); 140 141 pmAstromObj *obj = pmAstromObjAlloc (X, Y, Mag, dMag); 142 psArrayAdd (stars, obj, 100); 143 } 144 fclose (f); 145 146 *header = myHeader; 147 return (stars); 148 } 149 150 pmFPA *pmFPACopy (pmFPA *inFPA) { 151 152 pmFPA *fpa = pmFPAAlloc (); 153 154 fpa->toSky = psMemCopy (inFPA->toSky); 155 fpa->toTPA = psMemCopy (inFPA->toTPA); 156 fpa->fromTPA = psMemCopy (inFPA->fromTPA); 157 158 fpa->chips = psArrayAlloc (inFPA->chips->n); 159 for (int i = 0; i < inFPA->chips->n; i++) { 160 161 pmChip *inChip = inFPA->chips->data[i]; 162 163 pmChip *chip = pmChipAlloc (); 164 chip->fpa = fpa; // assign parent fpa (view only; don't free) 165 166 chip->toFPA = psMemCopy (inChip->toFPA); 167 chip->fromFPA = psMemCopy (inChip->fromFPA); 168 169 chip->cells = psArrayAlloc (inChip->cells->n); 170 for (int j = 0; j < Ncells; j++) { 171 172 pmCell *inCell = inChip->cells->data[j]; 173 174 pmCell *cell = pmCellAlloc (); 175 cell->chip = chip; // assign parent chip (view only; don't free) 176 177 cell->header = psMemCopy (inCell->header); 178 cell->toChip = psMemCopy (inCell->toChip); 179 180 cell->readouts = psArrayAlloc (inCell); 181 for (int k = 0; k < Nreadouts; k++) { 182 183 pmReadout *inReadout = inCell->readouts->data[k]; 184 185 pmReadout *readout = pmReadoutAlloc (); 186 187 *readout = *inReadout; 188 readout->stars = NULL; 189 190 cell->readouts->data[k] = readout; 191 } 192 chip->cells->data[j] = cell; 193 } 194 fpa->chips->data[i] = chip; 195 } 196 return (fpa); 197 } 198 199 bool psastroProjectFPA (pmFPA *fpa, bool toSky) { 39 int MAX_NSTARS = psMetadataLookupS32 (&status, config, "PSASTRO.STARS.MAX"); 200 40 201 41 for (int i = 0; i < fpa->chips->n; i++) { … … 205 45 for (int k = 0; k < cell->readouts->n; k++) { 206 46 pmReadout *readout = cell->readouts->data[k]; 207 if (toSky) { 208 psastroProjectRawstars (readout->stars, readout); 209 } else { 210 psastroProjectRefstars (readout->stars, readout); 47 48 psArray *stars = psMetadataLookupPtr (&status, readout->analysis, "STARS.FULLSET"); 49 stars = psArraySort (stars, pmAstromObjSortByMag); 50 51 int nSubset = PS_MIN (MAX_NSTARS, stars->n); 52 psArray *subset = psArrayAlloc (nSubset); 53 54 for (int i = 0; i < nSubset; i++) { 55 subset->data[i] = stars->data[i]; 211 56 } 57 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "STARS.SUBSET", PS_DATA_ARRAY, "stars from analysis", subset); 212 58 } 213 59 } … … 215 61 return true; 216 62 } 217 218 bool psastroProjectRawstars (psArray *stars, pmReadout *readout) { 219 220 pmCell *cell = readout->cell; 221 pmChip *chip = cell->chip; 222 pmFPA *fpa = chip->cell; 223 224 for (int i = 0; i < readout->stars->n; i++) { 225 pmAstromObj *star = readout->stars->data[i]; 226 psCoordReadoutToCell (&star->cell, &star->pix, readout); 227 psCoordCellToChip (&star->chip, &star->cell, cell); 228 psCoordChipToFP (&star->FP, &star->chip, chip); 229 psCoordFPtoTP (&star->TP, &star->FP, fpa); 230 psCoordTPtoSky (&star->sky, &star->TP, fpa); 231 } 232 return true; 233 } 234 235 bool psastroProjectRefstars (psArray *stars, pmReadout *readout) { 236 237 pmCell *cell = readout->cell; 238 pmChip *chip = cell->chip; 239 pmFPA *fpa = chip->cell; 240 241 for (int i = 0; i < stars->n; i++) { 242 pmAstromObj *star = stars->data[i]; 243 244 psCoordSkytoTP (&star->TP, &star->sky, fpa); 245 psCoordTPtoFP (&star->FP, &star->TP, fpa); 246 psCoordFPtoChip (&star->chip, &star->FP, chip); 247 psCoordChipToCell (&star->cell, &star->chip, cell); 248 psCoordReadoutToCell (&star->pix, &star->cell, readout); 249 } 250 return true; 251 } 252 63 64 pmFPA *pmFPACopyAstrom (pmFPA *inFPA) { 65 66 pmFPA *fpa = pmFPAAlloc (NULL, NULL); 67 68 // copy FPA astrometry data 69 fpa->toSky = psProjectionCopy (inFPA->toSky); 70 fpa->toTPA = psPlaneDistortCopy (inFPA->toTPA); 71 fpa->fromTPA = psPlaneDistortCopy (inFPA->fromTPA); 72 73 psArrayRealloc (fpa->chips, inFPA->chips->n); 74 for (int i = 0; i < inFPA->chips->n; i++) { 75 pmChip *inChip = inFPA->chips->data[i]; 76 pmChip *chip = pmChipAlloc (fpa); 77 78 // copy Chip astrometry data 79 chip->toFPA = psPlaneTransformCopy (inChip->toFPA); 80 chip->fromFPA = psPlaneTransformCopy (inChip->fromFPA); 81 82 psArrayRealloc (chip->cells, inChip->cells->n); 83 for (int j = 0; j < inChip->cells->n; j++) { 84 pmCell *inCell = inChip->cells->data[j]; 85 pmCell *cell = pmCellAlloc (chip); 86 87 // cell.header is a view on inCell.header 88 cell->header = psMemCopy (inCell->header); 89 90 // copy Cell astrometry data 91 cell->toChip = psPlaneTransformCopy (inCell->toChip); 92 93 psArrayRealloc (cell->readouts, inCell->readouts->n); 94 for (int k = 0; k < inCell->readouts->n; k++) { 95 pmReadout *inReadout = inCell->readouts->data[k]; 96 pmReadout *readout = pmReadoutAlloc (cell); 97 98 // copy Readout data 99 *readout = *inReadout; 100 101 cell->readouts->data[k] = readout; 102 } 103 chip->cells->data[j] = cell; 104 } 105 fpa->chips->data[i] = chip; 106 } 107 return (fpa); 108 } 109 253 110 // measure per-chip astrometry terms 254 111 bool psastroChipAstrom (pmFPA *fpa, psMetadata *config) { 255 112 256 pmFPA *raw = pmFPACopy (fpa); 113 bool status; 114 psArray *match; 115 pmAstromStats stats; 116 117 // save the raw astrometry for later reference 118 pmFPA *raw = pmFPACopyAstrom (fpa); 257 119 258 120 // first pass: measure the per-chip solutions, modify the chip.toFPA terms … … 282 144 pmReadout *readout = cell->readouts->data[k]; 283 145 284 // use the header & config info to project refstars on the focal plane 146 // pull out the SUBSET rawstars (a view) 147 psArray *rawstars = psMetadataLookupPtr (&status, readout->analysis, "STARS.SUBSET"); 148 149 // project the rawstars to the current best guess astrometry 150 psastroProjectRawstars (rawstars, readout); 151 152 // use the header & config info to project refstars onto the focal plane 285 153 psastroProjectRefstars (refstars, readout); 286 154 155 testWriteRaw ("ref.inp", refstars); 156 testWriteRaw ("raw.inp", rawstars); 157 158 // fprintf (stderr, "rawstars:\n"); 159 // psastroDumpStars (rawstars); 160 // fprintf (stderr, "refstars:\n"); 161 // psastroDumpStars (refstars); 162 287 163 // find initial offset / rotation 288 stat = pmAstromGridMatch (readout->stars, refstars, config);164 stats = pmAstromGridMatch (rawstars, refstars, config); 289 165 290 166 // adjust the chip.toFPA terms only 291 pmAstromGridApply (chip->toFPA, stat); 167 pmAstromGridApply (chip->toFPA, stats); 168 chip->fromFPA = p_psPlaneTransformLinearInvert (chip->toFPA); 292 169 293 170 // use fit result to re-project rawstars 294 psastroProjectRawstars (readout->stars, readout); 295 psastroProjectRefstars (refstars, readout); 171 psastroProjectRawstars (rawstars, readout); 172 psastroProjectRefstars (refstars, readout); 173 174 testWriteRaw ("ref.dat", refstars); 175 testWriteRaw ("raw.dat", rawstars); 296 176 297 177 // use small radius to match stars 298 match = pmAstromRadiusMatch (rawstars, refstars, options);178 match = pmAstromRadiusMatch (rawstars, refstars, config); 299 179 300 180 // fit astrometric terms 301 pmAstromMatch edListFit (chip->toFPA, readout->stars, refstars, match, options);181 pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, config); 302 182 } 303 183 } … … 306 186 // second stage: re-normalize the chip terms, passing the 307 187 // average rotation and offset values to the fpa.toSky 308 309 # if (0) 310 // code disabled for now 311 // this is not as trivial as it seems at first: 312 // applying a new rotation to the FPA implies changes to the 313 // (x,y) reference coordinates for the chips as well as a rotation 314 // I need to calculate both the x,y offset effect and the rotation 315 // in one step. what about the effect of higher order terms in either 316 // the chip.toFPA or the fpa.toTPA? 317 // this calculation also needs to account for scale effects between the 318 // fpa and the chips. 319 320 // calculate the average rotation and boresite offset relative to raw 321 for (int i = 0; i < fpa->chips->n; i++) { 322 pmChip *iChip = raw->chips->data[i]; 323 pmChip *oChip = fpa->chips->data[i]; 324 325 T1 = psPlaneTransformGetRotation (iChip->toFPA); 326 T2 = psPlaneTransformGetRotation (oChip->toFPA); 327 dT += T1 - T2; 328 dN ++; 329 188 if (RENORM) { 189 190 // this code is needed for the mosastro stage, with multiple chip solutions 191 192 double dX, dY, dT, dN; 193 dX = dY = dT = dN = 0; 194 195 psPlane origin, P1, P2; 196 origin.x = 0; 197 origin.y = 0; 198 199 // calculate the average rotation and boresite offset relative to raw 200 for (int i = 0; i < fpa->chips->n; i++) { 201 pmChip *iChip = raw->chips->data[i]; 202 pmChip *oChip = fpa->chips->data[i]; 203 204 // offset of chip 205 psCoordChipToFPA (&P1, &origin, iChip); 206 psCoordChipToFPA (&P2, &origin, oChip); 207 dX += (P2.x - P1.x); 208 dY += (P2.y - P1.y); 209 210 // get parity-independent rotations for old and new solutions 211 double T1 = psPlaneTransformGetRotation (iChip->toFPA); 212 double T2 = psPlaneTransformGetRotation (oChip->toFPA); 213 dT += T2 - T1; 214 dN ++; 215 } 216 217 dT /= dN; 218 dX /= dN; 219 dY /= dN; 220 221 // R(T) 222 double PC1_1 = fpa->toTPA->x->coeff[1][0][0][0]; 223 double PC1_2 = fpa->toTPA->x->coeff[0][1][0][0]; 224 double PC2_1 = fpa->toTPA->y->coeff[1][0][0][0]; 225 double PC2_2 = fpa->toTPA->y->coeff[0][1][0][0]; 226 227 // R(dT) 228 double dPC1_1 = +cos (dT); 229 double dPC1_2 = +sin (dT); 230 double dPC2_1 = -sin (dT); 231 double dPC2_2 = +cos (dT); 232 233 // R'(T) = R(T) * R(dT) 234 double pc1_1 = PC1_1*dPC1_1 + PC1_2*dPC2_1; 235 double pc1_2 = PC1_1*dPC1_2 + PC1_2*dPC2_2; 236 double pc2_1 = PC2_1*dPC1_1 + PC2_2*dPC2_1; 237 double pc2_2 = PC2_1*dPC1_2 + PC2_2*dPC2_2; 238 239 double det = 1.0 / (pc1_1*pc2_2 - pc1_2*pc2_1); 240 241 // R'(-T) (matrix inverse, not just rotation inverse -- keeps parity) 242 double pi1_1 = +pc2_2 * det; 243 double pi1_2 = -pc1_2 * det; 244 double pi2_1 = -pc2_1 * det; 245 double pi2_2 = +pc1_1 * det; 246 247 // apply the new modifcations in rotation and boresite 248 for (int i = 0; i < fpa->chips->n; i++) { 249 pmChip *oChip = fpa->chips->data[i]; 250 251 // r(T) 252 double pr1_1 = oChip->toFPA->x->coeff[1][0]; 253 double pr1_2 = oChip->toFPA->x->coeff[0][1]; 254 double pr2_1 = oChip->toFPA->y->coeff[1][0]; 255 double pr2_2 = oChip->toFPA->y->coeff[0][1]; 256 257 // ri'(T) = R(T) r(t) 258 double ri1_1 = PC1_1*pr1_1 + PC1_2*pr2_1; 259 double ri1_2 = PC1_1*pr1_2 + PC1_2*pr2_2; 260 double ri2_1 = PC2_1*pr1_1 + PC2_2*pr2_1; 261 double ri2_2 = PC2_1*pr1_2 + PC2_2*pr2_2; 262 263 // r'(T) = R'(-T) ri'(T) 264 oChip->toFPA->x->coeff[1][0] = pi1_1*ri1_1 + pi1_2*ri2_1; 265 oChip->toFPA->x->coeff[0][1] = pi1_1*ri1_2 + pi1_2*ri2_2; 266 oChip->toFPA->y->coeff[1][0] = pi2_1*ri1_1 + pi2_2*ri2_1; 267 oChip->toFPA->y->coeff[0][1] = pi2_1*ri1_2 + pi2_2*ri2_2; 268 269 double dx = PC1_1*oChip->toFPA->x->coeff[0][0] + PC1_2*oChip->toFPA->y->coeff[0][0] + dX; 270 double dy = PC2_1*oChip->toFPA->x->coeff[0][0] + PC2_2*oChip->toFPA->y->coeff[0][0] + dY; 271 272 oChip->toFPA->x->coeff[0][0] = pi1_1*dx + pi1_2*dy; 273 oChip->toFPA->y->coeff[0][0] = pi2_1*dx + pi2_2*dy; 274 } 275 276 fpa->toTPA->x->coeff[0][0][0][0] -= dX; 277 fpa->toTPA->y->coeff[0][0][0][0] -= dY; 278 279 fpa->toTPA->x->coeff[1][0][0][0] = pc1_1; 280 fpa->toTPA->x->coeff[0][1][0][0] = pc1_2; 281 fpa->toTPA->y->coeff[1][0][0][0] = pc2_1; 282 fpa->toTPA->y->coeff[0][1][0][0] = pc2_2; 283 } 284 return true; 285 } 286 287 // returns the rotation term, forcing positive parity 288 double psPlaneTransformGetRotation (psPlaneTransform *map) { 289 290 if (map->x->nX < 1) return 0; 291 if (map->x->nY < 1) return 0; 292 293 if (map->y->nX < 1) return 0; 294 if (map->y->nY < 1) return 0; 295 296 double pc1_1 = map->x->coeff[1][0]; 297 double pc1_2 = map->x->coeff[0][1]; 298 double pc2_1 = map->y->coeff[1][0]; 299 double pc2_2 = map->y->coeff[0][1]; 300 301 double px = SIGN (pc1_1); 302 double py = SIGN (pc2_2); 303 304 // both x and y terms imply an angle. take the average 305 double t1 = -atan2 (px*pc1_2, px*pc1_1); 306 double t2 = +atan2 (py*pc2_1, py*pc2_2); 307 308 // careful near -pi,+pi boundary... 309 if (t1 - t2 > M_PI/2) t2 += 2*M_PI; 310 if (t2 - t1 > M_PI/2) t1 += 2*M_PI; 311 312 double theta = 0.5*(t1 + t2); 313 while (theta < M_PI) theta += 2*M_PI; 314 while (theta > M_PI) theta -= 2*M_PI; 315 316 return (theta); 317 } 318 319 // elixir-style pseudo FITS table (header + ascii list) 320 bool testWriteRaw (char *filename, psArray *sources) { 321 322 int i; 323 324 // re-open, add data to end of file 325 FILE *f = fopen (filename, "w"); 326 if (f == NULL) { 327 psLogMsg ("WriteSourceOBJ", 3, "can't open output file for output %s\n", filename); 328 return false; 329 } 330 331 for (i = 0; i < sources->n; i++) { 330 332 331 } 332 333 dT /= dN; 334 335 psPlaneTransformSetRotation (fpa->toTPA, dT); 336 337 // apply the new modifcations in rotation and boresite 338 for (int i = 0; i < fpa->chips->n; i++) { 339 pmChip *iChip = raw->chips->data[i]; 340 pmChip *oChip = fpa->chips->data[i]; 341 342 psPlaneTransformSetRotation (oChip->toFPA, -dT); 343 } 344 # endif 345 } 333 pmAstromObj *star = sources->data[i]; 334 335 fprintf (f, "%8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f %10.6f %10.6f %8.2f %8.2f\n", 336 star->pix.x, star->pix.y, 337 star->cell.x, star->cell.y, 338 star->chip.x, star->chip.y, 339 star->FP.x, star->FP.y, 340 star->TP.x, star->TP.y, 341 star->sky.r*DEG_RAD, star->sky.d*DEG_RAD, 342 star->Mag, star->dMag); 343 } 344 fclose (f); 345 return true; 346 }
Note:
See TracChangeset
for help on using the changeset viewer.
