Index: /trunk/ippconfig/gpc2/ghost.model.mdc
===================================================================
--- /trunk/ippconfig/gpc2/ghost.model.mdc	(revision 41347)
+++ /trunk/ippconfig/gpc2/ghost.model.mdc	(revision 41348)
@@ -1,16 +1,25 @@
 # TdB20200327 ghost model fit for gpc2
+
+# These are the original linear solutions for gpc1
+GHOST.MIRROR.RAD METADATA
+  NORDER_X S32 1
+  VAL_X00  F64 -412.2283909
+  VAL_X01  F64 2.07619288
+  NELEMENTS  S32 2
+END
+
 GHOST.CENTER.X METADATA
   NORDER_X S32 3
   NORDER_Y S32 3
-  VAL_X00_Y00  F64 -1.15871916e+02
-  VAL_X01_Y00  F64  4.09678844e-02
-  VAL_X02_Y00  F64  2.83256020e-08
-  VAL_X03_Y00  F64  5.83797628e-11
-  VAL_X00_Y01  F64  2.14720353e-03
-  VAL_X01_Y01  F64 -2.07766141e-07
-  VAL_X02_Y01  F64  2.45261797e-12
-  VAL_X00_Y02  F64  2.45187527e-07
-  VAL_X01_Y02  F64  1.24779721e-10
-  VAL_X00_Y03  F64  4.74932940e-12
+  VAL_X00_Y00  F64  2.03112383e+01
+  VAL_X01_Y00  F64 -1.65708159e-02
+  VAL_X02_Y00  F64  1.43129504e-07
+  VAL_X03_Y00  F64  4.52735266e-11
+  VAL_X00_Y01  F64  4.26192254e-03
+  VAL_X01_Y01  F64  6.66469973e-08
+  VAL_X02_Y01  F64 -1.33859987e-11
+  VAL_X00_Y02  F64  2.34527886e-07
+  VAL_X01_Y02  F64  6.81385407e-11
+  VAL_X00_Y03  F64 -1.01627226e-11
   NELEMENTS  S32 10
 END
@@ -19,19 +28,18 @@
   NORDER_X S32 3
   NORDER_Y S32 3
-  VAL_X00_Y00  F64  4.06137992e+01
-  VAL_X01_Y00  F64 -3.89362940e-02
-  VAL_X02_Y00  F64 -2.22548205e-07
-  VAL_X03_Y00  F64  8.83360295e-11
-  VAL_X00_Y01  F64 -2.50474486e-03
-  VAL_X01_Y01  F64  3.37661246e-07
-  VAL_X02_Y01  F64  1.76755513e-10
-  VAL_X00_Y02  F64  1.92636172e-07
-  VAL_X01_Y02  F64 -6.90714499e-12
-  VAL_X00_Y03  F64  1.45561098e-10
+  VAL_X00_Y00  F64 -3.07632661e+02
+  VAL_X01_Y00  F64 -1.70554450e-03
+  VAL_X02_Y00  F64  9.68642857e-08
+  VAL_X03_Y00  F64 -4.93941120e-12
+  VAL_X00_Y01  F64 -1.59277258e-02
+  VAL_X01_Y01  F64  5.50875919e-08
+  VAL_X02_Y01  F64  5.61297596e-11
+  VAL_X00_Y02  F64  1.12248583e-07
+  VAL_X01_Y02  F64  2.87924055e-11
+  VAL_X00_Y03  F64  4.50177026e-11
   NELEMENTS  S32 10
 END
 
-
-# These are the original linear solutions
+# These are the original linear solutions for gpc1
 GHOST.INNER.MAJOR METADATA
   NORDER_X S32 1
Index: /trunk/ippconfig/gpc2/psastro.config
===================================================================
--- /trunk/ippconfig/gpc2/psastro.config	(revision 41347)
+++ /trunk/ippconfig/gpc2/psastro.config	(revision 41348)
@@ -62,5 +62,5 @@
 
 # XXX Test for taurus
