xref: /plan9/sys/src/cmd/scat/posn.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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