Index: /branches/eam_branches/ohana.20160226/src/relastro/Makefile
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/Makefile	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/Makefile	(revision 39432)
@@ -41,4 +41,5 @@
 $(SRC)/Shutdown.$(ARCH).o 	     \
 $(SRC)/UpdateChips.$(ARCH).o         \
+$(SRC)/UpdateStacks.$(ARCH).o         \
 $(SRC)/UpdateMosaic.$(ARCH).o        \
 $(SRC)/UpdateObjects.$(ARCH).o       \
Index: /branches/eam_branches/ohana.20160226/src/relastro/include/relastro.h
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/include/relastro.h	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/include/relastro.h	(revision 39432)
@@ -528,4 +528,5 @@
 int UpdateSimple (Catalog *catalog, int Ncatalog);
 int UpdateChips (Catalog *catalog, int Ncatalog, int Nloop);
+int UpdateStacks (Catalog *catalog, int Ncatalog);
 int UpdateMosaic (Catalog *catalog, int Ncatalog);
 int UpdateMeasures (Catalog *catalog, int Ncatalog);
Index: /branches/eam_branches/ohana.20160226/src/relastro/src/ImageOps.c
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/src/ImageOps.c	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/src/ImageOps.c	(revision 39432)
@@ -1,4 +1,3 @@
 # include "relastro.h"
-int isGPC1chip (int photcode);
 
 # define USE_IMAGE_ID 1
Index: /branches/eam_branches/ohana.20160226/src/relastro/src/UpdateMeasures.c
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/src/UpdateMeasures.c	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/src/UpdateMeasures.c	(revision 39432)
@@ -71,5 +71,5 @@
 
       double dR = 3600.0*fabs(csdec*(oldR - R));
-      double dD = 3600.0*fabs(oldD - R);
+      double dD = 3600.0*fabs(oldD - D);
 
       // complain if the new location is far from the old location
Index: /branches/eam_branches/ohana.20160226/src/relastro/src/UpdateStacks.c
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/src/UpdateStacks.c	(revision 39432)
+++ /branches/eam_branches/ohana.20160226/src/relastro/src/UpdateStacks.c	(revision 39432)
@@ -0,0 +1,60 @@
+# include "relastro.h"
+
+// NOTE: we only measure the systematic floor of the astrometric scatter per stack, no change to the calibration
+int UpdateStacks (Catalog *catalog, int Ncatalog) {
+
+  off_t Nimage;
+  Image *image = getimages (&Nimage, NULL);
+
+  off_t Nskip = 0;
+  off_t Nmeas = 0;
+
+  // measure the scatter for each stack
+  for (off_t i = 0; i < Nimage; i++) {
+
+    /* skip all except stack images */
+    if (!isGPC1stack(image[i].photcode)) continue;
+
+    /* convert measure coordinates to raw entries */
+    off_t Nraw;
+    StarData *raw = getImageRaw (catalog, Ncatalog, i, &Nraw, MODE_SIMPLE);
+    if (!raw) {
+      Nskip ++;
+      continue;
+    }
+    if (Nraw <= IMFIT_TOO_FEW) {
+      Nskip ++;
+      free (raw);
+      continue;
+    }
+
+    /* convert average coordinates to ref entries */
+    off_t Nref;
+    StarData *ref = getImageRef (catalog, Ncatalog, i, &Nref, MODE_SIMPLE);
+    if (!ref) {
+      Nskip ++;
+      free (raw);
+      continue;
+    }
+
+    // note that Nraw & Nref must be equal: if not, we made a programming error in one of these two functions.
+    assert (Nraw == Nref);
+
+    int Nstat;
+    float dLsig, dMsig, dRsig;
+    GetScatterRawRef(&dLsig, &dMsig, &dRsig, &Nstat, raw, ref, Nraw, IMFIT_SYS_SIGMA_LIM);
+
+    // XXX: I need to convert dLsig, dMsig from degrees to pixels
+    dLsig *= 3600.0 / 0.25;
+    dMsig *= 3600.0 / 0.25;
+
+    image[i].dXpixSys = dLsig;
+    image[i].dYpixSys = dMsig;
+    image[i].nFitAstrom = Nstat;
+  }
+
+  fprintf (stderr, "UpdateStacks: %d measured, %d skipped\n", (int) Nmeas, (int) Nskip);
+  return (TRUE);
+}
+
+// XXX 2 hardwired hacks in this file: 1) photcode hardwired for GPC1 stacks, 2) platescale
Index: /branches/eam_branches/ohana.20160226/src/relastro/src/bcatalog.c
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/src/bcatalog.c	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/src/bcatalog.c	(revision 39432)
@@ -184,4 +184,7 @@
       offset = catalog[0].average[i].measureOffset + j;
       
+      // we do not measure astrometry for the warps, so skip:
+      if (isGPC1warp(catalog[0].measure[offset].photcode)) continue;
+
       // filter objects based on user supplied criteria, including SIGMA_LIM
       if (!MeasFilterTest(&catalog[0].measure[offset], TRUE)) {
Index: /branches/eam_branches/ohana.20160226/src/relastro/src/relastro_parallel_images.c
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/src/relastro_parallel_images.c	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/src/relastro_parallel_images.c	(revision 39432)
@@ -141,4 +141,9 @@
 	LOGRTIME("slurp_meas_pos loop %d on %s, host %d: %f sec\n", i, myHostName, REGION_HOST_ID, dtime);
       }