-PSASTRO.GRID.MIN.SIGMA  F32  5.0
+PSASTRO.GRID.MIN.SIGMA  F32  1.0
 PSASTRO.IGNORE          STR  SATURATED,CRLIMIT,DEFECT,BLEND,FAIL
 
@@ -174,9 +174,9 @@
   ZEROPT   F32 26.3
   PHOTCODE STR r
-  GHOST_MAX_MAG                   F32 -23.0
+  GHOST_MAX_MAG                   F32 -23.5
 END
 
 REFSTAR_MASK                    BOOL TRUE
-REFSTAR_MASK_MAX_MAG            F32 -15.0
+REFSTAR_MASK_MAX_MAG            F32 -16.0
 REFSTAR_MASK_SATSTAR_MAG_MAX    F32 -15.0
 REFSTAR_MASK_SATSTAR_MAG_SLOPE  F32  10.15
@@ -237,5 +237,5 @@
 GLINT_ANGLE_POS_SLOPE           F32  0.07903  
 GLINT_ANGLE_POS_REF             F32 -575.5
-GLINT_WIDTH                     F32  30.0
+GLINT_WIDTH                     F32  60.0
 
 # save glint positions?
@@ -251,20 +251,20 @@
 
 GLINT.REGION			METADATA
-  REGION			STR  [-38000:-24000,-20000:+20000]
+  REGION			STR  [-38000:-25000,-20000:+20000]
   GLINT.TYPE                    STR  LEFT
 END
 
 GLINT.REGION			METADATA
-  REGION			STR  [+24000:+38000,-20000:+20000]
+  REGION			STR  [+25000:+38000,-20000:+20000]
   GLINT.TYPE                    STR  RIGHT
 END
 
 GLINT.REGION			METADATA
-  REGION			STR  [-20000:+20000,+24000:+38000:]
+  REGION			STR  [-20000:+20000,+25000:+38000:]
   GLINT.TYPE                    STR  TOP
 END
 
 GLINT.REGION			METADATA
-  REGION			STR  [-20000:+20000,-38000:-24000]
+  REGION			STR  [-20000:+20000,-38000:-25000]
   GLINT.TYPE                    STR  BOTTOM
 END
Index: /trunk/psModules/src/objects/pmSourceIO.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO.c	(revision 41347)
+++ /trunk/psModules/src/objects/pmSourceIO.c	(revision 41348)
@@ -810,4 +810,5 @@
     pmSourceIO_WriteMatchedRefs (file->fits, file->fpa, config);
     pmSourceIO_WriteGlints (file->fits, file->fpa, config);
+    pmSourceIO_WriteGhosts (file->fits, file->fpa, config);
     return true;
 }
Index: /trunk/psModules/src/objects/pmSourceIO.h
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO.h	(revision 41347)
+++ /trunk/psModules/src/objects/pmSourceIO.h	(revision 41348)
@@ -92,4 +92,5 @@
 
 bool pmSourceIO_WriteGlints (psFits *fits, pmFPA *fpa, pmConfig *config);
+bool pmSourceIO_WriteGhosts (psFits *fits, pmFPA *fpa, pmConfig *config);
 
 /// @}
Index: /trunk/psModules/src/objects/pmSourceIO_Ghosts.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO_Ghosts.c	(revision 41347)
+++ /trunk/psModules/src/objects/pmSourceIO_Ghosts.c	(revision 41348)
@@ -104,4 +104,5 @@
     psPolynomial2D *centerX = NULL;
     psPolynomial2D *centerY = NULL;
+    psPolynomial1D *mirrorRad = NULL;
     psPolynomial1D *outerMajor = NULL;
     psPolynomial1D *outerMinor = NULL;
@@ -110,4 +111,6 @@
     psMetadata *ghostModel = NULL;
 
+    psLogMsg ("psastro", PS_LOG_INFO, "writing ghost positions");
+
     // select the current recipe
     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
