Index: /trunk/ippconfig/gpc1/psastro.config
===================================================================
--- /trunk/ippconfig/gpc1/psastro.config	(revision 33850)
+++ /trunk/ippconfig/gpc1/psastro.config	(revision 33851)
@@ -130,5 +130,5 @@
   ZEROPT   F32 24.563
   PHOTCODE STR g
-  GHOST_MAX_MAG                   F32 -20.0
+  GHOST_MAX_MAG                   F32 -18.0
 END
 PHOTCODE.DATA METADATA
Index: /trunk/psastro/src/psastroLoadCrosstalk.c
===================================================================
--- /trunk/psastro/src/psastroLoadCrosstalk.c	(revision 33850)
+++ /trunk/psastro/src/psastroLoadCrosstalk.c	(revision 33851)
@@ -53,5 +53,5 @@
   pmFPAview *viewMask = pmFPAviewAlloc (0);
 
-  float zeropt, exptime, MAX_MAG;
+  float zeropt, exptime, MAX_MAG, SPIKE_MAX_MAG;
 
   psLogMsg ("psastro", PS_LOG_INFO, "determine crosstalk positions");
@@ -105,4 +105,8 @@
   MAX_MAG += MagOffset;
 
+  // Get the spike maximum, as well
+  SPIKE_MAX_MAG = psMetadataLookupF32(&status, recipe, "REFSTAR_MASK_BLEED_MAG_MAX");
+  SPIKE_MAX_MAG += MagOffset;
+  
   psTrace("psastro.crosstalk",2,"%f %f %f %f\n",zeropt,exptime,MAX_MAG,MagOffset);
 
@@ -259,5 +263,5 @@
 
             pmAstromObj *crosstalk = pmAstromObjAlloc();
-
+	    
             crosstalk->Mag = ref->Mag - MagOffset;
             crosstalk->chip->x = x_t_chip;
@@ -274,8 +278,92 @@
             }
             psArrayAdd(crosstalks,100,crosstalk);
-
+	    
             psFree(targetChipName);
             psFree(targetCellName);
             psFree(crosstalk);
+
+	    // Determine if we need to add a spike mask.
+/* 	    psWarning("BLAH: %g %g %g\n",ref->Mag,MagOffset,SPIKE_MAX_MAG); */
+	    if (ref->Mag < SPIKE_MAX_MAG) {
+	      if ((X == 2)&&(! ((U == 3)||(U == 5)||(U == 6)))) {
+		psTrace ("psastro.crosstalk",2,"Cell (%d%d) on chip (%d%d) not a known crosstalk source.",U,V,X,Y);
+		continue;
+	      }
+	      if ((X == 3)&&(! ((U == 3)))) {
+		psTrace ("psastro.crosstalk",2,"Cell (%d%d) on chip (%d%d) not a known crosstalk source.",U,V,X,Y);
+		continue;
+	      }
+	      if ((X == 4)&&(! ((U == 3)))) {
+		psTrace ("psastro.crosstalk",2,"Cell (%d%d) on chip (%d%d) not a known crosstalk source.",U,V,X,Y);
+		continue;
+	      }
+	      if ((X == 5)&&(! ((U == 3)||(U == 5)||(U == 6)))) {
+		psTrace ("psastro.crosstalk",2,"Cell (%d%d) on chip (%d%d) not a known crosstalk source.",U,V,X,Y);
+		continue;
+	      }
+	      
+	      Xt = X;
+	      Yt = Y;
+	      Vt = V;
+	      
+	      for (Ut = 0; Ut < 8; Ut++) {
+
+		psString targetChipName = NULL;
+		psStringAppend(&targetChipName,"XY%d%d",Xt,Yt);
+		psString targetCellName = NULL;
+		psStringAppend(&targetCellName,"xy%d%d",Ut,Vt);
+		
+		psTrace ("psastro.crosstalk",2,"CTsource @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%d%dxy%d%d@%f,%f [%s %s]",
+			 X,Y,U,V,x_cell,y_cell,Xt,Yt,Ut,Vt,x_t_cell,y_t_cell,
+			 targetChipName,targetCellName);
+/* 		psWarning ("CT bleed ct @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%d%dxy%d%d@%f,%f [%s %s]", */
+/* 			 X,Y,U,V,x_cell,y_cell,Xt,Yt,Ut,Vt,x_t_cell,y_t_cell, */
+/* 			 targetChipName,targetCellName); */
+		
+		pmCell *CTtargetCell = getCellByName (CTsourceChip,targetCellName);
+		if (!CTtargetCell) continue;
+		
+		pmChipCoordsForCell(&x_t_chip,&y_t_chip,CTtargetCell,x_t_cell,y_t_cell);
+
+		psTrace ("psastro.crosstalk",2,"CTsource @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%d%dxy%d%d@%f,%f ChipLoc: (%f,%f)",
+			 X,Y,U,V,x_cell,y_cell,Xt,Yt,Ut,Vt,x_t_cell,y_t_cell,x_t_chip,y_t_chip);
+		
+		// Hunt down the readout for the target, and save the chip position and magnitude of source star.
+		pmChip *targetChip = getChipByName(fpa,targetChipName);
+		if (!targetChip) continue;
+		if (!targetChip->cells) continue;
+		if (!targetChip->cells->n) continue;
+		
+		pmCell *targetCell = targetChip->cells->data[0];
+		if (!targetCell) continue;
+		if (!targetCell->readouts) continue;
+		if (!targetCell->readouts->n) continue;
+		pmReadout *targetReadout = targetCell->readouts->data[0];
+		if (!targetReadout) continue;
+		
+		pmAstromObj *crosstalk = pmAstromObjAlloc();
+		
+		crosstalk->Mag = ref->Mag;
+		crosstalk->chip->x = x_t_chip;
+		crosstalk->chip->y = y_t_chip;
+		
+		psArray *crosstalks = psMetadataLookupPtr (&status, targetReadout->analysis, "PSASTRO.CROSSTALKS.SPIKES");
+		if (crosstalks == NULL) {
+		  crosstalks = psArrayAllocEmpty(100);
+		  if (!psMetadataAdd(targetReadout->analysis,PS_LIST_TAIL,"PSASTRO.CROSSTALKS.SPIKES", PS_DATA_ARRAY, "crosstalk locations", crosstalks)) {
+		    psError(PSASTRO_ERR_CONFIG, false, "failure to add crosstalks to readout");
+		    goto escape;
+		  }
+		  psFree(crosstalks);
+		}
+		psArrayAdd(crosstalks,100,crosstalk);
+		
+		psFree(targetChipName);
+		psFree(targetCellName);
+		psFree(crosstalk);
+	      }
+	    } // End satspike crosstalks
+
+	    
           } // refstars
         } // readout
