1*219b2ee8SDavid du Colombier #include <u.h>
2*219b2ee8SDavid du Colombier #include <libc.h>
3*219b2ee8SDavid du Colombier #include <bio.h>
4*219b2ee8SDavid du Colombier #include "sky.h"
5*219b2ee8SDavid du Colombier
6*219b2ee8SDavid du Colombier void
amdinv(Header * h,Angle ra,Angle dec,float mag,float col)7*219b2ee8SDavid du Colombier amdinv(Header *h, Angle ra, Angle dec, float mag, float col)
8*219b2ee8SDavid du Colombier {
9*219b2ee8SDavid du Colombier int i, max_iterations;
10*219b2ee8SDavid du Colombier float tolerance;
11*219b2ee8SDavid du Colombier float object_x, object_y, delta_x, delta_y, f, fx, fy, g, gx, gy;
12*219b2ee8SDavid du Colombier float x1, x2, x3, x4;
13*219b2ee8SDavid du Colombier float y1, y2, y3, y4;
14*219b2ee8SDavid du Colombier
15*219b2ee8SDavid du Colombier /*
16*219b2ee8SDavid du Colombier * Initialize
17*219b2ee8SDavid du Colombier */
18*219b2ee8SDavid du Colombier max_iterations = 50;
19*219b2ee8SDavid du Colombier tolerance = 0.0000005;
20*219b2ee8SDavid du Colombier
21*219b2ee8SDavid du Colombier /*
22*219b2ee8SDavid du Colombier * Convert RA and Dec to St.coords
23*219b2ee8SDavid du Colombier */
24*219b2ee8SDavid du Colombier traneqstd(h, ra, dec);
25*219b2ee8SDavid du Colombier
26*219b2ee8SDavid du Colombier /*
27*219b2ee8SDavid du Colombier * Set initial value for x,y
28*219b2ee8SDavid du Colombier */
29*219b2ee8SDavid du Colombier object_x = h->xi/h->param[Ppltscale];
30*219b2ee8SDavid du Colombier object_y = h->eta/h->param[Ppltscale];
31*219b2ee8SDavid du Colombier
32*219b2ee8SDavid du Colombier /*
33*219b2ee8SDavid du Colombier * Iterate by Newtons method
34*219b2ee8SDavid du Colombier */
35*219b2ee8SDavid du Colombier for(i = 0; i < max_iterations; i++) {
36*219b2ee8SDavid du Colombier /*
37*219b2ee8SDavid du Colombier * X plate model
38*219b2ee8SDavid du Colombier */
39*219b2ee8SDavid du Colombier x1 = object_x;
40*219b2ee8SDavid du Colombier x2 = x1 * object_x;
41*219b2ee8SDavid du Colombier x3 = x1 * object_x;
42*219b2ee8SDavid du Colombier x4 = x1 * object_x;
43*219b2ee8SDavid du Colombier
44*219b2ee8SDavid du Colombier y1 = object_y;
45*219b2ee8SDavid du Colombier y2 = y1 * object_y;
46*219b2ee8SDavid du Colombier y3 = y1 * object_y;
47*219b2ee8SDavid du Colombier y4 = y1 * object_y;
48*219b2ee8SDavid du Colombier
49*219b2ee8SDavid du Colombier f =
50*219b2ee8SDavid du Colombier h->param[Pamdx1] * x1 +
51*219b2ee8SDavid du Colombier h->param[Pamdx2] * y1 +
52*219b2ee8SDavid du Colombier h->param[Pamdx3] +
53*219b2ee8SDavid du Colombier h->param[Pamdx4] * x2 +
54*219b2ee8SDavid du Colombier h->param[Pamdx5] * x1*y1 +
55*219b2ee8SDavid du Colombier h->param[Pamdx6] * y2 +
56*219b2ee8SDavid du Colombier h->param[Pamdx7] * (x2+y2) +
57*219b2ee8SDavid du Colombier h->param[Pamdx8] * x2*x1 +
58*219b2ee8SDavid du Colombier h->param[Pamdx9] * x2*y1 +
59*219b2ee8SDavid du Colombier h->param[Pamdx10] * x1*y2 +
60*219b2ee8SDavid du Colombier h->param[Pamdx11] * y3 +
61*219b2ee8SDavid du Colombier h->param[Pamdx12] * x1* (x2+y2) +
62*219b2ee8SDavid du Colombier h->param[Pamdx13] * x1 * (x2+y2) * (x2+y2) +
63*219b2ee8SDavid du Colombier h->param[Pamdx14] * mag +
64*219b2ee8SDavid du Colombier h->param[Pamdx15] * mag*mag +
65*219b2ee8SDavid du Colombier h->param[Pamdx16] * mag*mag*mag +
66*219b2ee8SDavid du Colombier h->param[Pamdx17] * mag*x1 +
67*219b2ee8SDavid du Colombier h->param[Pamdx18] * mag * (x2+y2) +
68*219b2ee8SDavid du Colombier h->param[Pamdx19] * mag*x1 * (x2+y2) +
69*219b2ee8SDavid du Colombier h->param[Pamdx20] * col;
70*219b2ee8SDavid du Colombier
71*219b2ee8SDavid du Colombier /*
72*219b2ee8SDavid du Colombier * Derivative of X model wrt x
73*219b2ee8SDavid du Colombier */
74*219b2ee8SDavid du Colombier fx =
75*219b2ee8SDavid du Colombier h->param[Pamdx1] +
76*219b2ee8SDavid du Colombier h->param[Pamdx4] * 2*x1 +
77*219b2ee8SDavid du Colombier h->param[Pamdx5] * y1 +
78*219b2ee8SDavid du Colombier h->param[Pamdx7] * 2*x1 +
79*219b2ee8SDavid du Colombier h->param[Pamdx8] * 3*x2 +
80*219b2ee8SDavid du Colombier h->param[Pamdx9] * 2*x1*y1 +
81*219b2ee8SDavid du Colombier h->param[Pamdx10] * y2 +
82*219b2ee8SDavid du Colombier h->param[Pamdx12] * (3*x2+y2) +
83*219b2ee8SDavid du Colombier h->param[Pamdx13] * (5*x4 + 6*x2*y2 + y4) +
84*219b2ee8SDavid du Colombier h->param[Pamdx17] * mag +
85*219b2ee8SDavid du Colombier h->param[Pamdx18] * mag*2*x1 +
86*219b2ee8SDavid du Colombier h->param[Pamdx19] * mag*(3*x2+y2);
87*219b2ee8SDavid du Colombier
88*219b2ee8SDavid du Colombier /*
89*219b2ee8SDavid du Colombier * Derivative of X model wrt y
90*219b2ee8SDavid du Colombier */
91*219b2ee8SDavid du Colombier fy =
92*219b2ee8SDavid du Colombier h->param[Pamdx2] +
93*219b2ee8SDavid du Colombier h->param[Pamdx5] * x1 +
94*219b2ee8SDavid du Colombier h->param[Pamdx6] * 2*y1 +
95*219b2ee8SDavid du Colombier h->param[Pamdx7] * 2*y1 +
96*219b2ee8SDavid du Colombier h->param[Pamdx9] * x2 +
97*219b2ee8SDavid du Colombier h->param[Pamdx10] * x1*2*y1 +
98*219b2ee8SDavid du Colombier h->param[Pamdx11] * 3*y2 +
99*219b2ee8SDavid du Colombier h->param[Pamdx12] * 2*x1*y1 +
100*219b2ee8SDavid du Colombier h->param[Pamdx13] * 4*x1*y1* (x2+y2) +
101*219b2ee8SDavid du Colombier h->param[Pamdx18] * mag*2*y1 +
102*219b2ee8SDavid du Colombier h->param[Pamdx19] * mag*2*x1*y1;
103*219b2ee8SDavid du Colombier /*
104*219b2ee8SDavid du Colombier * Y plate model
105*219b2ee8SDavid du Colombier */
106*219b2ee8SDavid du Colombier g =
107*219b2ee8SDavid du Colombier h->param[Pamdy1] * y1 +
108*219b2ee8SDavid du Colombier h->param[Pamdy2] * x1 +
109*219b2ee8SDavid du Colombier h->param[Pamdy3] +
110*219b2ee8SDavid du Colombier h->param[Pamdy4] * y2 +
111*219b2ee8SDavid du Colombier h->param[Pamdy5] * y1*x1 +
112*219b2ee8SDavid du Colombier h->param[Pamdy6] * x2 +
113*219b2ee8SDavid du Colombier h->param[Pamdy7] * (x2+y2) +
114*219b2ee8SDavid du Colombier h->param[Pamdy8] * y3 +
115*219b2ee8SDavid du Colombier h->param[Pamdy9] * y2*x1 +
116*219b2ee8SDavid du Colombier h->param[Pamdy10] * y1*x3 +
117*219b2ee8SDavid du Colombier h->param[Pamdy11] * x3 +
118*219b2ee8SDavid du Colombier h->param[Pamdy12] * y1 * (x2+y2) +
119*219b2ee8SDavid du Colombier h->param[Pamdy13] * y1 * (x2+y2) * (x2+y2) +
120*219b2ee8SDavid du Colombier h->param[Pamdy14] * mag +
121*219b2ee8SDavid du Colombier h->param[Pamdy15] * mag*mag +
122*219b2ee8SDavid du Colombier h->param[Pamdy16] * mag*mag*mag +
123*219b2ee8SDavid du Colombier h->param[Pamdy17] * mag*y1 +
124*219b2ee8SDavid du Colombier h->param[Pamdy18] * mag * (x2+y2) +
125*219b2ee8SDavid du Colombier h->param[Pamdy19] * mag*y1 * (x2+y2) +
126*219b2ee8SDavid du Colombier h->param[Pamdy20] * col;
127*219b2ee8SDavid du Colombier
128*219b2ee8SDavid du Colombier /*
129*219b2ee8SDavid du Colombier * Derivative of Y model wrt x
130*219b2ee8SDavid du Colombier */
131*219b2ee8SDavid du Colombier gx =
132*219b2ee8SDavid du Colombier h->param[Pamdy2] +
133*219b2ee8SDavid du Colombier h->param[Pamdy5] * y1 +
134*219b2ee8SDavid du Colombier h->param[Pamdy6] * 2*x1 +
135*219b2ee8SDavid du Colombier h->param[Pamdy7] * 2*x1 +
136*219b2ee8SDavid du Colombier h->param[Pamdy9] * y2 +
137*219b2ee8SDavid du Colombier h->param[Pamdy10] * y1*2*x1 +
138*219b2ee8SDavid du Colombier h->param[Pamdy11] * 3*x2 +
139*219b2ee8SDavid du Colombier h->param[Pamdy12] * 2*x1*y1 +
140*219b2ee8SDavid du Colombier h->param[Pamdy13] * 4*x1*y1 * (x2+y2) +
141*219b2ee8SDavid du Colombier h->param[Pamdy18] * mag*2*x1 +
142*219b2ee8SDavid du Colombier h->param[Pamdy19] * mag*y1*2*x1;
143*219b2ee8SDavid du Colombier
144*219b2ee8SDavid du Colombier /*
145*219b2ee8SDavid du Colombier * Derivative of Y model wrt y
146*219b2ee8SDavid du Colombier */
147*219b2ee8SDavid du Colombier gy =
148*219b2ee8SDavid du Colombier h->param[Pamdy1] +
149*219b2ee8SDavid du Colombier h->param[Pamdy4] * 2*y1 +
150*219b2ee8SDavid du Colombier h->param[Pamdy5] * x1 +
151*219b2ee8SDavid du Colombier h->param[Pamdy7] * 2*y1 +
152*219b2ee8SDavid du Colombier h->param[Pamdy8] * 3*y2 +
153*219b2ee8SDavid du Colombier h->param[Pamdy9] * 2*y1*x1 +
154*219b2ee8SDavid du Colombier h->param[Pamdy10] * x2 +
155*219b2ee8SDavid du Colombier h->param[Pamdy12] * 3*y2 +
156*219b2ee8SDavid du Colombier h->param[Pamdy13] * (5*y4 + 6*x2*y2 + x4) +
157*219b2ee8SDavid du Colombier h->param[Pamdy17] * mag +
158*219b2ee8SDavid du Colombier h->param[Pamdy18] * mag*2*y1 +
159*219b2ee8SDavid du Colombier h->param[Pamdy19] * mag*(x2 + 3*y2);
160*219b2ee8SDavid du Colombier
161*219b2ee8SDavid du Colombier f = f - h->xi;
162*219b2ee8SDavid du Colombier g = g - h->eta;
163*219b2ee8SDavid du Colombier delta_x = (-f*gy+g*fy) / (fx*gy-fy*gx);
164*219b2ee8SDavid du Colombier delta_y = (-g*fx+f*gx) / (fx*gy-fy*gx);
165*219b2ee8SDavid du Colombier object_x = object_x + delta_x;
166*219b2ee8SDavid du Colombier object_y = object_y + delta_y;
167*219b2ee8SDavid du Colombier if((fabs(delta_x) < tolerance) && (fabs(delta_y) < tolerance))
168*219b2ee8SDavid du Colombier break;
169*219b2ee8SDavid du Colombier }
170*219b2ee8SDavid du Colombier
171*219b2ee8SDavid du Colombier /*
172*219b2ee8SDavid du Colombier * Convert mm from plate center to pixels
173*219b2ee8SDavid du Colombier */
174*219b2ee8SDavid du Colombier h->x = (h->param[Pppo3]-object_x*1000.0)/h->param[Pxpixelsz];
175*219b2ee8SDavid du Colombier h->y = (h->param[Pppo6]+object_y*1000.0)/h->param[Pypixelsz];
176*219b2ee8SDavid du Colombier }
177*219b2ee8SDavid du Colombier
178*219b2ee8SDavid du Colombier void
ppoinv(Header * h,Angle ra,Angle dec)179*219b2ee8SDavid du Colombier ppoinv(Header *h, Angle ra, Angle dec)
180*219b2ee8SDavid du Colombier {
181*219b2ee8SDavid du Colombier
182*219b2ee8SDavid du Colombier /*
183*219b2ee8SDavid du Colombier * Convert RA and Dec to standard coords.
184*219b2ee8SDavid du Colombier */
185*219b2ee8SDavid du Colombier traneqstd(h, ra, dec);
186*219b2ee8SDavid du Colombier
187*219b2ee8SDavid du Colombier /*
188*219b2ee8SDavid du Colombier * Convert st.coords from arcsec to radians
189*219b2ee8SDavid du Colombier */
190*219b2ee8SDavid du Colombier h->xi /= ARCSECONDS_PER_RADIAN;
191*219b2ee8SDavid du Colombier h->eta /= ARCSECONDS_PER_RADIAN;
192*219b2ee8SDavid du Colombier
193*219b2ee8SDavid du Colombier /*
194*219b2ee8SDavid du Colombier * Compute PDS coordinates from solution
195*219b2ee8SDavid du Colombier */
196*219b2ee8SDavid du Colombier h->x =
197*219b2ee8SDavid du Colombier h->param[Pppo1]*h->xi +
198*219b2ee8SDavid du Colombier h->param[Pppo2]*h->eta +
199*219b2ee8SDavid du Colombier h->param[Pppo3];
200*219b2ee8SDavid du Colombier h->y =
201*219b2ee8SDavid du Colombier h->param[Pppo4]*h->xi +
202*219b2ee8SDavid du Colombier h->param[Pppo5]*h->eta +
203*219b2ee8SDavid du Colombier h->param[Pppo6];
204*219b2ee8SDavid du Colombier /*
205*219b2ee8SDavid du Colombier * Convert x,y from microns to pixels
206*219b2ee8SDavid du Colombier */
207*219b2ee8SDavid du Colombier h->x /= h->param[Pxpixelsz];
208*219b2ee8SDavid du Colombier h->y /= h->param[Pypixelsz];
209*219b2ee8SDavid du Colombier
210*219b2ee8SDavid du Colombier }
211*219b2ee8SDavid du Colombier
212*219b2ee8SDavid du Colombier void
traneqstd(Header * h,Angle object_ra,Angle object_dec)213*219b2ee8SDavid du Colombier traneqstd(Header *h, Angle object_ra, Angle object_dec)
214*219b2ee8SDavid du Colombier {
215*219b2ee8SDavid du Colombier float div;
216*219b2ee8SDavid du Colombier
217*219b2ee8SDavid du Colombier /*
218*219b2ee8SDavid du Colombier * Find divisor
219*219b2ee8SDavid du Colombier */
220*219b2ee8SDavid du Colombier div =
221*219b2ee8SDavid du Colombier (sin(object_dec)*sin(h->param[Ppltdec]) +
222*219b2ee8SDavid du Colombier cos(object_dec)*cos(h->param[Ppltdec]) *
223*219b2ee8SDavid du Colombier cos(object_ra - h->param[Ppltra]));
224*219b2ee8SDavid du Colombier
225*219b2ee8SDavid du Colombier /*
226*219b2ee8SDavid du Colombier * Compute standard coords and convert to arcsec
227*219b2ee8SDavid du Colombier */
228*219b2ee8SDavid du Colombier h->xi = cos(object_dec) *
229*219b2ee8SDavid du Colombier sin(object_ra - h->param[Ppltra]) *
230*219b2ee8SDavid du Colombier ARCSECONDS_PER_RADIAN/div;
231*219b2ee8SDavid du Colombier
232*219b2ee8SDavid du Colombier h->eta = (sin(object_dec)*cos(h->param[Ppltdec])-
233*219b2ee8SDavid du Colombier cos(object_dec)*sin(h->param[Ppltdec])*
234*219b2ee8SDavid du Colombier cos(object_ra - h->param[Ppltra]))*
235*219b2ee8SDavid du Colombier ARCSECONDS_PER_RADIAN/div;
236*219b2ee8SDavid du Colombier
237*219b2ee8SDavid du Colombier }
238*219b2ee8SDavid du Colombier
239*219b2ee8SDavid du Colombier void
xypos(Header * h,Angle ra,Angle dec,float mag,float col)240*219b2ee8SDavid du Colombier xypos(Header *h, Angle ra, Angle dec, float mag, float col)
241*219b2ee8SDavid du Colombier {
242*219b2ee8SDavid du Colombier if (h->amdflag) {
243*219b2ee8SDavid du Colombier amdinv(h, ra, dec, mag, col);
244*219b2ee8SDavid du Colombier } else {
245*219b2ee8SDavid du Colombier ppoinv(h, ra, dec);
246*219b2ee8SDavid du Colombier }
247*219b2ee8SDavid du Colombier }
248