@@ -132,4 +135,5 @@
     pmFPAview *view = pmFPAviewAlloc (0);
 
+    GET_1D_POLY ("GHOST.MIRROR.RAD", mirrorRad);
     GET_2D_POLY ("GHOST.CENTER.X", centerX);
     GET_2D_POLY ("GHOST.CENTER.Y", centerY);
@@ -187,5 +191,4 @@
  		    for (int i = 0; i < refstars->n; i++) {
  			pmAstromObj *ref = refstars->data[i];
- 			psTrace("psastro.ghost",5,"Begin ghost %d/%ld: MAX_MAG: %g; ref_mag: %g @ (%.10g,%.10g)",i,refstars->n,MAX_MAG,ref->Mag,ref->sky->r * 180 / M_PI,ref->sky->d * 180.0 / M_PI);
  			if (ref->Mag > MAX_MAG) continue;
 
@@ -194,9 +197,15 @@
  			ghost->srcFP->y = ref->FP->y;
 
- 			// XXX it is stupid that this takes -X_fpa,-Y_fpa --> the analysis script is reporting the guess FPA position, and the fit is using that...
- 			ghost->FP->x = -ref->FP->x + psPolynomial2DEval(centerX, -ref->FP->x, -ref->FP->y);
- 			ghost->FP->y = -ref->FP->y + psPolynomial2DEval(centerY, -ref->FP->x, -ref->FP->y);
-
- 			float rSrc = hypot (ref->FP->x, ref->FP->y);
+                        //TdB: first mirror the reference star positions (around the 0,0 pixel) using the radial offset coefficients and the ghost/star angle
+		        double rSrc = hypot (ref->FP->x, ref->FP->y);
+     	                double theta0 = atan2(ref->FP->y,ref->FP->x);
+
+		        double ghost_offset_rad = psPolynomial1DEval (mirrorRad, rSrc);
+		        double ghost_x_fpa_mirror = ref->FP->x + ((ref->FP->x*-1.)/abs(ref->FP->x)*abs(cos(theta0)*ghost_offset_rad));
+		        double ghost_y_fpa_mirror = ref->FP->y + ((ref->FP->y*-1.)/abs(ref->FP->y)*abs(sin(theta0)*ghost_offset_rad));
+
+		        // Now use the mirrored position together with the 2D ghost center fitting to get the actual ghost position in FPA coords 
+		        ghost->FP->x = ghost_x_fpa_mirror + psPolynomial2DEval(centerX, ghost_x_fpa_mirror, ghost_y_fpa_mirror);
+		        ghost->FP->y = ghost_y_fpa_mirror + psPolynomial2DEval(centerY, ghost_x_fpa_mirror, ghost_y_fpa_mirror);
 
  			ghost->inner.major = psPolynomial1DEval (innerMajor, rSrc);
@@ -278,5 +287,4 @@
     	psFree (ghostModel);
     	psFree (view);
-    	return true;
 
         if (table->n == 0) {
Index: /trunk/psModules/src/objects/pmSourceIO_Glints.c
===================================================================
--- /trunk/psModules/src/objects/pmSourceIO_Glints.c	(revision 41347)
+++ /trunk/psModules/src/objects/pmSourceIO_Glints.c	(revision 41348)
@@ -66,4 +66,6 @@
     float zeropt, exptime;
 
+    psLogMsg ("psastro", PS_LOG_INFO, "writing glint positions");
+
     // select the current recipe
     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSASTRO_RECIPE);
@@ -184,9 +186,9 @@
                 }
 
