9 #include "ApolloPanIO.h"
18 #define FIDL 5344.186 //nominal line spread of fiducials in 5 micro pixels
19 #define FIDS 22980 //nominal sample spread of fiducials in 5 micron pixels
28 ApolloPanIO::ApolloPanIO() {
35 ApolloPanIO::~ApolloPanIO() {
42 void ApolloPanIO::initialize() {
58 for (i=0; i<90; i++) {
63 obs[i].image[0] = FIDS/2;
65 obs[i].image[0] = -FIDS/2;
67 obs[i].image[1] = (-21.5 + double(
int(i/2)))*FIDL;
72 obs[i].image[1] -= FIDL/2;
73 else if (
int(i/2) > 22)
74 obs[i].image[1] -= FIDL;
76 obs[i].image[1] = -obs[i].image[1];
96 int ApolloPanIO::fiducialObservation(
int fiducialNumber,
double machineX,
double machineY) {
109 if (fiducialNumber < 0 || fiducialNumber > 89)
114 if (fabs(machineX) > 1e20)
117 if (fabs(machineY) > 1e20)
121 obs[fiducialNumber].mach[0] = machineX;
122 obs[fiducialNumber].mach[1] = machineY;
125 obs[fiducialNumber].flag = 1;
140 int ApolloPanIO::clearFiducialObservation(
int fiducialNumber) {
142 if (fiducialNumber < 0 || fiducialNumber > 89)
146 obs[fiducialNumber].flag = 0;
160 int ApolloPanIO::computeInteriorOrienation()
164 double cdot[43][4][6],
175 double adot[2][6],wdot[2];
196 affines[0].indeces[0] =0;
199 for (i=2, n=0; i<90; i+=2) {
205 if (obs[i].flag && obs[i+1].flag) {
206 affines[n ].indeces[1] = i+1;
207 affines[n+1].indeces[0] = i ;
214 if (n ==0)
return -1;
221 for (i =0; i<n; i++) {
230 for (j=affines[i].indeces[0]; j<=affines[i].indeces[1]; j++) {
234 adot[0][0] = obs[j].mach[0];
235 adot[0][1] = obs[j].mach[1];
237 adot[1][2] = obs[j].mach[0];
238 adot[1][3] = obs[j].mach[1];
240 wdot[0] = obs[j].image[0];
241 wdot[1] = obs[j].image[1];
248 ndot[i][Isis::isymp(k,l)] += adot[m][k]*adot[m][l];
251 atw[i][k] += adot[0][k]*wdot[0] + adot[1][k]*wdot[1];
258 affines[i].A2I[j] = atw[i][j];
263 if (!Isis::choleski_solve(ndot[i],affines[i].A2I,6,3))
274 for (i=0; i<n-1; i++) {
276 cdot[i][0][0 ] = obs[affines[i].indeces[1]-1].mach[0];
277 cdot[i][0][1 ] = obs[affines[i].indeces[1]-1].mach[1];
278 cdot[i][0][2 ] = 0.0;
279 cdot[i][0][3 ] = 0.0;
280 cdot[i][0][4 ] = 1.0;
281 cdot[i][0][5 ] = 0.0;
283 cdot[i][1][0 ] = 0.0;
284 cdot[i][1][1 ] = 0.0;
285 cdot[i][1][2 ] = obs[affines[i].indeces[1]-1].mach[0];
286 cdot[i][1][3 ] = obs[affines[i].indeces[1]-1].mach[1];
287 cdot[i][1][4 ] = 0.0;
288 cdot[i][1][5 ] = 1.0;
290 cdot[i][2][0 ] = obs[affines[i].indeces[1] ].mach[0];
291 cdot[i][2][1 ] = obs[affines[i].indeces[1] ].mach[1];
292 cdot[i][2][2 ] = 0.0;
293 cdot[i][2][3 ] = 0.0;
294 cdot[i][2][4 ] = 1.0;
295 cdot[i][2][5 ] = 0.0;
297 cdot[i][3][0 ] = 0.0;
298 cdot[i][3][1 ] = 0.0;
299 cdot[i][3][2 ] = obs[affines[i].indeces[1] ].mach[0];
300 cdot[i][3][3 ] = obs[affines[i].indeces[1] ].mach[1];
301 cdot[i][3][4 ] = 0.0;
302 cdot[i][3][5 ] = 1.0;
306 for (i=0; i<n-1; i++) {
310 cndot[i][j][k] = 0.0;
314 for (l=0; l<6; l++) {
315 cndot[i][j][k ] += cdot[i][j][l] * ndot[i ][Isis::isymp(l,k)];
316 cndot[i][j][k+6] -= cdot[i][j][l] * ndot[i+1][Isis::isymp(l,k)];
321 for (i=0; i<(n-1)*4; i++) {
327 for (l=0; l<6; l++) {
328 cxstar[i] -= cdot[j][k][l]*affines[j ].A2I[l];
329 cxstar[i] += cdot[j][k][l]*affines[j+1].A2I[l];
334 for (i=0; i<14878; i++)
338 for (i=0; i<n-1; i++) {
341 for (l=0; l<12; l++) {
343 cnct[Isis::isymp(j+4*i,k+4*i)] += cndot[i][j][l] * cdot[i][k][l];
345 cnct[Isis::isymp(j+4*i,k+4*i)] -= cndot[i][j][l] * cdot[i][k][l-6];
350 for (i=0; i<n-2; i++) {
354 cnct[Isis::isymp(j+i*4,k+4+i*4)] += cndot[i][j][l+6]*cdot[i+1][k][l];
358 Isis::choleski_solve(cnct,cxstar,4*(n-1),2);
365 for (i=0; i<6; i++) {
367 affines[0].A2I[i] += cxstar[j]*cndot[0][j][i];
371 for (i=1; i<n-1; i++) {
372 for (j=0; j<6; j++) {
374 affines[i].A2I[j] += cxstar[(i-1)*4+k]*cndot[i-1][k][j+6];
376 affines[i].A2I[j] += cxstar[(i )*4+k]*cndot[i ][k][j ];
381 for (i=0; i<6; i++) {
383 affines[n-1].A2I[i] += cxstar[4*(n-2)+j]*cndot[n-2][j][i+6];
388 for (i=0; i<n; i++) {
389 det = affines[i].A2I[0]*affines[i].A2I[3] - affines[i].A2I[1]*affines[i].A2I[2];
391 affines[i].A2M[0] = affines[i].A2I[3]/det;
392 affines[i].A2M[3] = affines[i].A2I[0]/det;
394 affines[i].A2M[1] = -affines[i].A2I[1]/det;
395 affines[i].A2M[2] = -affines[i].A2I[2]/det;
397 affines[i].A2M[4] = - affines[i].A2M[0]*affines[i].A2I[4]
398 - affines[i].A2M[1]*affines[i].A2I[5];
399 affines[i].A2M[5] = - affines[i].A2M[2]*affines[i].A2I[4]
400 - affines[i].A2M[3]*affines[i].A2I[5];
407 double pt1[2], pt2[2],v[2];
409 for (i=0; i<n; i++) {
414 pt1[0] = obs[affines[i].indeces[1]-1].mach[0];
415 pt1[1] = obs[affines[i].indeces[1]-1].mach[1];
417 pt2[0] = obs[affines[i].indeces[1] ].mach[0];
418 pt2[1] = obs[affines[i].indeces[1] ].mach[1];
424 v[0] = pt1[0] - pt2[0];
425 v[1] = pt1[1] - pt2[1];
428 det = -(pt1[0]*v[0] + pt1[1]*v[1])/(v[0]*v[0]+v[1]*v[1]);
432 angle = atan2((pt1[0]+det*v[0]),(pt1[1]+det*v[1]));
437 affines[i].rotM[0] = sin(angle);
438 affines[i].rotM[1] = cos(angle);
443 affines[i].mM = pt1[0]*affines[i].rotM[0] + pt1[1]*affines[i].rotM[1];
456 pt1[0] = affines[i].A2I[0] * obs[affines[i].indeces[1]-1].mach[0] +
457 affines[i].A2I[1] * obs[affines[i].indeces[1]-1].mach[1] +
460 pt1[1] = affines[i].A2I[2] * obs[affines[i].indeces[1]-1].mach[0] +
461 affines[i].A2I[3] * obs[affines[i].indeces[1]-1].mach[1] +
464 pt2[0] = affines[i].A2I[0] * obs[affines[i].indeces[1] ].mach[0] +
465 affines[i].A2I[1] * obs[affines[i].indeces[1] ].mach[1] +
468 pt2[1] = affines[i].A2I[2] * obs[affines[i].indeces[1] ].mach[0] +
469 affines[i].A2I[3] * obs[affines[i].indeces[1] ].mach[1] +
476 v[0] = pt1[0] - pt2[0];
477 v[1] = pt1[1] - pt2[1];
480 det = -(pt1[0]*v[0] + pt1[1]*v[1])/(v[0]*v[0]+v[1]*v[1]);
484 angle = atan((pt1[0]+det*v[0])/(pt1[1]+det*v[1]));
489 affines[i].rotI[0] = sin(angle);
490 affines[i].rotI[1] = cos(angle);
495 affines[i].mI = pt1[0]*affines[i].rotI[0] + pt1[1]*affines[i].rotI[1];
515 for (i=0; i<90; i++) {
519 image2Machine(obs[i].image[0],obs[i].image[1],&pt1[0],&pt1[1]);
521 obs[i].residuals[0] = pt1[0] - obs[i].mach[0];
522 obs[i].residuals[1] = pt1[1] - obs[i].mach[1];
526 calc_residual_stats();
546 int ApolloPanIO::machine2Image(
double *machineX,
double *machineY) {
552 temp = *machineX * affines[n-2].rotM[0] + *machineY * affines[n-2].rotM[1];
554 if (temp > affines[n-2].mM) {
558 for (i=0; i<n-1; i++) {
559 temp = *machineX * affines[i].rotM[0] + *machineY * affines[i].rotM[1];
562 if (temp <= affines[i].mM)
568 npt[0] = affines[i].A2I[0] * *machineX + affines[i].A2I[1] * *machineY + affines[i].A2I[4];
569 npt[1] = affines[i].A2I[2] * *machineX + affines[i].A2I[3] * *machineY + affines[i].A2I[5];
599 int ApolloPanIO::machine2Image(
double machineX,
609 i = machine2Image(imageX,imageY);
629 int ApolloPanIO::image2Machine(
double *imageX,
double *imageY) {
635 temp = *imageX * affines[n-2].rotI[0] + *imageY * affines[n-2].rotI[1];
637 if( temp < affines[n-2].mI)
641 for (i=0; i<n-1; i++) {
642 temp = *imageX * affines[i].rotI[0] + *imageY * affines[i].rotI[1];
645 if( temp >= affines[i].mI)
651 npt[0] = affines[i].A2M[0] * *imageX + affines[i].A2M[1] * *imageY + affines[i].A2M[4];
652 npt[1] = affines[i].A2M[2] * *imageX + affines[i].A2M[3] * *imageY + affines[i].A2M[5];
682 int ApolloPanIO::image2Machine(
double imageX,
698 return image2Machine(machineX,machineY);
707 void ApolloPanIO::calc_residual_stats() {
718 for (i=0; i<90; i++) {
720 l = sqrt(obs[i].residuals[0]*obs[i].residuals[0] +
721 obs[i].residuals[1]*obs[i].residuals[1]);
734 for (i=0; i<90; i++) {
736 l = sqrt(obs[i].residuals[0]*obs[i].residuals[0] +
737 obs[i].residuals[1]*obs[i].residuals[1]);
739 stdevR += (l-meanR)*(l-meanR);
743 stdevR = sqrt(stdevR/(n-1));
754 double ApolloPanIO::stdevResiduals() {
766 double ApolloPanIO::meanResiduals()
777 double ApolloPanIO::maxResiduals()