Index: trunk/psastro/src/Makefile.am
===================================================================
--- trunk/psastro/src/Makefile.am	(revision 41609)
+++ trunk/psastro/src/Makefile.am	(revision 41657)
@@ -109,4 +109,5 @@
 	psastroMosaicSetMatch.c     \
 	psastroFindChip.c           \
+	psastroFindChipGPC.c           \
 	psastroZeroPoint.c    	    \
 	psastroDemoDump.c           \
Index: trunk/psastro/src/psastro.h
===================================================================
--- trunk/psastro/src/psastro.h	(revision 41609)
+++ trunk/psastro/src/psastro.h	(revision 41657)
@@ -184,4 +184,9 @@
 bool 		  psastroFPAtoChip (double *xChip, double *yChip, pmFPA *fpa, int nChip, double xFPA, double yFPA);
 
+pmChip           *psastroFindChipGPC (double *xChip, double *yChip, pmFPA *fpa, double xFPA, double yFPA);
+bool 		  psastroChipBoundsGPC (pmFPA *fpa);
+pmChip           *psastroCheckChip (double *xChip, double *yChip, pmFPA *fpa, int nChip, double xFPA, double yFPA);
+bool              psastroExtractFreeChipBoundsGPC(void);
+
 //bool              psastroMaskStats(pmConfig *config, psMetadata *stats);
 
Index: trunk/psastro/src/psastroLoadCrosstalk.c
===================================================================
--- trunk/psastro/src/psastroLoadCrosstalk.c	(revision 41609)
+++ trunk/psastro/src/psastroLoadCrosstalk.c	(revision 41657)
@@ -12,4 +12,5 @@
 
 # include "psastroInternal.h"
+#include <time.h>
 
 # define ESCAPE { \
