10 #define FIDL 5344.186 //nominal line spread of fiducials in 5 micro pixels
11 #define FIDS 22980 //nominal sample spread of fiducials in 5 micron pixels
18 ApolloPanIO::ApolloPanIO() {
23 ApolloPanIO::~ApolloPanIO() {
28 void ApolloPanIO::initialize() {
44 for (i=0; i<90; i++) {
49 obs[i].image[0] = FIDS/2;
51 obs[i].image[0] = -FIDS/2;
53 obs[i].image[1] = (-21.5 + double(
int(i/2)))*FIDL;
58 obs[i].image[1] -= FIDL/2;
59 else if (
int(i/2) > 22)
60 obs[i].image[1] -= FIDL;
62 obs[i].image[1] = -obs[i].image[1];
82 int ApolloPanIO::fiducialObservation(
int fiducialNumber,
double machineX,
double machineY) {
95 if (fiducialNumber < 0 || fiducialNumber > 89)
100 if (fabs(machineX) > 1e20)
103 if (fabs(machineY) > 1e20)
107 obs[fiducialNumber].mach[0] = machineX;
108 obs[fiducialNumber].mach[1] = machineY;
111 obs[fiducialNumber].flag = 1;
126 int ApolloPanIO::clearFiducialObservation(
int fiducialNumber) {
128 if (fiducialNumber < 0 || fiducialNumber > 89)
132 obs[fiducialNumber].flag = 0;
146 int ApolloPanIO::computeInteriorOrienation()
150 double cdot[43][4][6],
161 double adot[2][6],wdot[2];
182 affines[0].indeces[0] =0;
185 for (i=2, n=0; i<90; i+=2) {
191 if (obs[i].flag && obs[i+1].flag) {
192 affines[n ].indeces[1] = i+1;
193 affines[n+1].indeces[0] = i ;
200 if (n ==0)
return -1;
207 for (i =0; i<n; i++) {
216 for (j=affines[i].indeces[0]; j<=affines[i].indeces[1]; j++) {
220 adot[0][0] = obs[j].mach[0];
221 adot[0][1] = obs[j].mach[1];
223 adot[1][2] = obs[j].mach[0];
224 adot[1][3] = obs[j].mach[1];
226 wdot[0] = obs[j].image[0];
227 wdot[1] = obs[j].image[1];
234 ndot[i][Isis::isymp(k,l)] += adot[m][k]*adot[m][l];
237 atw[i][k] += adot[0][k]*wdot[0] + adot[1][k]*wdot[1];
244 affines[i].A2I[j] = atw[i][j];
249 if (!Isis::choleski_solve(ndot[i],affines[i].A2I,6,3))
260 for (i=0; i<n-1; i++) {
262 cdot[i][0][0 ] = obs[affines[i].indeces[1]-1].mach[0];
263 cdot[i][0][1 ] = obs[affines[i].indeces[1]-1].mach[1];
264 cdot[i][0][2 ] = 0.0;
265 cdot[i][0][3 ] = 0.0;
266 cdot[i][0][4 ] = 1.0;
267 cdot[i][0][5 ] = 0.0;
269 cdot[i][1][0 ] = 0.0;
270 cdot[i][1][1 ] = 0.0;
271 cdot[i][1][2 ] = obs[affines[i].indeces[1]-1].mach[0];
272 cdot[i][1][3 ] = obs[affines[i].indeces[1]-1].mach[1];
273 cdot[i][1][4 ] = 0.0;
274 cdot[i][1][5 ] = 1.0;
276 cdot[i][2][0 ] = obs[affines[i].indeces[1] ].mach[0];
277 cdot[i][2][1 ] = obs[affines[i].indeces[1] ].mach[1];
278 cdot[i][2][2 ] = 0.0;
279 cdot[i][2][3 ] = 0.0;
280 cdot[i][2][4 ] = 1.0;
281 cdot[i][2][5 ] = 0.0;
283 cdot[i][3][0 ] = 0.0;
284 cdot[i][3][1 ] = 0.0;
285 cdot[i][3][2 ] = obs[affines[i].indeces[1] ].mach[0];
286 cdot[i][3][3 ] = obs[affines[i].indeces[1] ].mach[1];
287 cdot[i][3][4 ] = 0.0;
288 cdot[i][3][5 ] = 1.0;
292 for (i=0; i<n-1; i++) {
296 cndot[i][j][k] = 0.0;
300 for (l=0; l<6; l++) {
301 cndot[i][j][k ] += cdot[i][j][l] * ndot[i ][Isis::isymp(l,k)];
302 cndot[i][j][k+6] -= cdot[i][j][l] * ndot[i+1][Isis::isymp(l,k)];
307 for (i=0; i<(n-1)*4; i++) {
313 for (l=0; l<6; l++) {
314 cxstar[i] -= cdot[j][k][l]*affines[j ].A2I[l];
315 cxstar[i] += cdot[j][k][l]*affines[j+1].A2I[l];
320 for (i=0; i<14878; i++)
324 for (i=0; i<n-1; i++) {
327 for (l=0; l<12; l++) {
329 cnct[Isis::isymp(j+4*i,k+4*i)] += cndot[i][j][l] * cdot[i][k][l];
331 cnct[Isis::isymp(j+4*i,k+4*i)] -= cndot[i][j][l] * cdot[i][k][l-6];
336 for (i=0; i<n-2; i++) {
340 cnct[Isis::isymp(j+i*4,k+4+i*4)] += cndot[i][j][l+6]*cdot[i+1][k][l];
344 Isis::choleski_solve(cnct,cxstar,4*(n-1),2);
351 for (i=0; i<6; i++) {
353 affines[0].A2I[i] += cxstar[j]*cndot[0][j][i];
357 for (i=1; i<n-1; i++) {
358 for (j=0; j<6; j++) {
360 affines[i].A2I[j] += cxstar[(i-1)*4+k]*cndot[i-1][k][j+6];
362 affines[i].A2I[j] += cxstar[(i )*4+k]*cndot[i ][k][j ];
367 for (i=0; i<6; i++) {
369 affines[n-1].A2I[i] += cxstar[4*(n-2)+j]*cndot[n-2][j][i+6];
374 for (i=0; i<n; i++) {
375 det = affines[i].A2I[0]*affines[i].A2I[3] - affines[i].A2I[1]*affines[i].A2I[2];
377 affines[i].A2M[0] = affines[i].A2I[3]/det;
378 affines[i].A2M[3] = affines[i].A2I[0]/det;
380 affines[i].A2M[1] = -affines[i].A2I[1]/det;
381 affines[i].A2M[2] = -affines[i].A2I[2]/det;
383 affines[i].A2M[4] = - affines[i].A2M[0]*affines[i].A2I[4]
384 - affines[i].A2M[1]*affines[i].A2I[5];
385 affines[i].A2M[5] = - affines[i].A2M[2]*affines[i].A2I[4]
386 - affines[i].A2M[3]*affines[i].A2I[5];
393 double pt1[2], pt2[2],v[2];
395 for (i=0; i<n; i++) {
400 pt1[0] = obs[affines[i].indeces[1]-1].mach[0];
401 pt1[1] = obs[affines[i].indeces[1]-1].mach[1];
403 pt2[0] = obs[affines[i].indeces[1] ].mach[0];
404 pt2[1] = obs[affines[i].indeces[1] ].mach[1];
410 v[0] = pt1[0] - pt2[0];
411 v[1] = pt1[1] - pt2[1];
414 det = -(pt1[0]*v[0] + pt1[1]*v[1])/(v[0]*v[0]+v[1]*v[1]);
418 angle = atan2((pt1[0]+det*v[0]),(pt1[1]+det*v[1]));
423 affines[i].rotM[0] = sin(angle);
424 affines[i].rotM[1] = cos(angle);
429 affines[i].mM = pt1[0]*affines[i].rotM[0] + pt1[1]*affines[i].rotM[1];
442 pt1[0] = affines[i].A2I[0] * obs[affines[i].indeces[1]-1].mach[0] +
443 affines[i].A2I[1] * obs[affines[i].indeces[1]-1].mach[1] +
446 pt1[1] = affines[i].A2I[2] * obs[affines[i].indeces[1]-1].mach[0] +
447 affines[i].A2I[3] * obs[affines[i].indeces[1]-1].mach[1] +
450 pt2[0] = affines[i].A2I[0] * obs[affines[i].indeces[1] ].mach[0] +
451 affines[i].A2I[1] * obs[affines[i].indeces[1] ].mach[1] +
454 pt2[1] = affines[i].A2I[2] * obs[affines[i].indeces[1] ].mach[0] +
455 affines[i].A2I[3] * obs[affines[i].indeces[1] ].mach[1] +
462 v[0] = pt1[0] - pt2[0];
463 v[1] = pt1[1] - pt2[1];
466 det = -(pt1[0]*v[0] + pt1[1]*v[1])/(v[0]*v[0]+v[1]*v[1]);
470 angle = atan((pt1[0]+det*v[0])/(pt1[1]+det*v[1]));
475 affines[i].rotI[0] = sin(angle);
476 affines[i].rotI[1] = cos(angle);
481 affines[i].mI = pt1[0]*affines[i].rotI[0] + pt1[1]*affines[i].rotI[1];
501 for (i=0; i<90; i++) {
505 image2Machine(obs[i].image[0],obs[i].image[1],&pt1[0],&pt1[1]);
507 obs[i].residuals[0] = pt1[0] - obs[i].mach[0];
508 obs[i].residuals[1] = pt1[1] - obs[i].mach[1];
512 calc_residual_stats();
532 int ApolloPanIO::machine2Image(
double *machineX,
double *machineY) {
538 temp = *machineX * affines[n-2].rotM[0] + *machineY * affines[n-2].rotM[1];
540 if (temp > affines[n-2].mM) {
544 for (i=0; i<n-1; i++) {
545 temp = *machineX * affines[i].rotM[0] + *machineY * affines[i].rotM[1];
548 if (temp <= affines[i].mM)
554 npt[0] = affines[i].A2I[0] * *machineX + affines[i].A2I[1] * *machineY + affines[i].A2I[4];
555 npt[1] = affines[i].A2I[2] * *machineX + affines[i].A2I[3] * *machineY + affines[i].A2I[5];
585 int ApolloPanIO::machine2Image(
double machineX,
595 i = machine2Image(imageX,imageY);
615 int ApolloPanIO::image2Machine(
double *imageX,
double *imageY) {
621 temp = *imageX * affines[n-2].rotI[0] + *imageY * affines[n-2].rotI[1];
623 if( temp < affines[n-2].mI)
627 for (i=0; i<n-1; i++) {
628 temp = *imageX * affines[i].rotI[0] + *imageY * affines[i].rotI[1];
631 if( temp >= affines[i].mI)
637 npt[0] = affines[i].A2M[0] * *imageX + affines[i].A2M[1] * *imageY + affines[i].A2M[4];
638 npt[1] = affines[i].A2M[2] * *imageX + affines[i].A2M[3] * *imageY + affines[i].A2M[5];
668 int ApolloPanIO::image2Machine(
double imageX,
684 return image2Machine(machineX,machineY);
693 void ApolloPanIO::calc_residual_stats() {
704 for (i=0; i<90; i++) {
706 l = sqrt(obs[i].residuals[0]*obs[i].residuals[0] +
707 obs[i].residuals[1]*obs[i].residuals[1]);
720 for (i=0; i<90; i++) {
722 l = sqrt(obs[i].residuals[0]*obs[i].residuals[0] +
723 obs[i].residuals[1]*obs[i].residuals[1]);
725 stdevR += (l-meanR)*(l-meanR);
729 stdevR = sqrt(stdevR/(n-1));
740 double ApolloPanIO::stdevResiduals() {
752 double ApolloPanIO::meanResiduals()
763 double ApolloPanIO::maxResiduals()