-                //do a rudimentary check of whether the glint enters the pixel FPA
-                if (!strcasecmp(glintType, "TOP")    && ((star->FP->y - glintLength) > 20500.))  continue;
-                if (!strcasecmp(glintType, "BOTTOM") && ((star->FP->y + glintLength) < -20500.))  continue;
-                if (!strcasecmp(glintType, "LEFT")   && ((star->FP->x + glintLength) < -20500.))  continue;
-                if (!strcasecmp(glintType, "RIGHT")  && ((star->FP->x - glintLength) > 20500.))  continue;
+                //do a rudimentary check of whether the glint enters the pixel FPA, and exclude very short ones
+                if (!strcasecmp(glintType, "TOP")    && ((star->FP->y - glintLength) > 19500.))  continue;
+                if (!strcasecmp(glintType, "BOTTOM") && ((star->FP->y + glintLength) < -19500.))  continue;
+                if (!strcasecmp(glintType, "LEFT")   && ((star->FP->x + glintLength) < -19500.))  continue;
+                if (!strcasecmp(glintType, "RIGHT")  && ((star->FP->x - glintLength) > 19500.))  continue;
             
                 //save the glint positions
Index: /trunk/psastro/src/psastroLoadGhosts.c
===================================================================
--- /trunk/psastro/src/psastroLoadGhosts.c	(revision 41347)
+++ /trunk/psastro/src/psastroLoadGhosts.c	(revision 41348)
@@ -105,4 +105,5 @@
     psPolynomial2D *centerX = NULL;
     psPolynomial2D *centerY = NULL;
+    psPolynomial1D *mirrorRad = NULL;
     psPolynomial1D *outerMajor = NULL;
     psPolynomial1D *outerMinor = NULL;
@@ -110,7 +111,7 @@
     psPolynomial1D *innerMinor = NULL;
 
-
     pmFPAview *view = pmFPAviewAlloc (0);
 
+    GET_1D_POLY ("GHOST.MIRROR.RAD", mirrorRad);
     GET_2D_POLY ("GHOST.CENTER.X", centerX);
     GET_2D_POLY ("GHOST.CENTER.Y", centerY);
@@ -178,9 +179,15 @@
 		    ghost->srcFP->y = ref->FP->y;
 
-		    // XXX it is stupid that this takes -X_fpa,-Y_fpa --> the analysis script is reporting the guess FPA position, and the fit is using that...
-		    ghost->FP->x = -ref->FP->x + psPolynomial2DEval(centerX, -ref->FP->x, -ref->FP->y);
-		    ghost->FP->y = -ref->FP->y + psPolynomial2DEval(centerY, -ref->FP->x, -ref->FP->y);
-
-		    float rSrc = hypot (ref->FP->x, ref->FP->y);
+                    //TdB: first mirror the reference star positions (around the 0,0 pixel) using the radial offset coefficients and the ghost/star angle
+		    double rSrc = hypot (ref->FP->x, ref->FP->y);
+     	            double theta0 = atan2(ref->FP->y,ref->FP->x);
+
+		    double ghost_offset_rad = psPolynomial1DEval (mirrorRad, rSrc);
+		    double ghost_x_fpa_mirror = ref->FP->x + ((ref->FP->x*-1.)/abs(ref->FP->x)*abs(cos(theta0)*ghost_offset_rad));
+		    double ghost_y_fpa_mirror = ref->FP->y + ((ref->FP->y*-1.)/abs(ref->FP->y)*abs(sin(theta0)*ghost_offset_rad));
+
+		    // Now use the mirrored position together with the 2D ghost center fitting to get the actual ghost position in FPA coords 
+		    ghost->FP->x = ghost_x_fpa_mirror + psPolynomial2DEval(centerX, ghost_x_fpa_mirror, ghost_y_fpa_mirror);
+		    ghost->FP->y = ghost_y_fpa_mirror + psPolynomial2DEval(centerY, ghost_x_fpa_mirror, ghost_y_fpa_mirror);
 
 		    ghost->inner.major = psPolynomial1DEval (innerMajor, rSrc);
@@ -203,28 +210,4 @@
 		    ghostChip = psastroFindChip (&ghost->chip->x, &ghost->chip->y, fpa, ghost->FP->x, ghost->FP->y);
 		    // fprintf (stderr, "-> model chip position: %f, %f\n", ghost->chip->x, ghost->chip->y);
