Changeset 5560 for trunk/psastro/src/pmAstromGrid.c
- Timestamp:
- Nov 21, 2005, 11:03:53 AM (21 years ago)
- File:
-
- 1 edited
-
trunk/psastro/src/pmAstromGrid.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psastro/src/pmAstromGrid.c
r5510 r5560 1 1 # include "pmAstrom.h" 2 2 3 static double maxOff set; // maximum allowed offset between lists, in raw pixels3 static double maxOffpix; // maximum allowed offset between lists, in raw pixels 4 4 static double Scale; // grid pixel scale 5 5 static double Offset; // deltas to pixels … … 7 7 // local function to convert x,y coords to grid bins 8 8 // it requires the globals defined above 9 static bool AstromGridBin (int * pOut, int *qOut, double dP, int dQ) {10 11 if (fabs(d P) > maxOffset) return false;12 if (fabs(d Q) > maxOffset) return false;13 14 * pOut = dP/ Scale + Offset;15 * qOut = dQ/ Scale + Offset;9 static bool AstromGridBin (int *dx, int *dy, double dX, double dY) { 10 11 if (fabs(dX) > maxOffpix) return false; 12 if (fabs(dY) > maxOffpix) return false; 13 14 *dx = dX / Scale + Offset; 15 *dy = dY / Scale + Offset; 16 16 return true; 17 17 } 18 18 19 // match two star lists20 pmAstromGridMatchStats pmAstromGridMatch (psArray *st1, psArray *st2, psMetadata *config) {21 22 double xMin, xMax, yMin, yMax;23 pmAstromObj *ob1, *ob2;24 25 pmAstromGridMatchStat minStat, newStat;26 psPlane center;27 28 // find center of the st2 field (focal-plane coords)29 xMin = yMin = +1e10;30 xMax = yMax = -1e10;31 for (int i = 0; i < st2->n; i++) {32 ob2 = (pmAstromObj *)st2->data[i];33 xMin = PS_MIN (ob2->FP.x, xMin);34 xMax = PS_MAX (ob2->FP.x, xMax);35 yMin = PS_MIN (ob2->FP.y, yMin);36 yMax = PS_MAX (ob2->FP.y, yMax);37 }38 center.x = 0.5*(xMin + xMax);39 center.y = 0.5*(yMin + yMax);40 41 double minAngle = psMetadataLookupF32 (&status, config, "GRID.MIN.ANGLE");42 double maxAngle = psMetadataLookupF32 (&status, config, "GRID.MAX.ANGLE");43 double delAngle = psMetadataLookupF32 (&status, config, "GRID.DEL.ANGLE");44 45 minStat.minMetric = 1e10;46 for (angle = minAngle; angle <= maxAngle; angle += delAngle) {47 st2r = pmAstromRotateObj (st2, center, angle);48 newStat = pmAstromGridMatchAngle (st1, st2r, config);49 newStat.angle = angle;50 newStat.center = center;51 if (newStat.minMetric < minStat.minMetric) {52 minStat = newStat;53 }54 psFree (st2r);55 }56 return (minStat);57 }58 59 19 // match the two lists using the binned delta-delta max 60 pmAstromGridMatchStats pmAstromGridMatchAngle (psArray *st1, psArray *st2, psMetadata *config) { 61 20 pmAstromStats pmAstromGridAngle (psArray *raw, psArray *ref, psMetadata *config) { 21 22 bool status; 62 23 int nPix; // size of matching grid 24 int nPixHalf; // half-size of matching grid 63 25 double dX, dY; // offset between a possible matched pair 64 26 int iX, iY; // corresponding grid bin 65 27 66 pmAstromObj *ob1, *ob2 // short-cut pointers to the objects67 pmAstrom GridMatchStats matchStats;// output match statistics28 pmAstromObj *ob1, *ob2; // short-cut pointers to the objects 29 pmAstromStats stats; // output match statistics 68 30 69 31 // max allowed offset in either X or Y directions 70 double gridOffset = psMetadataLookupF32 (&status, config, " GRID.OFFSET");32 double gridOffset = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.OFFSET"); 71 33 72 34 // sampling scale of the grid 73 double gridScale = psMetadataLookupF32 (&status, config, " GRID.SCALE");35 double gridScale = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.SCALE"); 74 36 75 37 // set the static scaling factors 76 nPix = (int)(gridOffset / gridScale + 0.5); // half-grid77 nPix = 2*nPix + 1;38 nPixHalf = (int)(gridOffset / gridScale + 0.5); // half-grid 39 nPix = 2*nPixHalf + 1; // full grid width 78 40 79 41 // these are globals used by p_pmAstromGridBin 80 maxOffpix = gridScale * (nPix + 0.5);42 maxOffpix = gridScale * (nPixHalf + 0.5); // max offset from true center 81 43 Offset = maxOffpix / gridScale; 82 44 Scale = gridScale; 83 45 84 // XXX EAM : can we assume the allocated image is init-ed?85 psImage *gridNP = psImageAlloc (nPix, nPix, PS_TYPE_ S32);46 // images used as accumulators for the loop below 47 psImage *gridNP = psImageAlloc (nPix, nPix, PS_TYPE_U32); 86 48 psImage *gridDX = psImageAlloc (nPix, nPix, PS_TYPE_F32); 87 49 psImage *gridDY = psImageAlloc (nPix, nPix, PS_TYPE_F32); 88 50 psImage *gridD2 = psImageAlloc (nPix, nPix, PS_TYPE_F32); 89 psImageInit (gridNP );90 psImageInit (gridDX );91 psImageInit (gridDY );92 psImageInit (gridD2 );51 psImageInit (gridNP, 0); 52 psImageInit (gridDX, 0); 53 psImageInit (gridDY, 0); 54 psImageInit (gridD2, 0); 93 55 94 56 // short-cut names for grid images 95 psS32 * NP = gridNP->data.S32;96 psF32 * DX = gridDP->data.F32;97 psF32 * DY = gridDQ->data.F32;98 psF32 * D2 = gridD2->data.F32;57 psS32 **NP = gridNP->data.S32; 58 psF32 **DX = gridDX->data.F32; 59 psF32 **DY = gridDY->data.F32; 60 psF32 **D2 = gridD2->data.F32; 99 61 100 62 // accumulate grids for focal plane (L,M) matches 101 for (int i = 0; i < st1->n; i++) {102 ob1 = (pmAstromObj *) st1->data[i];103 for (int j = 0; j < st2->n; j++) {104 ob2 = (pmAstromObj *) st2->data[i];63 for (int i = 0; i < raw->n; i++) { 64 ob1 = (pmAstromObj *)raw->data[i]; 65 for (int j = 0; j < ref->n; j++) { 66 ob2 = (pmAstromObj *)ref->data[j]; 105 67 dX = ob1->FP.x - ob2->FP.x; 106 68 dY = ob1->FP.y - ob2->FP.y; 107 69 70 // fprintf (stderr, "dX,dY: %8.2f %8.2f : %8.2f %8.2f : %8.2f %8.2f\n", dX, dY, ob1->FP.x, ob2->FP.x, ob1->FP.y, ob2->FP.y); 108 71 // find bin coordinates for this delta-delta 109 if (! p_pmAstromGridBin (&iX, &iY, dX, dY)) {72 if (!AstromGridBin (&iX, &iY, dX, dY)) { 110 73 continue; // matched pair is too far offset 111 112 74 } 113 75 114 76 // accumulate bin stats 115 77 NP[iY][iX] ++; 116 D P[iY][iX] += dX;117 D Q[iY][iX] += dY;78 DX[iY][iX] += dX; 79 DY[iY][iX] += dY; 118 80 D2[iY][iX] += PS_SQR(dX) + PS_SQR(dY); 119 81 } … … 124 86 double minMetric = 1e10; 125 87 double minVar = 1e10; 126 doubleminX = -1;127 doubleminY = -1;88 int minX = -1; 89 int minY = -1; 128 90 double metric, var; 129 91 130 92 // find the max pixel 131 psStats * stats = psStatsAlloc (PS_STAT_MAX);132 stats = psImageStats (stats, gridNP);93 psStats *imStats = psStatsAlloc (PS_STAT_MAX); 94 imStats = psImageStats (imStats, gridNP, NULL, 0); 133 95 134 96 // only check bins with at least 1/2 of max bin 135 int minNpt = 0.5*stats->max; 97 int minNpts = 0.5*imStats->max; 98 fprintf (stderr, "minNpts: %d, max: %d\n", minNpts, (int)(imStats->max)); 136 99 137 100 // find the 'best' bin 138 for (int j = 0; j < gridNP->n Y; j++) {139 for (int i = 0; i < gridNP->n X; i++) {101 for (int j = 0; j < gridNP->numRows; j++) { 102 for (int i = 0; i < gridNP->numCols; i++) { 140 103 141 104 if (NP[j][i] < minNpts) continue; … … 145 108 metric = var / PS_SQR(PS_SQR(NP[j][i])); 146 109 110 fprintf (stderr, "try : %f %f (%d pts, %f var, %f met)\n", DX[j][i]/NP[j][i], DY[j][i]/NP[j][i], NP[j][i], var, metric); 111 147 112 if (metric < minMetric) { 148 113 minMetric = metric; … … 155 120 156 121 // convert the bin to delta-delta 157 matchStats.offset.x = DP[minY][minX] / NP[minY][minX]; 158 matchStats.offset.y = DQ[minY][minX] / NP[minY][minX]; 159 matchStats.minMetric = minMetric; 160 matchStats.minVar = minVar; 161 matchStats.nMatch = NP[minY][minX]; 162 } 163 return (matchStats); 122 stats.offset.x = DX[minY][minX] / NP[minY][minX]; 123 stats.offset.y = DY[minY][minX] / NP[minY][minX]; 124 stats.minMetric = minMetric; 125 stats.minVar = minVar; 126 stats.nMatch = NP[minY][minX]; 127 128 // XXX EAM : This routine, and pmAstromGridMatch, need to handle failure cases better 129 } 130 return (stats); 131 } 132 133 // match two star lists 134 pmAstromStats pmAstromGridMatch (psArray *raw, psArray *ref, psMetadata *config) { 135 136 bool status; 137 double xMin, xMax, yMin, yMax; 138 pmAstromObj *obj; 139 psArray *rot; 140 141 pmAstromStats minStat, newStat; 142 psPlane center; 143 144 // find center of the raw field (focal-plane coords) 145 xMin = yMin = +1e10; 146 xMax = yMax = -1e10; 147 for (int i = 0; i < raw->n; i++) { 148 obj = (pmAstromObj *)raw->data[i]; 149 xMin = PS_MIN (obj->FP.x, xMin); 150 xMax = PS_MAX (obj->FP.x, xMax); 151 yMin = PS_MIN (obj->FP.y, yMin); 152 yMax = PS_MAX (obj->FP.y, yMax); 153 } 154 center.x = 0.5*(xMin + xMax); 155 center.y = 0.5*(yMin + yMax); 156 157 double minAngle = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.MIN.ANGLE"); 158 double maxAngle = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.MAX.ANGLE"); 159 double delAngle = psMetadataLookupF32 (&status, config, "PSASTRO.GRID.DEL.ANGLE"); 160 161 minStat.minMetric = 1e10; 162 for (double angle = minAngle; angle <= maxAngle; angle += delAngle) { 163 rot = pmAstromRotateObj (raw, center, angle); 164 newStat = pmAstromGridAngle (rot, ref, config); 165 newStat.angle = angle; 166 newStat.center = center; 167 if (newStat.minMetric < minStat.minMetric) { 168 minStat = newStat; 169 } 170 psFree (rot); 171 } 172 fprintf (stderr, "best: %f %f (%d pts, %f var, %f met)\n", newStat.offset.x, newStat.offset.y, newStat.nMatch, newStat.minVar, newStat.minMetric); 173 return (minStat); 164 174 } 165 175 166 176 // apply the measured FPA offset and rotation (stat) to the fpa astrom structures 167 psFPA *pmAstromGridApply (psPlaneTransform *map, pmAstromGridMatchStat stat) { 168 169 // stat.angle, stat.center, stat.offse 170 // I think i need to know the center reference.... 171 172 return (fpa); 177 psPlaneTransform *pmAstromGridApply (psPlaneTransform *map, pmAstromStats stat) { 178 179 double cs = cos (stat.angle); 180 double sn = sin (stat.angle); 181 182 double dx = (map->x->coeff[0][0] - stat.center.x); 183 double dy = (map->y->coeff[0][0] - stat.center.y); 184 185 // new offset 186 map->x->coeff[0][0] = cs*dx + sn*dy - stat.offset.x + stat.center.x; 187 map->y->coeff[0][0] = -sn*dx + cs*dy - stat.offset.y + stat.center.y; 188 189 // original rotation matrix 190 double pc1_1 = map->x->coeff[1][0]; 191 double pc1_2 = map->x->coeff[0][1]; 192 double pc2_1 = map->y->coeff[1][0]; 193 double pc2_2 = map->y->coeff[0][1]; 194 195 // new rotation matrix 196 map->x->coeff[1][0] = +cs*pc1_1 + sn*pc2_1; 197 map->x->coeff[0][1] = +cs*pc1_2 + sn*pc2_2; 198 map->y->coeff[1][0] = -sn*pc1_1 + cs*pc2_1; 199 map->y->coeff[0][1] = -sn*pc1_2 + cs*pc2_2; 200 201 return (map); 173 202 } 174 203
Note:
See TracChangeset
for help on using the changeset viewer.