Index: /trunk/psastro/src/psastroLoadGhosts.c
===================================================================
--- /trunk/psastro/src/psastroLoadGhosts.c	(revision 33850)
+++ /trunk/psastro/src/psastroLoadGhosts.c	(revision 33851)
@@ -128,4 +128,5 @@
                 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;
 
@@ -163,11 +164,46 @@
 		    pmChip *ghostChip = psastroFindChip (&ghost->chip->x, &ghost->chip->y, fpa, -ghost->srcFP->x, -ghost->srcFP->y);
 		    // fprintf (stderr, "raw chip position: %f, %f ", ghost->chip->x, ghost->chip->y);
-
+		    float ref_chip_x = ghost->chip->x;
+		    float ref_chip_y = ghost->chip->y;
 		    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);
 
+		    if (ghostChip) {
+		      psTrace("psastro.ghost",5,"   in ghost: %d/%ld: ref: (%f,%f) or (%f,%f,%s) ghost: (%f,%f) or (%f,%f,%s) %f inner: (%f,%f,%f) outer: (%f,%f,%f)",
+			      i,refstars->n,
+			      ref->FP->x,ref->FP->y,
+			      ref_chip_x,ref_chip_y,psMetadataLookupStr(NULL,chip->concepts,"CHIP.NAME"),
+			      ghost->FP->x,ghost->FP->y,
+			      ghost->chip->x,ghost->chip->y,psMetadataLookupStr(NULL,ghostChip->concepts,"CHIP.NAME"),
+			      rSrc,
+			      ghost->inner.major,ghost->inner.minor,ghost->inner.theta,
+			      ghost->outer.major,ghost->outer.minor,ghost->outer.theta);
+/* 		      psWarning("   GHOST_DATA: %d/%ld: ref: (%f,%f) or (%f,%f,%s) ghost: (%f,%f) or (%f,%f,%s) %f inner: (%f,%f,%f) outer: (%f,%f,%f)", */
+/* 			      i,refstars->n, */
+/* 			      ref->FP->x,ref->FP->y, */
+/* 			      ref_chip_x,ref_chip_y,psMetadataLookupStr(NULL,chip->concepts,"CHIP.NAME"), */
+/* 			      ghost->FP->x,ghost->FP->y, */
+/* 			      ghost->chip->x,ghost->chip->y,psMetadataLookupStr(NULL,ghostChip->concepts,"CHIP.NAME"), */
+/* 			      rSrc, */
+/* 			      ghost->inner.major,ghost->inner.minor,ghost->inner.theta, */
+/* 			      ghost->outer.major,ghost->outer.minor,ghost->outer.theta); */
+		    }
+		    else {
+		      psTrace("psastro.ghost",5,"   in ghost: %d/%ld: ref: (%f,%f) ghost: (%f,%f) or (%f,%f,%s) inner: (%f,%f,%f) outer: (%f,%f,%f)",
+			      i,refstars->n,
+			      ref->FP->x,ref->FP->y,
+			      ghost->FP->x,ghost->FP->y,
+			      ghost->chip->x,ghost->chip->y,"NONE",
+			      ghost->inner.major,ghost->inner.minor,ghost->inner.theta,
+			      ghost->outer.major,ghost->outer.minor,ghost->outer.theta);
+		    }		      
+		      
+
+			    
 		    if (!ghostChip) goto skip;
 		    if (!ghostChip->cells) goto skip;
 		    if (!ghostChip->cells->n) goto skip;