-
-	            psPlane coordFPA,ptCH2;
-    	            psPlane coordCell,ptFP2;
-	            coordCell.x = ghost->chip->x;
-	            coordCell.y = ghost->chip->y;
-                    psPlaneTransformApply(&coordFPA,ghostChip->toFPA,&coordCell);
-	            ptCH2.x = ghost->chip->x;
-               	    ptCH2.y = ghost->chip->y;
-                    psPlaneTransformApply(&ptFP2,ghostChip->toFPA,&ptCH2);
-
-	            psPlane ptCH, ptFP;
-	            ptFP.x = ghost->FP->x;
-               	    ptFP.y = ghost->FP->y;
-                    psPlaneTransformApply (&ptCH, ghostChip->fromFPA, &ptFP);
-
-                    psastroUpdateChipToFPA (fpa, ghostChip);
-	            psPlane ptCH3, ptFP3;
-	            ptCH3.x = ghost->chip->x;
-               	    ptCH3.y = ghost->chip->y;
-                    psPlaneTransformApply(&ptFP3,ghostChip->toFPA,&ptCH3);
-
-
-
-                    psLogMsg ("psastro", 3, "Ghost refpos: %f %f %s pos: %f %f %f %f %f %f %f %f %f %f %f %f mag: %f inshape: %f %f %f outshape: %f %f %f \n", ref->FP->x,ref->FP->y,psMetadataLookupStr(NULL,chip->concepts,"CHIP.NAME"), ghost->FP->x,ghost->FP->y,coordFPA.x,coordFPA.y,ghost->chip->x, ghost->chip->y,ptCH.x,ptCH.y,ptFP2.x,ptFP2.y,ptFP3.x,ptFP3.y, ghost->Mag,ghost->inner.major,ghost->inner.minor,ghost->inner.theta/PM_RAD_DEG,ghost->outer.major,ghost->outer.minor,ghost->outer.theta/PM_RAD_DEG);
 
 		    if (ghostChip) {
@@ -257,7 +240,5 @@
 			      ghost->outer.major,ghost->outer.minor,ghost->outer.theta);
 		    }		      
-		      
-
-			    
+		      			    
 		    if (!ghostChip) goto skip;
 		    if (!ghostChip->cells) goto skip;
Index: /trunk/psastro/src/psastroLoadGlints.c
===================================================================
--- /trunk/psastro/src/psastroLoadGlints.c	(revision 41347)
+++ /trunk/psastro/src/psastroLoadGlints.c	(revision 41348)
@@ -152,4 +152,9 @@
             }
 
+            //do a rudimentary check of whether the glint enters the pixel FPA
+            if (!strcasecmp(glintType, "TOP")    && ((star->FP->y - glintLength) > 20000.))  continue;
+            if (!strcasecmp(glintType, "BOTTOM") && ((star->FP->y + glintLength) < -20000.))  continue;
+            if (!strcasecmp(glintType, "LEFT")   && ((star->FP->x + glintLength) < -20000.))  continue;
+            if (!strcasecmp(glintType, "RIGHT")  && ((star->FP->x - glintLength) > 20000.))  continue;
 
 	    psVector *x_glint = psVectorAlloc(2,PS_TYPE_F32);
@@ -179,4 +184,5 @@
 		        double yFPAs, yFPAe;
 		        psastroFindChipYedges (&yFPAs, &yFPAe, fpa, nChip);
+		        if (yFPAs > yFPAe) PS_SWAP (yFPAs, yFPAe);
 
   		        xFPA0 = star->FP->x;
@@ -204,4 +210,5 @@
 		        double yFPAs, yFPAe;
 		        psastroFindChipYedges (&yFPAs, &yFPAe, fpa, nChip);
+		        if (yFPAs > yFPAe) PS_SWAP (yFPAs, yFPAe);
 
   		        xFPA0 = star->FP->x;
