Index: /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/ImagePosIO.c
===================================================================
--- /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/ImagePosIO.c	(revision 36565)
+++ /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/ImagePosIO.c	(revision 36565)
@@ -0,0 +1,309 @@
+# include "relastro.h"
+
+# define GET_COLUMN(OUT,NAME,TYPE) \
+  TYPE *OUT = gfits_get_bintable_column_data (&theader, &ftable, NAME, type, &Nrow, &Ncol); \
+  myAssert (!strcmp(type, #TYPE), "wrong column type");
+
+// this is nearly identical to the one in 'uniphot/src' used by setphot / setphot_client.
+// Here, we use a handful of different columns (if not, we could move to libdvo)
+ImagePos *ImagePosLoad(char *filename, off_t *nimage_pos) {
+
+  int i, Ncol;
+  off_t Nrow;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  *nimage_pos = 0;
+  ImagePos *image_pos = NULL;
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image subset file %s\n", filename);
+    return NULL;
+  }
+
+  /* load in PHU segment (ignore) */
+  if (!gfits_fread_header (f, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset header\n");
+    fclose (f);
+    return NULL;
+  }
+  if (!gfits_fread_matrix (f, &matrix, &header)) {
+    if (VERBOSE) fprintf (stderr, "can't read image subset matrix\n");
+    gfits_free_header (&header);
+    fclose (f);
+    return NULL;
+  }
+
+  ftable.header = &theader;
+
+  // load data for this header 
+  if (!gfits_load_header (f, &theader)) {
+    fclose (f);
+    return NULL;
+  }
+
+  // read the fits table bytes
+  if (!gfits_fread_ftable_data (f, &ftable, FALSE)) {
+    fclose (f);
+    return (NULL);
+  }
+  fclose (f);
+
+  // a bit annoying : we read the entire block of data, then extract the columns, then set the image structure values.
+  // this means I need 3 copies in memory at some point.  ugh.
+
+  char type[16];
+
+  GET_COLUMN (crval1,           "CRVAL1",            double);
+  GET_COLUMN (crval2,           "CRVAL2",            double);
+  GET_COLUMN (crpix1,           "CRPIX1",            float);
+  GET_COLUMN (crpix2,           "CRPIX2",            float);
+  GET_COLUMN (cdelt1,           "CDELT1",            float);
+  GET_COLUMN (cdelt2,           "CDELT2",            float);
+  GET_COLUMN (pc1_1,            "PC1_1",             float);
+  GET_COLUMN (pc1_2,            "PC1_2",             float);
+  GET_COLUMN (pc2_1,            "PC2_1",             float);
+  GET_COLUMN (pc2_2,            "PC2_2",             float);
+  GET_COLUMN (polyterms,        "POLYTERMS",         float); // verify that we got 14 columns?
+  GET_COLUMN (ctype,            "CTYPE",             char);  // verify that we got 15 columns?
+  GET_COLUMN (Npolyterms,       "NPOLYTERMS",        char);
+  GET_COLUMN (dXpixSys,         "XPIX_SYS_ERR",      float);
+  GET_COLUMN (dYpixSys,         "YPIX_SYS_ERR",      float);
+  GET_COLUMN (imageID,          "ID",                int);
+  GET_COLUMN (nFitAstrom,       "NFIT",              int);
+  GET_COLUMN (flags,            "FLAGS",             int);
+
+  ALLOCATE (image_pos, ImagePos, Nrow);
+  for (i = 0; i < Nrow; i++) {
+    image_pos[i].coords.crval1             = crval1    [i];
+    image_pos[i].coords.crval2             = crval2    [i];
+    image_pos[i].coords.crpix1             = crpix1    [i];
+    image_pos[i].coords.crpix2             = crpix2    [i];
+    image_pos[i].coords.cdelt1             = cdelt1    [i];
+    image_pos[i].coords.cdelt2             = cdelt2    [i];
+    image_pos[i].coords.pc1_1              = pc1_1     [i];
+    image_pos[i].coords.pc1_2              = pc1_2     [i];
+    image_pos[i].coords.pc2_1              = pc2_1     [i];
+    image_pos[i].coords.pc2_2              = pc2_2     [i];
+    image_pos[i].coords.Npolyterms         = Npolyterms[i];
+    image_pos[i].dXpixSys                  = dXpixSys  [i];
+    image_pos[i].dYpixSys                  = dYpixSys  [i];
+    image_pos[i].imageID                   = imageID   [i];
+    image_pos[i].nFitAstrom                = nFitAstrom[i];
+    image_pos[i].flags                     = flags     [i];
+
+    // polyterms and ctype are a bit different
+    memcpy (&image_pos[i].coords.polyterms, &polyterms[i*14], 14*sizeof(float));
+    memcpy (&image_pos[i].coords.ctype    , &ctype    [i*15], 15*sizeof(char));
+  }
+  fprintf (stderr, "loaded data for %lld images\n", (long long) Nrow);
+
+  free (crval1    );
+  free (crval2    );
+  free (crpix1    );
+  free (crpix2    );
+  free (cdelt1    );
+  free (cdelt2    );
+  free (pc1_1     );
+  free (pc1_2     );
+  free (pc2_1     );
+  free (pc2_2     );
+  free (polyterms );
+  free (ctype     );
+  free (Npolyterms);
+  free (dXpixSys  );
+  free (dYpixSys  );
+  free (imageID   );
+  free (nFitAstrom);
+  free (flags     );
+
+  *nimage_pos = Nrow;
+  return image_pos;
+}
+
+// STATUS is value expected for success
+# define CHECK_STATUS(STATUS,MSG,...)                                   \
+  if (!(STATUS)) {                                                      \
+    fprintf (stderr, MSG, __VA_ARGS__);                                 \
+    return FALSE;                                                       \
+  }
+
+int ImagePosSave(char *filename, ImagePos *image_pos, off_t Nimage_pos) {
+
+  int i;
+  Header header;
+  Header theader;
+  Matrix matrix;
+  FTable ftable;
+
+  gfits_init_header (&header);
+  header.extend = TRUE;
+  gfits_create_header (&header);
+  gfits_create_matrix (&header, &matrix);
+
+  gfits_create_table_header (&theader, "BINTABLE", "IMAGE_POS");
+
+  gfits_define_bintable_column (&theader, "D",   "CRVAL1",       "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "D",   "CRVAL2",       "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "CRPIX1",       "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "CRPIX2",       "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "CDELT1",       "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "CDELT2",       "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "PC1_1",        "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "PC1_2",        "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "PC2_1",        "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "PC2_2",        "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "14E", "POLYTERMS",    "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "15A", "CTYPE",        "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "L",   "NPOLYTERMS",   "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "XPIX_SYS_ERR", "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "E",   "YPIX_SYS_ERR", "word", "unit", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "ID",           "image ID",               "unitless", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "NFIT",         "number of fitted stars", "unitless", 1.0, 0.0);
+  gfits_define_bintable_column (&theader, "J",   "FLAGS",        "analysis flags",         "unitless", 1.0, 0.0);
+
+  // generate the output array that carries the data
+  gfits_create_table (&theader, &ftable);
+
+  double *crval1    ;
+  double *crval2    ;
+  float  *crpix1    ;
+  float  *crpix2    ;
+  float  *cdelt1    ;
+  float  *cdelt2    ;
+  float  *pc1_1     ;
+  float  *pc1_2     ;
+  float  *pc2_1     ;
+  float  *pc2_2     ;
+  float  *polyterms ;
+  char   *ctype     ;
+  char   *Npolyterms;
+  float  *dXpixSys  ;
+  float  *dYpixSys  ;
+  int    *imageID   ;
+  int    *nFitAstrom;
+  int    *flags     ;
+
+  // create intermediate storage arrays
+  ALLOCATE (crval1    ,         double,          Nimage_pos);
+  ALLOCATE (crval2    ,         double,          Nimage_pos);
+  ALLOCATE (crpix1    ,         float ,          Nimage_pos);
+  ALLOCATE (crpix2    ,         float ,          Nimage_pos);
+  ALLOCATE (cdelt1    ,         float ,          Nimage_pos);
+  ALLOCATE (cdelt2    ,         float ,          Nimage_pos);
+  ALLOCATE (pc1_1     ,         float ,          Nimage_pos);
+  ALLOCATE (pc1_2     ,         float ,          Nimage_pos);
+  ALLOCATE (pc2_1     ,         float ,          Nimage_pos);
+  ALLOCATE (pc2_2     ,         float ,          Nimage_pos);
+  ALLOCATE (polyterms ,         float ,          Nimage_pos);
+  ALLOCATE (ctype     ,         char  ,          Nimage_pos);
+  ALLOCATE (Npolyterms,         char  ,          Nimage_pos);
+  ALLOCATE (dXpixSys  ,         float ,          Nimage_pos);
+  ALLOCATE (dYpixSys  ,         float ,          Nimage_pos);
+  ALLOCATE (imageID   ,         int   ,          Nimage_pos);
+  ALLOCATE (nFitAstrom,         int   ,          Nimage_pos);
+  ALLOCATE (flags     ,         int   ,          Nimage_pos);
+
+  // assign the storage arrays
+  for (i = 0; i < Nimage_pos; i++) {
+    crval1    [i] = image_pos[i].coords.crval1    ;
+    crval2    [i] = image_pos[i].coords.crval2    ;
+    crpix1    [i] = image_pos[i].coords.crpix1    ;
+    crpix2    [i] = image_pos[i].coords.crpix2    ;
+    cdelt1    [i] = image_pos[i].coords.cdelt1    ;
+    cdelt2    [i] = image_pos[i].coords.cdelt2    ;
+    pc1_1     [i] = image_pos[i].coords.pc1_1     ;
+    pc1_2     [i] = image_pos[i].coords.pc1_2     ;
+    pc2_1     [i] = image_pos[i].coords.pc2_1     ;
+    pc2_2     [i] = image_pos[i].coords.pc2_2     ;
+    Npolyterms[i] = image_pos[i].coords.Npolyterms;
+    dXpixSys  [i] = image_pos[i].dXpixSys         ;
+    dYpixSys  [i] = image_pos[i].dYpixSys         ;
+    imageID   [i] = image_pos[i].imageID          ;
+    nFitAstrom[i] = image_pos[i].nFitAstrom       ;
+    flags     [i] = image_pos[i].flags            ;
+
+    // polyterms and ctype are a bit different
+    memcpy (&polyterms[i*14], &image_pos[i].coords.polyterms, 14*sizeof(float));
+    memcpy (&ctype    [i*15], &image_pos[i].coords.ctype    , 15*sizeof(char));
+  }
+
+  // add the columns to the output array
+  gfits_set_bintable_column (&theader, &ftable, "CRVAL1",      crval1    ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "CRVAL2",      crval2    ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "CRPIX1",      crpix1    ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "CRPIX2",      crpix2    ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "CDELT1",      cdelt1    ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "CDELT2",      cdelt2    ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "PC1_1",       pc1_1     ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "PC1_2",       pc1_2     ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "PC2_1",       pc2_1     ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "PC2_2",       pc2_2     ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "POLYTERMS",   polyterms ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "CTYPE",       ctype     ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "NPOLYTERMS",  Npolyterms,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "XPIX_SYS_ERR",dXpixSys  ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "YPIX_SYS_ERR",dYpixSys  ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "ID",          imageID   ,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "NFIT",        nFitAstrom,         Nimage_pos);
+  gfits_set_bintable_column (&theader, &ftable, "FLAGS",       flags     ,         Nimage_pos);
+
+  free (crval1    );
+  free (crval2    );
+  free (crpix1    );
+  free (crpix2    );
+  free (cdelt1    );
+  free (cdelt2    );
+  free (pc1_1     );
+  free (pc1_2     );
+  free (pc2_1     );
+  free (pc2_2     );
+  free (polyterms );
+  free (ctype     );
+  free (Npolyterms);
+  free (dXpixSys  );
+  free (dYpixSys  );
+  free (imageID   );
+  free (nFitAstrom);
+  free (flags     );
+  
+  FILE *f = fopen (filename, "w");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open image_pos file for output %s\n", filename);
+    return FALSE;
+  }
+
+  int status;
+  status = gfits_fwrite_header  (f, &header);
+  CHECK_STATUS (status, "ERROR: cannot write header for image_pos %s\n", filename);
+
+  status = gfits_fwrite_matrix  (f, &matrix);
+  CHECK_STATUS (status, "ERROR: cannot write matrix for image_pos %s\n", filename);
+
+  status = gfits_fwrite_Theader (f, &theader);
+  CHECK_STATUS (status, "ERROR: cannot write table header for image_pos %s\n", filename);
+
+  status = gfits_fwrite_table  (f, &ftable);
+  CHECK_STATUS (status, "ERROR: cannot write table data for image_pos %s\n", filename);
+
+  gfits_free_header (&header);
+  gfits_free_matrix (&matrix);
+  gfits_free_header (&theader);
+  gfits_free_table (&ftable);
+
+  int fd = fileno (f);
+
+  status = fflush (f);
+  CHECK_STATUS (!status, "ERROR: cannot flush file image_pos %s\n", filename);
+
+  status = fsync (fd);
+  CHECK_STATUS (!status, "ERROR: cannot flush file image_pos %s\n", filename);
+
+  status = fclose (f);
+  CHECK_STATUS (!status, "ERROR: problem closing image_pos file %s\n", filename);
+
+  return TRUE;
+}
Index: /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/indexCatalogs.c
===================================================================
--- /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/indexCatalogs.c	(revision 36564)
+++ /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/indexCatalogs.c	(revision 36565)
@@ -1,3 +1,3 @@
-# include "relphot.h"
+# include "relastro.h"
 
 static int   catIDmax = 0;
Index: /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/markObjects.c
===================================================================
--- /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/markObjects.c	(revision 36565)
+++ /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/markObjects.c	(revision 36565)
@@ -0,0 +1,22 @@
+# include "relastro.h"
+
+int markObjects (Catalog *catalog, int Ncatalog) {
+
+  int i, n;
+  off_t j;
+
+  // How strongly do I own this object?
+  for (i = 0; i < Ncatalog; i++) {
+    for (j = 0; j < catalog[i].Naverage; j++) {
+      int nOwn = 0;
+      int m = catalog[i].averageT[j].measureOffset;
+      for (n = 0; n < catalog[i].averageT[j].Nmeasure; n++) {
+	if (!catalog[i].measureT[m+n].myDet) continue;
+	nOwn ++;
+      }
+      catalog[i].averageT[j].nOwn = nOwn;
+    }
+  }
+  return TRUE;
+}
+
Index: /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/share_images_pos.c
===================================================================
--- /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/share_images_pos.c	(revision 36565)
+++ /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/share_images_pos.c	(revision 36565)
@@ -0,0 +1,115 @@
+# include "relastro.h"
+
+// we are sharing image astrometry calibrations for all images which (a) I own and (b) which have unowned detections
+
+# define D_NIMAGEPOS 1000
+int share_image_pos (RegionHostTable *regionHosts, int nloop) {
+
+  off_t i, Nimages;
+  Image *images = getimages (&Nimages, NULL);
+
+  off_t Nimage_pos = 0;
+  off_t NIMAGE_POS = D_NIMAGEPOS;
+  
+  ImagePos *image_pos = NULL;
+  ALLOCATE (image_pos, ImagePos, NIMAGE_POS);
+
+  for (i = 0; i < Nimages; i++) {
+    // XXX does this image have missing detections (does someone else need it?)
+    // XXX : NOTE NEED TO FIX THIS: if (imageExtra[i].Nmiss == 0) continue;
+    
+    set_image_pos (&image_pos[Nimage_pos], &images[i]);
+    Nimage_pos ++;
+
+    CHECK_REALLOCATE (image_pos, ImagePos, NIMAGE_POS, Nimage_pos, D_NIMAGEPOS);
+  }
+
+  // write out the image_mag fits table AND write state in some file
+  int myHost = regionHosts->index[REGION_HOST_ID];
+  char *hostname = regionHosts->hosts[myHost].hostname;
+
+  char *iposfile = make_filename (CATDIR, hostname, REGION_HOST_ID, "imagepos.fits");
+  ImagePosSave (iposfile, image_pos, Nimage_pos);
+  free (iposfile);
+
+  char *syncfile = make_filename (CATDIR, hostname, REGION_HOST_ID, "imagepos.sync");
+  update_sync_file (syncfile, nloop);
+  free (syncfile);
+
+  return TRUE;
+}
+
+int slurp_image_pos (RegionHostTable *regionHosts, int nloop) {
+
+  off_t Nimage, i;
+  Image *images = getimages (&Nimage, NULL);
+
+  int Nimage_pos = 0;
+  ImagePos *image_pos = NULL;
+  ALLOCATE (image_pos, ImagePos, 1);
+
+  fprintf (stderr, "grabbing image mags from other hosts...\n");
+
+  for (i = 0; i < regionHosts->Nhosts; i++) {
+    if (regionHosts->hosts[i].hostID == REGION_HOST_ID) continue;
+    // XXX add neighbor check? : if (not_neighbor(host[i])) continue;
+
+    char *syncfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagepos.sync");
+    check_sync_file (syncfile, nloop);
+    free (syncfile);
+    
+    off_t Nsubset;
+    char *iposfile = make_filename (CATDIR, regionHosts->hosts[i].hostname, regionHosts->hosts[i].hostID, "imagepos.fits");
+    ImagePos *image_pos_subset = ImagePosLoad (iposfile, &Nsubset);
+    free (iposfile);
+
+    image_pos = merge_image_pos (image_pos, &Nimage_pos, image_pos_subset, Nsubset);
+  }
+
+  for (i = 0; i < Nimage_pos; i++) {
+    off_t seq = getImageByID (image_pos[i].imageID);
+    if (seq < 0) {
+      // XXX is this a problem? (no, other hosts don't know which images I own)
+      continue;
+    }
+    images[seq].coords     = image_pos[i].coords    ;
+    images[seq].dXpixSys   = image_pos[i].dXpixSys  ;
+    images[seq].dYpixSys   = image_pos[i].dYpixSys  ;
+    images[seq].imageID    = image_pos[i].imageID   ;
+    images[seq].nFitAstrom = image_pos[i].nFitAstrom;
+    images[seq].flags      = image_pos[i].flags     ;
+  }
+
+  fprintf (stderr, "DONE grabbing image mags from other hosts\n");
+
+  return TRUE;
+}
+
+int set_image_pos (ImagePos *image_pos, Image *image) {
+
+  image_pos->coords       = image->coords;
+  image_pos->dXpixSys     = image->dXpixSys;
+  image_pos->dYpixSys     = image->dYpixSys;
+  image_pos->imageID      = image->imageID;
+  image_pos->nFitAstrom   = image->nFitAstrom;
+  image_pos->flags        = image->flags;
+
+  return TRUE;
+}
+
+ImagePos *merge_image_pos (ImagePos *target, int *ntarget, ImagePos *source, int Nsource) {
+
+  off_t i;
+
+  REALLOCATE (target, ImagePos, *ntarget + Nsource);
+  for (i = 0; i < Nsource; i++) {
+    off_t n = i + *ntarget;
+    target[n] = source[i];
+  }
+  
+  free (source);
+
+  *ntarget += Nsource;
+  return (target);
+}
+
Index: /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/syncfile.c
===================================================================
--- /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/syncfile.c	(revision 36565)
+++ /branches/eam_branches/ipp-20140206/Ohana/src/relastro/src/syncfile.c	(revision 36565)
@@ -0,0 +1,77 @@
+# include "relastro.h"
+# define MSG_LENGTH 12
+
+char *make_filename (char *dirname, char *hostname, int hostID, char *tailname) {
+
+  char tmp[10], *line; 
+  int Nchar = snprintf (tmp, 0, "%s/%s.%03d.%s", dirname, hostname, hostID, tailname);
+  
+  ALLOCATE (line, char, Nchar + 1);
+  snprintf (line, Nchar + 1, "%s/%s.%03d.%s", dirname, hostname, hostID, tailname);
+
+  return line;
+}
+
+int check_sync_file (char *filename, int nloop) {
+
+  char message[MSG_LENGTH];
+
+  FILE *f = NULL; 
+
+  while (TRUE) {
+
+    f = fopen (filename, "r");
+    if (!f) {
+      usleep (2000000);
+      continue;
+    }
+
+    // XXX MSG_LENGTH : 0 EOL byte?
+    int Nread = fread (message, 1, MSG_LENGTH, f);
+    if (Nread < MSG_LENGTH) {
+      fclose (f);
+      usleep (2000000);
+      continue;
+    }
+    fclose (f);
+
+    // message is of the form: NLOOP: %03d
+    int loop;
+    sscanf (message, "%*s %d", &loop);
+    if (loop != nloop) {
+      usleep (2000000);
+      continue;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+int clear_sync_file (char *filename) {
+  // delete file contents
+  truncate (filename, 0);
+
+  return TRUE;
+}
+
+int update_sync_file (char *filename, int nloop) {
+
+  char message[MSG_LENGTH];
+
+  FILE *f = fopen (filename, "w");
+  if (!f) { 
+    fprintf (stderr, "failure to open sync file for write\n");
+    exit (4);
+  }
+
+  snprintf (message, MSG_LENGTH, "NLOOP: %03d\n", nloop);
+  
+  int Nwrite = fwrite (message, 1, MSG_LENGTH, f);
+  if (Nwrite != MSG_LENGTH) {
+    fprintf (stderr, "failure to write sync message\n");
+    exit (3);
+  }
+
+  fclose (f);
+  return TRUE;
+}