+
+		    
 		    pmCell *ghostCell = ghostChip->cells->data[0];
 		    if (!ghostCell) goto skip;
@@ -190,4 +226,5 @@
 
 		skip:
+		    
 		    psFree (ghost);
                 }
Index: /trunk/psastro/src/psastroMaskUpdates.c
===================================================================
--- /trunk/psastro/src/psastroMaskUpdates.c	(revision 33850)
+++ /trunk/psastro/src/psastroMaskUpdates.c	(revision 33851)
@@ -406,4 +406,31 @@
                     // XXX for now, assume cell binning is 1x1 relative to chip
                     psastroMaskCircle (readoutMask->mask, crosstalkMaskValue, ref->chip->x, ref->chip->y, radius, radius);
+                  }
+                }
+		// Crosstalk Bleeds
+                psArray *bleedcrosstalks = psMetadataLookupPtr (&status, readout->analysis, "PSASTRO.CROSSTALKS.SPIKES");
+                if (bleedcrosstalks) {
+                  for (int i = 0; i < bleedcrosstalks->n; i++) {
+                    pmAstromObj *ref = bleedcrosstalks->data[i];
+                    float width = REFSTAR_MASK_BLEED_MAG_SLOPE * (REFSTAR_MASK_BLEED_MAG_MAX - ref->Mag);
+                    psTrace("psastro.crosstalk",2,"Masking spike on Chip %s @ (%f,%f) Magnitude: %f Radius %f\n",
+                            psMetadataLookupStr(&status,readout->parent->parent->concepts,"CHIP.NAME"),
+                            ref->chip->x,ref->chip->y,ref->Mag,width);
+                    // XXX for now, assume cell binning is 1x1 relative to chip
+		    pmCell *refCell = pmCellInChip(refChip,ref->chip->x,ref->chip->y);
+		    if (refCell) {
+		      float xCell = 0.0;
+		      float yCell = 0.0;
+		      pmCellCoordsForChip (&xCell, &yCell, refCell, ref->chip->x, ref->chip->y);
+		      int ySize = psMetadataLookupS32(NULL,refCell->concepts,"CELL.YSIZE");
+/* 		      psWarning("Masking CTspike on Chip %s @ (%f,%f) Magnitude: %f (%f %f) Radius %f Z: %d %d %d %d\n", */
+/* 				psMetadataLookupStr(&status,readout->parent->parent->concepts,"CHIP.NAME"), */
+/* 				ref->chip->x,ref->chip->y,ref->Mag,REFSTAR_MASK_BLEED_MAG_SLOPE,REFSTAR_MASK_BLEED_MAG_MAX,width, */
+/* 				(int) (ref->chip->x - 0.5 * width),   (int) (ref->chip->y - yCell), */
+/* 				(int) (ref->chip->x+0.5 * width + 1), (int) (ref->chip->y + (ySize - yCell))); */
+		      psastroMaskRectangle (readoutMask->mask, crosstalkMaskValue,
+					    (int) (ref->chip->x - 0.5 * width),   (int) (ref->chip->y - yCell),
+					    (int) (ref->chip->x+0.5 * width + 1), (int) (ref->chip->y + (ySize - yCell)));
+		    }
                   }
                 }
Index: /trunk/psastro/src/psastroMaskUtils.c
===================================================================
--- /trunk/psastro/src/psastroMaskUtils.c	(revision 33850)
+++ /trunk/psastro/src/psastroMaskUtils.c	(revision 33851)
@@ -135,5 +135,5 @@
 	// XXX optimize this
 	float A = 1.0;
-	float B = shape.sxy*y*PS_SQR(shape.sx);
+	float B = 2.0 * shape.sxy*y*PS_SQR(shape.sx);
 	float C = PS_SQR(y*shape.sx/shape.sy) - PS_SQR(shape.sx);
 