@@ -218,4 +225,5 @@
 	        x_glint->data.F32[1] = xFPA1;
 	        y_glint->data.F32[1] = yFPA1;
+
 
                 //we need to loop over each corner to select the chips that can have the glint on it
@@ -243,4 +251,5 @@
 		        if (yFPA0 > yFPAe) continue;
 		        if (yFPA1 < yFPAs) continue;
+
 
                         //find the y-coord positions for this chip
@@ -322,10 +331,11 @@
 
 		        // FPA coordinates of intersections with chip edges 
-		        double yFPAs, yFPAe;
-		        psastroFindChipYedges (&yFPAs, &yFPAe, fpa, nChip);
-
-  		        xFPA0 = yFPAe;
+		        double xFPAs, xFPAe;
+		        psastroFindChipXedges (&xFPAs, &xFPAe, fpa, nChip);
+		        if (xFPAs > xFPAe) PS_SWAP (xFPAs, xFPAe);
+
+  		        xFPA0 = xFPAe;
 		        yFPA0 = star->FP->y;
-                        glintLength-= (star->FP->x-yFPAe);
+                        glintLength-= (star->FP->x-xFPAe);
                     }
 
@@ -347,10 +357,11 @@
 
 		        // FPA coordinates of intersections with chip edges 
-		        double yFPAs, yFPAe;
-		        psastroFindChipYedges (&yFPAs, &yFPAe, fpa, nChip);
-
-  		        xFPA0 = yFPAs;
+		        double xFPAs, xFPAe;
+		        psastroFindChipXedges (&xFPAs, &xFPAe, fpa, nChip);
+		        if (xFPAs > xFPAe) PS_SWAP (xFPAs, xFPAe);
+
+  		        xFPA0 = xFPAs;
 		        yFPA0 = star->FP->y;
-                        glintLength-= (yFPAs-star->FP->x);
+                        glintLength-= (xFPAs-star->FP->x);
                     }
 
@@ -431,4 +442,5 @@
 		   	
 		   	fprintf (stderr, "glint %s : %d %f,%f to %f,%f (%f %f %f)\n", glintType, nChip, xChip0, yChip0, xChip1, yChip1, glint_length, glintWidth, chip_angle);
+
 		   	psVector *glint = psVectorAlloc(5,PS_TYPE_F32);
 		   	glint->data.F32[0] = xChip0;
Index: /trunk/psastro/src/psastroMaskUpdates.c
===================================================================
--- /trunk/psastro/src/psastroMaskUpdates.c	(revision 41347)
+++ /trunk/psastro/src/psastroMaskUpdates.c	(revision 41348)
@@ -424,6 +424,6 @@
                         psastroGhost *ghost = ghosts->data[i];
                         //offset the ghost angles with the astrometric rotation angle
-                        ghost->inner.theta -= (ROT_PARITY * ROTANGLE);
-                        ghost->outer.theta -= (ROT_PARITY * ROTANGLE);
+                        ghost->inner.theta = ghost->inner.theta - AST_T0;
+                        ghost->outer.theta = ghost->outer.theta - AST_T0;
                         // XXX bright vs faint ghost bits? (OR with SUSPECT)
                         psastroMaskEllipticalAnnulus (readoutMask->mask, ghostMaskValue, ghost->chip->x, ghost->chip->y, ghost->inner, ghost->outer);
@@ -444,4 +444,5 @@
                         //psastroMaskRectangle (readoutMask->mask, glintMaskValue, glint->x0, glint->y0, glint->x1, glint->y1);
 
+                        psLogMsg ("psastro", 3, "glint: %d %f %f %f %f %f\n",i, glint->data.F32[0], glint->data.F32[1],glint->data.F32[2], glint->data.F32[3], glint->data.F32[4]);
 		        psastroMaskBox (readoutMask->mask, glintMaskValue, glint->data.F32[0], glint->data.F32[1],
 				    glint->data.F32[2], glint->data.F32[3], glint->data.F32[4]);
