Index: /trunk/psastro/src/psastroModelAnalysis.c
===================================================================
--- /trunk/psastro/src/psastroModelAnalysis.c	(revision 19515)
+++ /trunk/psastro/src/psastroModelAnalysis.c	(revision 19516)
@@ -1,3 +1,4 @@
 # include "psastroStandAlone.h"
+# define NONLIN_TOL 0.001
 
 bool psastroModelAnalysis (pmConfig *config) {
@@ -12,11 +13,5 @@
     }
 
-    pmFPAfile *output = psMetadataLookupPtr (&status, config->files, "PSASTRO.OUT.MODEL");
-    if (!status) psAbort ("Can't find output pmFPAfile PSASTRO.OUT.MODEL");
-
-    char *outroot = psMetadataLookupStr (&status, config->arguments, "OUTPUT");
-    if (!status || !outroot) psAbort ("Can't find outroot on config->arguments");
-
-    // physical pixel scale in microns per pixel
+    // reference chip for boresite parameters
     char *refChip = psMetadataLookupStr (&status, recipe, "PSASTRO.MODEL.REF.CHIP");
     if (!refChip) {
@@ -24,4 +19,23 @@
 	return false; 
     } 
+
+    pmFPAfile *output = psMetadataLookupPtr (&status, config->files, "PSASTRO.OUT.MODEL");
+    if (!status) psAbort ("Can't find output pmFPAfile PSASTRO.OUT.MODEL");
+
+    // measure the boresite position from a rotation sequence?
+    bool fitBoresite = psMetadataLookupBool (&status, recipe, "PSASTRO.MODEL.FIT.BORESITE");
+    if (!fitBoresite) {
+	psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.BORE.X0", PS_META_REPLACE, "boresite parameter", 0.0); 
+	psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.BORE.Y0", PS_META_REPLACE, "boresite parameter", 0.0); 
+	psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.BORE.RX", PS_META_REPLACE, "boresite parameter", 0.0); 
+	psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.BORE.RY", PS_META_REPLACE, "boresite parameter", 0.0); 
+	psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.BORE.T0", PS_META_REPLACE, "boresite parameter", 0.0); 
+	psMetadataAddF32 (output->fpa->concepts, PS_LIST_TAIL, "FPA.BORE.P0", PS_META_REPLACE, "boresite parameter", 0.0); 
+	psMetadataAddStr (output->fpa->concepts, PS_LIST_TAIL, "FPA.REF.CHIP", PS_META_REPLACE, "boresite parameter", refChip);
+	return true; 
+    } 
+
+    char *outroot = psMetadataLookupStr (&status, config->arguments, "OUTPUT");
+    if (!status || !outroot) psAbort ("Can't find outroot on config->arguments");
 
     /* model analysis:
@@ -38,4 +52,5 @@
      * T_0 : reference angle for rotator
      * P_0 : orientation of boresite ellipse
+     *
      */
 
@@ -76,5 +91,5 @@
 	pmFPAfile *input = file->data.V;
 
-	// reported rotator position angle (this should perhaps be ROT, not POS)
+	// reported rotator position angle
 	double POSANGLE = psMetadataLookupF64 (&status, input->fpa->concepts, "FPA.POSANGLE"); 
 	if (!status) psAbort ("missing FPA.POSANGLE");
@@ -84,5 +99,4 @@
 	if (!chip) psAbort ("invalid chip name for reference");
 
-	// fprintf (stderr, "input %d : %zx : %zx : %zx\n", i, (size_t) input, (size_t) chip, (size_t) chip->toFPA);
 	if (!chip->toFPA) continue;
 
@@ -96,6 +110,8 @@
 	// all posZero values should be clustered in some region, but we need to flip over the 0,360 boundary correctly.
 	// push all to one side or the other
-	float posangle = PM_DEG_RAD * atan2 (chip->toFPA->y->coeff[1][0], chip->toFPA->x->coeff[1][0]);
-	posZero->data.F32[n] = POSANGLE - posangle;
+	float chipAngle = PM_DEG_RAD * atan2 (chip->toFPA->y->coeff[1][0], chip->toFPA->x->coeff[1][0]);
+	float fpaAngle = PM_DEG_RAD * atan2 (input->fpa->toTPA->y->coeff[1][0], input->fpa->toTPA->x->coeff[1][0]);
+
+	posZero->data.F32[n] = POSANGLE - chipAngle - fpaAngle;
 	if (n == 0) {
 	    posBoundary = posZero->data.F32[n] + 180.0;
@@ -106,7 +122,14 @@
 
 	Po->data.F32[n] = POSANGLE * PM_RAD_DEG; // reported position angle
-	Xo->data.F32[n] = chip->fromFPA->x->coeff[0][0]; // reported boresite x position in ref chip coordinates
-	Yo->data.F32[n] = chip->fromFPA->y->coeff[0][0]; // reported boresite y position in ref chip coordinates
-	fprintf (outfile, "%d : %f %f : %f = %f - %f\n", i, Xo->data.F32[n], Yo->data.F32[n], posZero->data.F32[n], POSANGLE, posangle);
+	float xc = chip->fromFPA->x->coeff[0][0]; // reported boresite x position in ref chip coordinates
+	float yc = chip->fromFPA->y->coeff[0][0]; // reported boresite y position in ref chip coordinates
+	// XXX this can also be derived from toFPA via GetCenter....
+	
+	psPlane *PT = psPlaneTransformGetCenter (chip->toFPA, NONLIN_TOL);
+	Xo->data.F32[n] = PT->x; // reported boresite x position in ref chip coordinates
+	Yo->data.F32[n] = PT->y; // reported boresite y position in ref chip coordinates
+	psFree (PT);
+
+	fprintf (outfile, "%d : %f %f : %f = %f - %f - %f | %f %f\n", i, Xo->data.F32[n], Yo->data.F32[n], posZero->data.F32[n], POSANGLE, chipAngle, fpaAngle, xc, yc);
 	n ++;
     }
