Changeset 5495
- Timestamp:
- Nov 10, 2005, 9:38:35 AM (21 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 2 edited
-
archive/modules/src/pmAstrom.c (modified) (1 diff)
-
psastro/src/pmAstrom.c (modified) (4 diffs)
-
psastro/src/pmAstromGrid.c (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/archive/modules/src/pmAstrom.c
r5494 r5495 228 228 } 229 229 230 231 230 // rotate the focal-plane coordinates about the center coordinate 232 231 // angle specified in radians -
trunk/psastro/src/pmAstrom.c
r5360 r5495 1 1 # include "pmAstrom.h" 2 3 // input: st1, st2 are psArray of psPlane? pmAstromObj4 5 static double maxOffset; // maximum allowed offset between lists, in raw pixels6 static double Scale; // grid pixel scale7 static double Offset; // deltas to pixels8 9 bool p_pmAstromGridBin (int *pOut, int *qOut, double dP, int dQ) {10 11 if (fabs(dP) > maxOffset) return false;12 if (fabs(dQ) > maxOffset) return false;13 14 *pOut = dP / Scale + Offset;15 *qOut = dQ / Scale + Offset;16 return true;17 }18 19 /* Illustration of the grid bins20 dP bin21 -35:-25 -> 0 bin = dP / Scale + Offset22 -25:-15 -> 1 Scale = 1023 -15:-05 -> 2 Offset = 3.524 -05:+05 -> 3 nPix = 3 (maxOffset = 35 = (nPix + 0.5)*dPix25 +05:+15 -> 4 dPix = 1026 +15:+25 -> 527 +25:+35 -> 628 29 maxOffsetRequest = 3030 nPix = (int) (maxOffset / dPix + 0.5);31 maxOffset = (nPix + 0.5)*Scale;32 */33 34 // apply the measured FPA offset and rotation (stat) to the fpa astrom structures35 psFPA *pmAstromApplyGridMatch (psFPA *fpa, pmAstromGridMatchStat stat) {36 37 // stat.angle modifies fpa.toTangentPlane (effective angle)38 // stat.dP, stat.dQ modifies fpa.projection (Ro, Do)39 40 return (fpa);41 }42 43 pmAstromGridMatchStat pmAstromGridMatch (psArray *st1, psArray *st2, psMetadata *config) {44 45 pmAstromGridMatchStat minStat, newStat;46 47 // find center of the st2 field (focal-plane coords)48 pMin = 1e10; pMax = -1e10;49 qMin = 1e10; qMax = -1e10;50 for (int i = 0; i < st2->n; i++) {51 ob2 = (pmAstromObj *)st2->data[i];52 pMin = PS_MIN (ob2->P, pMin);53 pMax = PS_MAX (ob2->P, pMax);54 qMin = PS_MIN (ob2->Q, qMin);55 qMax = PS_MAX (ob2->Q, qMax);56 }57 pCenter = 0.5*(pMin + pMax);58 qCenter = 0.5*(qMin + qMax);59 60 double minAngle = psMetadataLookupF32 (&status, config, "MIN_ANGLE");61 double maxAngle = psMetadataLookupF32 (&status, config, "MAX_ANGLE");62 double delAngle = psMetadataLookupF32 (&status, config, "DEL_ANGLE");63 64 minStat.minMetric = 1e10;65 for (angle = minAngle; angle <= maxAngle; angle += delAngle) {66 st2r = pmAstromRotateObj (st2, angle, pCenter, qCenter);67 newStat = pmAstromGridMatchAngle (st1, st2r, config);68 newStat.angle = angle;69 if (newStat.minMetric < minStat.minMetric) {70 minStat = newStat;71 }72 }73 return (minStat);74 }75 76 // rotate the focal-plane coordinates about the center coordinate77 // angle specified in radians78 psArray *pmAstromRotateObj (psArray *old, double angle, double pCenter, double qCenter) {79 80 pmAstromObj *ob;81 82 psArray *new = psArrayAlloc (old->n);83 84 cs = cos(angle);85 sn = sin(angle);86 87 for (int i = 0; i < old->n; i++) {88 89 oldObj = (pmAstromObj *)old->data[i];90 newObj = pmAstromObjCopy (oldObj);91 92 P = oldObj->P - pCenter;93 Q = oldObj->Q - qCenter;94 95 newObj->P = P*cs + Q*sn;96 newObj->Q = Q*cs - P*sn;97 98 new->data[i] = newObj;99 }100 return (new);101 }102 103 // match the two lists using the binned delta-delta max104 pmAstromGridMatchStats pmAstromGridMatchAngle (psArray *st1, psArray *st2, psMetadata *config) {105 106 // input lists must be projected to common focal plane107 pmAstromGridMatchStats matchStats;108 109 double gridOffset = psMetadataLookupF32 (&status, config, "GRID_OFFSET");110 double gridScale = psMetadataLookupF32 (&status, config, "GRID_SCALE");111 112 // set the static scaling factors113 nPixHalf = (int)(gridOffset / gridScale + 0.5);114 nPix = 2*nPixHalf + 1;115 116 maxOffpix = gridScale * (nPix + 0.5);117 Offset = maxOffpix / gridScale;118 Scale = gridScale;119 120 // ** can we assume the allocated image is init-ed?121 gridNP = psImageAlloc (nPix, nPix, PS_TYPE_S32);122 gridDP = psImageAlloc (nPix, nPix, PS_TYPE_F32);123 gridDQ = psImageAlloc (nPix, nPix, PS_TYPE_F32);124 gridD2 = psImageAlloc (nPix, nPix, PS_TYPE_F32);125 psImageInit (gridNP);126 psImageInit (gridDP);127 psImageInit (gridDQ);128 psImageInit (gridD2);129 130 // short-cut names for grid images131 NP = gridNP->data.F32;132 DP = gridDP->data.F32;133 DQ = gridDQ->data.F32;134 D2 = gridD2->data.F32;135 136 // accumulate grids for focal plane (L,M) matches137 for (int i = 0; i < st1->n; i++) {138 ob1 = (pmAstromObj *)st1->data[i];139 for (int j = 0; j < st2->n; j++) {140 ob2 = (pmAstromObj *)st2->data[i];141 dP = ob1->P - ob2->P;142 if (fabs(dP) > maxOffset) continue;143 144 dQ = ob1->Q - ob2->Q;145 if (fabs(dQ) > maxOffset) continue;146 147 // find bin coordinates for this delta-delta148 p_pmAstromGridBin (&iP, &iQ, dP, dQ);149 150 // accumulate dP2, dQ2?151 NP[iQ][iP] ++;152 DP[iQ][iP] += dP;153 DQ[iQ][iP] += dQ;154 D2[iQ][iP] += PS_SQR(dP) + PS_SQR(dQ);155 }156 }157 158 // find the max pixel159 stats = psStatsAlloc (PS_STAT_MAX);160 stats = psImageStats (stats, gridNP);161 162 // only check bins with at least 1/2 of max bin163 minNpt = 0.5*stats->max;164 165 // find the 'best' bin166 minMetric = minVar = 1e10;167 minP = minQ = -1;168 for (int j = 0; j < gridNP->nY; j++) {169 for (int i = 0; i < gridNP->nX; i++) {170 171 if (NP[j][i] < minNpts) continue;172 173 // this metric emphasize a narrow peak with lots of sources over one with few.174 var = fabs((D2[j][i]/NP[j][i]) - PS_SQR(DP[j][i]/NP[j][i]) - PS_SQR(DQ[j][i]/NP[j][i]));175 metric = var / PS_SQR(PS_SQR(NP[j][i]));176 177 if (metric < minMetric) {178 minMetric = metric;179 minVar = var;180 minP = i;181 minQ = j;182 }183 }184 }185 186 // convert the bin to delta-delta187 matchStats.dP = DP[minQ][minP] / NP[minQ][minP];188 matchStats.dQ = DQ[minQ][minP] / NP[minQ][minP];189 matchStats.minMetric = minMetric;190 matchStats.minVar = minVar;191 matchStats.nMatch = NP[minQ][minP];192 193 return (matchStats);194 }195 2 196 3 psArray *pmAstromRadiusMatch (psArray *st1, psArray *st2, psMetadata *config) { 197 4 198 5 // assume the lists are sorted, or sort in place? 199 200 6 // sort st1 by P 201 7 // sort st2 by P 8 9 double dX, dY; 202 10 203 11 int i = 0; … … 212 20 while ((i < st1->n) && (j < st2->n)) { 213 21 214 d P = ((pmAstromObj *)st1->data[i])->P - ((pmAstromObj *)st2->data[i])->P;215 if (d P< -RADIUS) {22 dX = ((pmAstromObj *)st1->data[i])->FP.x - ((pmAstromObj *)st2->data[j])->FP.x; 23 if (dX < -RADIUS) { 216 24 i++; 217 25 continue; 218 26 } 219 if (d P> +RADIUS) {27 if (dX > +RADIUS) { 220 28 j++; 221 29 continue; … … 225 33 while ((dX > -RADIUS) && (j < st2->n)) { 226 34 227 d P = ((pmAstromObj *)st1->data[i])->P - ((pmAstromObj *)st2->data[i])->P;228 dQ = ((pmAstromObj *)st1->data[i])-> Q - ((pmAstromObj *)st2->data[i])->Q;229 dR = d P*dP+ dQ*dQ;35 dX = ((pmAstromObj *)st1->data[i])->FP.x - ((pmAstromObj *)st2->data[j])->FP.x; 36 dQ = ((pmAstromObj *)st1->data[i])->FP.y - ((pmAstromObj *)st2->data[j])->FP.y; 37 dR = dX*dX + dQ*dQ; 230 38 231 39 if (dR > RADIUS_SQR) { … … 276 84 // apply fitted polynomials to fpa 277 85 } 86 87 // rotate the focal-plane coordinates about the center coordinate 88 // angle specified in radians 89 psArray *pmAstromRotateObj (psArray *old, psPlane center, double angle) { 90 91 pmAstromObj *newObj; 92 93 psArray *new = psArrayAlloc (old->n); 94 95 cs = cos(angle); 96 sn = sin(angle); 97 xCenter = center.x; 98 yCenter = center.y; 99 100 for (int i = 0; i < old->n; i++) { 101 102 oldObj = (pmAstromObj *)old->data[i]; 103 newObj = pmAstromObjCopy (oldObj); 104 105 P = oldObj->FP.x - xCenter; 106 Q = oldObj->FP.y - yCenter; 107 108 newObj->FP.x = P*cs + Q*sn; 109 newObj->FP.y = Q*cs - P*sn; 110 111 new->data[i] = newObj; 112 } 113 return (new); 114 } 115 116 static void pmAstromObjFree (pmAstromObj *obj) { 117 118 if (obj == NULL) return; 119 return; 120 } 121 122 pmAstromObj *pmAstromObjAlloc (void) { 123 124 pmAstromObj *obj = psAlloc (sizeof(pmAstromObj)); 125 psMemSetDeallocator (obj, (psFreeFunc) pmAstromObjFree); 126 127 obj->pix.x = 0; 128 obj->pix.y = 0; 129 130 obj->FP.x = 0; 131 obj->FP.y = 0; 132 133 obj->TP.x = 0; 134 obj->TP.y = 0; 135 136 obj->sky.x = 0; 137 obj->sky.y = 0; 138 139 obj->mag = 0; 140 141 return (obj); 142 } 143 144 pmAstromObj *pmAstromObjCopy (pmAstromObj *old) { 145 146 pmAstromObj *obj = pmAstromObjAlloc (); 147 148 obj[0] = old[0]; 149 150 return (obj); 151 } 152 153 static void pmAstromMatchFree (pmAstromMatch *match) { 154 155 if (match == NULL) return; 156 return; 157 } 158 159 pmAstromMatch *pmAstromMatchAlloc (int i1, int i2) { 160 161 pmAstromMatch *match = psAlloc (sizeof(pmAstromMatch)); 162 psMemSetDeallocator(match, (psFreeFunc) pmAstromMatchFree); 163 164 match->i1 = i1; 165 match->i2 = i2; 166 167 return (match); 168 }
Note:
See TracChangeset
for help on using the changeset viewer.