@@ -135,5 +136,4 @@
       while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
         psTrace ("psastro.crosstalk", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
-
         if (!cell->process || !cell->file_exists) { continue; }
 
@@ -398,13 +398,4 @@
 
 	      int crossChip = psMetadataLookupS32 (&status, crossItem->data.md, "CHIP.SRC");
-	      int crossCell = psMetadataLookupS32 (&status, crossItem->data.md, "CELL.SRC");
-	      int crossChipOffset = psMetadataLookupS32 (&status, crossItem->data.md, "CHIP.OFFSET");
-	      int crossCellOffset = psMetadataLookupS32 (&status, crossItem->data.md, "CELL.OFFSET");
-	      float crossMagOff = psMetadataLookupF32 (&status, crossItem->data.md, "CROSS.MAGDIFF");
-	      if (!status) {
-		psWarning ("CROSSTALK.RULE entry is missing necessary entry");
-		continue;
-	      }
-
               if (!(X == crossChip)) {
                 psTrace ("psastro.crosstalk",2,"Chip (%d%d) not a known crosstalk source.",X,Y); 
@@ -412,6 +403,41 @@
               }
 
+	      int crossCell = psMetadataLookupS32 (&status, crossItem->data.md, "CELL.SRC");
+	      char *strChipOffset = psMetadataLookupStr (&status, crossItem->data.md, "CHIP.OFFSET");
+	      char *strCellOffset = psMetadataLookupStr (&status, crossItem->data.md, "CELL.OFFSET");
+	      char *strMagOffset = psMetadataLookupStr (&status, crossItem->data.md, "CROSS.MAGDIFF");
+
+              //Parse the strings into individual entries
+              int crossChipOffset[40];
+              int crossCellOffset[40];
+              float crossMagOffset[40];
+
+              int nrul = 0;
+              char *p = strtok (strChipOffset, "/");
+              while (p != NULL) {
+                  crossChipOffset[nrul++] = atoi(p);
+                  p = strtok (NULL, "/");
+              }  
+              int nrul2 = 0;
+              char *p2 = strtok (strCellOffset, "/");
+              while (p2 != NULL) {
+                  crossCellOffset[nrul2++] = atoi(p2);
+                  p2 = strtok (NULL, "/");
+              }  
+              int nrul3 = 0;
+              char *p3 = strtok (strMagOffset, "/");
+              while (p3 != NULL) {
+                  crossMagOffset[nrul3++] = atof(p3);
+                  p3 = strtok (NULL, "/");
+              }  
+
+	      if ((nrul != nrul2) | (nrul != nrul3)) {
+		psWarning ("CROSSTALK.RULE entry is not correctly formatted or incomplete");
+		continue;
+	      }
+
               //the source star needs to be bright enough to produce a crosstalk feature on the target chip/cell that is above the refmag
-              float INSTR_CROSS_MAX_MAG = de->magRef - crossMagOff;
+              //float INSTR_CROSS_MAX_MAG = de->magRef - crossMagOff;
+              float INSTR_CROSS_MAX_MAG = de->magRef;
               float CROSS_MAX_MAG = INSTR_CROSS_MAX_MAG + MagOffset;
 
@@ -423,6 +449,6 @@
               for (int i = 0; i < calstars->n; i++) {
                 pmAstromObj *cal = calstars->data[i];
-                //kick out stars too faint to produce crosstalk with this rule
-                if (cal->Mag > INSTR_CROSS_MAX_MAG) { continue; }
+                //kick out stars too faint to produce crosstalk with any rule
+                if (cal->Mag > (INSTR_CROSS_MAX_MAG-6.)) { continue; }
 
                 // Identify which cell holds the star
@@ -454,141 +480,141 @@
                 }
 
-                int chipTarget = chipNum + crossChipOffset ; 
-                int cellTarget = cellNum + crossCellOffset ; 
-
-                // Convert target cell coordinates to target chip coordinates
-                psString targetChipName = NULL;
-                if(chipTarget > 8) {
-                  psStringAppend(&targetChipName,"XY%2d",chipTarget);
-                }
-                if(chipTarget < 8) {
-                  psStringAppend(&targetChipName,"XY0%1d",chipTarget);
-                }
-                psString targetCellName = NULL;
-                if(cellTarget > 8) {
-                  psStringAppend(&targetCellName,"xy%2d",cellTarget);
-                }
-                if(cellTarget < 8) {
-                  psStringAppend(&targetCellName,"xy0%1d",cellTarget);
-                }
-
-                psTrace ("psastro.crosstalk",2,"CTsource from DETEC @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%2dxy%2d@%f,%f [%s %s]",
+                for (int k = 0 ; k < nrul; k++) {
+                    int chipTarget = chipNum + crossChipOffset[k] ; 
+                    int cellTarget = cellNum + crossCellOffset[k] ; 
+                    if (cal->Mag > (INSTR_CROSS_MAX_MAG-crossMagOffset[k])) { continue; }
+
+                    // Convert target cell coordinates to target chip coordinates
+                    psString targetChipName = NULL;
+                    if(chipTarget > 8) {
+                      psStringAppend(&targetChipName,"XY%2d",chipTarget);
+                    }
+                    if(chipTarget < 8) {
+                      psStringAppend(&targetChipName,"XY0%1d",chipTarget);
+                    }
+                    psString targetCellName = NULL;
+                    if(cellTarget > 8) {
+                      psStringAppend(&targetCellName,"xy%2d",cellTarget);
+                    }
+                    if(cellTarget < 8) {
+                      psStringAppend(&targetCellName,"xy0%1d",cellTarget);
+                    }
+
+                    psTrace ("psastro.crosstalk",2,"CTsource from DETEC @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%2dxy%2d@%f,%f [%s %s]",
                        X,Y,U,V,x_cell,y_cell,chipTarget,cellTarget,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 from DETEC @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%2dxy%2d@%f,%f ChipLoc: (%f,%f)",
+                    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 from DETEC @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%2dxy%2d@%f,%f ChipLoc: (%f,%f)",
                        X,Y,U,V,x_cell,y_cell,chipTarget,cellTarget,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;
-
-                //check if the crosstalk is above the target chip background level
-                pmDetEff *tarde = psMetadataLookupPtr(NULL, targetReadout->analysis, PM_DETEFF_ANALYSIS); // Detection efficiency
-                if (isnan(tarde->magRef)) { continue; }
-
-                float TARGET_CROSS_MAX_MAG = tarde->magRef-crossMagOff;
-
-                if (cal->Mag > TARGET_CROSS_MAX_MAG) { continue; }
-
-                pmAstromObj *crosstalk = pmAstromObjAlloc();
+                    // 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;
+
+                    //check again if the crosstalk is above the target chip background level
+                    pmDetEff *tarde = psMetadataLookupPtr(NULL, targetReadout->analysis, PM_DETEFF_ANALYSIS); // Detection efficiency
+                    if (isnan(tarde->magRef)) { continue; }
+
+                    float TARGET_CROSS_MAX_MAG = tarde->magRef-crossMagOffset[k];
+                    if (cal->Mag > TARGET_CROSS_MAX_MAG) { continue; }
+                    pmAstromObj *crosstalk = pmAstromObjAlloc();
 	    
-                crosstalk->Mag = cal->Mag;
-                crosstalk->chip->x = x_t_chip;
-                crosstalk->chip->y = y_t_chip;
-
-                psArray *crosstalks = psMetadataLookupPtr (&status, targetReadout->analysis, "PSASTRO.CROSSTALKS");
-                if (crosstalks == NULL) {
-                  crosstalks = psArrayAllocEmpty(100);
-                  if (!psMetadataAdd(targetReadout->analysis,PS_LIST_TAIL,"PSASTRO.CROSSTALKS", 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);
+                    crosstalk->Mag = cal->Mag;
+                    crosstalk->chip->x = x_t_chip;
+                    crosstalk->chip->y = y_t_chip;
+
+                    psArray *crosstalks = psMetadataLookupPtr (&status, targetReadout->analysis, "PSASTRO.CROSSTALKS");
+                    if (crosstalks == NULL) {
+                      crosstalks = psArrayAllocEmpty(100);
+                      if (!psMetadataAdd(targetReadout->analysis,PS_LIST_TAIL,"PSASTRO.CROSSTALKS", 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);
-
-	        // Determine if we need to add a spike mask.
-                // TdB20210304: This should not be relevant for faint crosstalk rules. Do this rather ad hoc right now by placing a limit at 8 mags of difference
-                if( crossMagOff > 8.) { continue; }
-	        if (cal->Mag < SPIKE_MAX_MAG) {	      
-	          int Xt = X;
-	          int Yt = Y;
-	          int Vt = V;
+                    psFree(targetChipName);
+                    psFree(targetCellName);
+                    psFree(crosstalk);
+
+	            // Determine if we need to add a spike mask.
+                    // TdB20210304: This should not be relevant for faint crosstalk rules. Do this rather ad hoc right now by placing a limit at 8 mags of difference
+                    if( crossMagOffset[k] > 8.) { continue; }
+	            if ((cal->Mag + MagOffset) < SPIKE_MAX_MAG) {	      
+	              int Xt = X;
+	              int Yt = Y;
+	              int Vt = V;
 	      
-	          for (int 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]",
+	              for (int 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);
 		
-		    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)",
+		        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;
+		        // 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 = cal->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
+		        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 = cal->Mag + MagOffset;
+		        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
+                  } //end of rules block
               } // End calMags
 
-          
               // We also want to use the refstars to check for crosstalk. In particular, the detections 
               // do not do well for bright stars, and saturated detections will underestimate the size of the crostalk
@@ -601,6 +627,5 @@
 	        // This is the source of the ct.
                 pmAstromObj *ref = refstars->data[i];
-
-                if (ref->Mag > CROSS_MAX_MAG) { continue; }
+                if (ref->Mag > (CROSS_MAX_MAG-6.)) { continue; }
 
                 // Identify which cell holds the star
@@ -633,139 +658,141 @@
                 }
 
-                int chipTarget = chipNum + crossChipOffset ; 
-                int cellTarget = cellNum + crossCellOffset ; 
-
-                // Convert target cell coordinates to target chip coordinates
-                psString targetChipName = NULL;
-                if(chipTarget > 8) {
-                  psStringAppend(&targetChipName,"XY%2d",chipTarget);
-                }
-                if(chipTarget < 8) {
-                  psStringAppend(&targetChipName,"XY0%1d",chipTarget);
-                }
-                psString targetCellName = NULL;
-                if(cellTarget > 8) {
-                  psStringAppend(&targetCellName,"xy%2d",cellTarget);
-                }
-                if(cellTarget < 8) {
-                  psStringAppend(&targetCellName,"xy0%1d",cellTarget);
-                }
-
-                psTrace ("psastro.crosstalk",2,"CTsource @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%2dxy%2d@%f,%f [%s %s]",
+                for (int k = 0 ; k < nrul; k++) {
+                    int chipTarget = chipNum + crossChipOffset[k] ; 
+                    int cellTarget = cellNum + crossCellOffset[k] ; 
+                    if (ref->Mag > (CROSS_MAX_MAG-crossMagOffset[k])) { continue; }
+
+                    // Convert target cell coordinates to target chip coordinates
+                    psString targetChipName = NULL;
+                    if(chipTarget > 8) {
+                      psStringAppend(&targetChipName,"XY%2d",chipTarget);
+                    }
+                    if(chipTarget < 8) {
+                      psStringAppend(&targetChipName,"XY0%1d",chipTarget);
+                    }
+                    psString targetCellName = NULL;
+                    if(cellTarget > 8) {
+                      psStringAppend(&targetCellName,"xy%2d",cellTarget);
+                    }
+                    if(cellTarget < 8) {
+                      psStringAppend(&targetCellName,"xy0%1d",cellTarget);
+                    }
+
+                    psTrace ("psastro.crosstalk",2,"CTsource @ OTA%d%dxy%d%d@%f,%f CTtarget OTA%2dxy%2d@%f,%f [%s %s]",
                        X,Y,U,V,x_cell,y_cell,chipTarget,cellTarget,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%2dxy%2d@%f,%f ChipLoc: (%f,%f)",
+                    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%2dxy%2d@%f,%f ChipLoc: (%f,%f)",
                        X,Y,U,V,x_cell,y_cell,chipTarget,cellTarget,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;
-
-                //check if the crosstalk is above the target chip background level
-                pmDetEff *tarde = psMetadataLookupPtr(NULL, targetReadout->analysis, PM_DETEFF_ANALYSIS); // Detection efficiency
-                if (isnan(tarde->magRef)) { continue; }
-
-                float TARGET_CROSS_MAX_MAG = tarde->magRef-crossMagOff + MagOffset;
-                if (ref->Mag > TARGET_CROSS_MAX_MAG) { continue; }
-
-                pmAstromObj *crosstalk = pmAstromObjAlloc();
+                    // 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;
+
+                    //check if the crosstalk is above the target chip background level
+                    pmDetEff *tarde = psMetadataLookupPtr(NULL, targetReadout->analysis, PM_DETEFF_ANALYSIS); // Detection efficiency
+                    if (isnan(tarde->magRef)) { continue; }
+
+                    float TARGET_CROSS_MAX_MAG = tarde->magRef-crossMagOffset[k] + MagOffset;
+                    if (ref->Mag > TARGET_CROSS_MAX_MAG) { continue; }
+
+                    pmAstromObj *crosstalk = pmAstromObjAlloc();
 	    
-                crosstalk->Mag = ref->Mag - MagOffset;
-                crosstalk->chip->x = x_t_chip;
-                crosstalk->chip->y = y_t_chip;
-
-                psArray *crosstalks = psMetadataLookupPtr (&status, targetReadout->analysis, "PSASTRO.CROSSTALKS");
-                if (crosstalks == NULL) {
-                  crosstalks = psArrayAllocEmpty(100);
-                  if (!psMetadataAdd(targetReadout->analysis,PS_LIST_TAIL,"PSASTRO.CROSSTALKS", 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);
+                    crosstalk->Mag = ref->Mag - MagOffset;
+                    crosstalk->chip->x = x_t_chip;
+                    crosstalk->chip->y = y_t_chip;
+
+                    psArray *crosstalks = psMetadataLookupPtr (&status, targetReadout->analysis, "PSASTRO.CROSSTALKS");
+                    if (crosstalks == NULL) {
+                      crosstalks = psArrayAllocEmpty(100);
+                      if (!psMetadataAdd(targetReadout->analysis,PS_LIST_TAIL,"PSASTRO.CROSSTALKS", 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);
-
-	        // Determine if we need to add a spike mask.
-                // TdB20210304: This should not be relevant for faint crosstalk rules. Do this rather ad hoc right now by placing a limit at 8 mags of difference
-                if( crossMagOff > 8.) { continue; }
-	        if (ref->Mag < SPIKE_MAX_MAG) {	      
-	          int Xt = X;
-	          int Yt = Y;
-	          int Vt = V;
+                    psFree(targetChipName);
+                    psFree(targetCellName);
+                    psFree(crosstalk);
+
+	            // Determine if we need to add a spike mask.
+                    // TdB20210304: This should not be relevant for faint crosstalk rules. Do this rather ad hoc right now by placing a limit at 8 mags of difference
+                    if( crossMagOffset[k] > 8.) { continue; }
+	            if (ref->Mag < SPIKE_MAX_MAG) {	      
+	              int Xt = X;
+	              int Yt = Y;
+	              int Vt = V;
 	      
-	          for (int 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]",
+	              for (int 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);
 		
-		    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)",
+		        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;
+		        // 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 - MagOffset;
-		    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
+		        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
+                  } // End rules block
               } // End refMags
-
             }
           }
Index: trunk/psastro/src/psastroLoadGhosts.c
===================================================================
--- trunk/psastro/src/psastroLoadGhosts.c	(revision 41609)
+++ trunk/psastro/src/psastroLoadGhosts.c	(revision 41657)
@@ -120,5 +120,5 @@
 
     //We need to check whether we are dealing with an old style ghost_model, or a new style model. Check if the mirror_rad polynomial exists
-    float mirCheck = 0;
+    int mirCheck = 0;
     md = psMetadataLookupMetadata (&status, ghostModel, "GHOST.MIRROR.RAD"); 
     if (!md) { psLogMsg ("psastro", PS_LOG_INFO, "No ghost mirror_rad polynomial found. Assuming old-style ghost masking"); } 
@@ -144,4 +144,14 @@
     pmFPA *fpa = astrom->fpa;
 
+    // select the reference mask fpa :: we use this to determine cell boundaries
+    pmFPAfile *refMask = psMetadataLookupPtr (NULL, config->files, "PSASTRO.REFMASK");
+    if (!refMask) {
+      psError(PSASTRO_ERR_CONFIG, true, "Can't find mask reference");
+      return false;
+    }
+    // Activate the reference mask to generate an FPA structure we can use to map stars down to cells
+    pmFPAfileActivate (config->files, false, NULL);
+    pmFPAfileActivate (config->files, true, "PSASTRO.REFMASK");
+
     // raise an error if the config is broken
     if (!psastroZeroPointFromRecipe (&zeropt, &exptime, &INSTR_MAX_MAG, NULL, fpa, recipe)) {
@@ -161,4 +171,14 @@
         if (!chip->fromFPA) { continue; }
 
+        // Get the current chip's name, and parse out the grid location.
+        pmChip *refChip  = pmFPAviewThisChip (view, refMask->fpa);
+        const char *chipName = psMetadataLookupStr(NULL,refChip->concepts, "CHIP.NAME");
+        int X = chipName[2] - '0';
+        int Y = chipName[3] - '0';
+
+        //Check if we are in the central 8 chips, where old ghost-style locations work better
+        int cenChip = 0;
+        if ( (Y >= 3)&&(Y <=4)&&(X >= 2)&&(X <= 5) ) {cenChip = 0;}
+
         while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
             psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
@@ -188,7 +208,7 @@
 
 		    double rSrc = hypot (cal->FP->x, cal->FP->y);
-     	            double theta0 = atan2(cal->FP->x,cal->FP->y);
-
-                    if(mirCheck) {
+     	            double theta0 = atan2(cal->FP->y,cal->FP->x);
+
+                    if((mirCheck) & (!cenChip)) {
                          //TdB: first mirror the reference star positions (around the 0,0 pixel) using the radial offset coefficients and the ghost/star angle
 		        double ghost_offset_rad = psPolynomial1DEval (mirrorRad, rSrc);
@@ -200,5 +220,5 @@
 		        ghost->FP->y = ghost_y_fpa_mirror + psPolynomial2DEval(centerY, ghost_x_fpa_mirror, ghost_y_fpa_mirror);
                     }  
-                    if(!mirCheck) {
+                    if((!mirCheck) | cenChip) {
                         //Use the old-style ghost position determination
                         ghost->FP->x = -cal->FP->x + psPolynomial2DEval(centerX, -cal->FP->x, -cal->FP->y);
@@ -312,5 +332,5 @@
      	            double theta0 = atan2(ref->FP->y,ref->FP->x);
 
-                    if(mirCheck) {
+                    if((mirCheck) & (!cenChip)) {
                          //TdB: first mirror the reference star positions (around the 0,0 pixel) using the radial offset coefficients and the ghost/star angle
 		        double ghost_offset_rad = psPolynomial1DEval (mirrorRad, rSrc);
@@ -322,5 +342,5 @@
 		        ghost->FP->y = ghost_y_fpa_mirror + psPolynomial2DEval(centerY, ghost_x_fpa_mirror, ghost_y_fpa_mirror);
                     }  
-                    if(!mirCheck) {
+                    if((!mirCheck) | cenChip) {
                         //Use the old-style ghost position determination
                         ghost->FP->x = -ref->FP->x + psPolynomial2DEval(centerX, -ref->FP->x, -ref->FP->y);
Index: trunk/psastro/src/psastroMaskUpdates.c
===================================================================
--- trunk/psastro/src/psastroMaskUpdates.c	(revision 41609)
+++ trunk/psastro/src/psastroMaskUpdates.c	(revision 41657)
@@ -127,5 +127,5 @@
     }
     psLogMsg ("psastro", PS_LOG_INFO, "generating a bright-star mask");
-    
+ 
     bool REFSTAR_MASK_BLEED                = psMetadataLookupBool (&status, recipe, "REFSTAR_MASK_BLEED");
     bool REFSTAR_MASK_BLEED_ORIENTATION_X  = psMetadataLookupBool (&status, recipe, "REFSTAR_MASK_BLEED_ORIENTATION_X");
@@ -479,5 +479,6 @@
                             ref->chip->x,ref->chip->y,ref->Mag,radius);
                     // XXX for now, assume cell binning is 1x1 relative to chip
-                    psastroMaskCircle (readoutMask->mask, crosstalkMaskValue, ref->chip->x, ref->chip->y, radius, radius);
+                    //For the moment, make the crostalk masks into ovals by doing a simple 1:2 scaling with radius. Not ideal, but better until we can get more examples.
+                    psastroMaskCircle (readoutMask->mask, crosstalkMaskValue, ref->chip->x, ref->chip->y, radius/2., radius);
                   }
                 }