+
+      // measure scatter for stacks
+      UpdateStacks (catalog, Ncatalog);
+      LOGRTIME("UpdateStacks on %s, host %d: %f sec\n", myHostName, REGION_HOST_ID, dtime);
+
       // create summary plots of the process
       // relastroVisualSummaryChips();
Index: /branches/eam_branches/ohana.20160226/src/relastro/src/share_meas_pos.c
===================================================================
--- /branches/eam_branches/ohana.20160226/src/relastro/src/share_meas_pos.c	(revision 39431)
+++ /branches/eam_branches/ohana.20160226/src/relastro/src/share_meas_pos.c	(revision 39432)
@@ -58,8 +58,4 @@
   off_t i, k;
 
-  int Nmeaspos = 0;
-  MeasPos *measpos = NULL;
-  ALLOCATE (measpos, MeasPos, 1);
-
   fprintf (stderr, "grabbing meas object pos from other hosts...\n");
 
@@ -78,42 +74,39 @@
     LOGRTIME("meas_load_sync host %d loop %d on %s, host %d: %f sec\n", i, nloop, myHostName, REGION_HOST_ID, dtime);
     
-    off_t Nsubset = 0;
+    off_t Nmeaspos = 0;
     char *posfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "measpos.fits");
-    MeasPos *measposSubset = MeasPosLoad (posfile, &Nsubset);
+    MeasPos *measpos = MeasPosLoad (posfile, &Nmeaspos);
     free (posfile);
     LOGRTIME("MeasPosLoad host %d loop %d on %s, host %d: %f sec\n", i, nloop, myHostName, REGION_HOST_ID, dtime);
 
-    // merge_meas_pos reallocs measpos and frees the input measposSubset
-    measpos = merge_meas_pos (measpos, &Nmeaspos, measposSubset, Nsubset);
-    LOGRTIME("merge_meas_pos host %d loop %d on %s, host %d: %f sec\n", i, nloop, myHostName, REGION_HOST_ID, dtime);
+    // apply the loaded measurement positions:
+    for (off_t j = 0; j < Nmeaspos; j++) {
+      int objID = measpos[j].objID;
+      int catID = measpos[j].catID;
+
+      // set the meas mag
+      int catSeq;
+      off_t objSeq;
+      if (!catID_and_objID_to_seq (catID, objID, &catSeq, &objSeq)) {
+	// XXX what should I do if this does not match?
+	continue;
+      }
+      myAssert (catSeq < Ncatalog, "oops");
+
+      off_t m = catalog[catSeq].average[objSeq].measureOffset;
+      for (k = 0; k < catalog[catSeq].average[objSeq].Nmeasure; k++, m++) {
+	if (catalog[catSeq].measureT[m].imageID != measpos[j].imageID) continue;
+	catalog[catSeq].measureT[m].R = measpos[j].R;
+	catalog[catSeq].measureT[m].D = measpos[j].D;
+	if (catalog[catSeq].measure) {
+	  catalog[catSeq].measure[m].R = measpos[j].R;
+	  catalog[catSeq].measure[m].D = measpos[j].D;
+	}
+      }
+    }
+    free (measpos);
+    LOGRTIME("match_catID_and_objID/meas loop %d on %s, host %d: %f sec\n", nloop, myHostName, REGION_HOST_ID, dtime);
   }
   LOGRTIME("meas_load_done loop %d on %s, host %d: %f sec\n", nloop, myHostName, REGION_HOST_ID, dtime);
-
-  for (i = 0; i < Nmeaspos; i++) {
-    int objID = measpos[i].objID;
-    int catID = measpos[i].catID;
-
-    // set the meas mag
-    int catSeq;
-    off_t objSeq;
-    if (!catID_and_objID_to_seq (catID, objID, &catSeq, &objSeq)) {
-	// XXX what should I do if this does not match?
-	continue;
-    }
-    myAssert (catSeq < Ncatalog, "oops");
-
-    off_t m = catalog[catSeq].average[objSeq].measureOffset;
-    for (k = 0; k < catalog[catSeq].average[objSeq].Nmeasure; k++, m++) {
-      if (catalog[catSeq].measureT[m].imageID != measpos[i].imageID) continue;
-      catalog[catSeq].measureT[m].R = measpos[i].R;
-      catalog[catSeq].measureT[m].D = measpos[i].D;
-      if (catalog[catSeq].measure) {
-	catalog[catSeq].measure[m].R = measpos[i].R;
-	catalog[catSeq].measure[m].D = measpos[i].D;
-      }
-    }
-  }
-  free (measpos);
-  LOGRTIME("match_catID_and_objID/meas loop %d on %s, host %d: %f sec\n", nloop, myHostName, REGION_HOST_ID, dtime);
 
   fprintf (stderr, "DONE grabbing meas object pos from other hosts...\n");
