Index: trunk/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 36515)
+++ trunk/Ohana/src/dvomerge/src/dvo_image_merge_dbs.c	(revision 36528)
@@ -167,14 +167,22 @@
   off_t i, oldID, newID;
 
+  if (!IDmap->old) {
+    fprintf (stderr, "input database has image IDs, but no Image table\n");
+    return FALSE;
+  }
+
+  off_t lastID = IDmap->old[IDmap->Nmap-1];
+
   for (i = 0; i < catalog[0].Nmeasure; i++) {
     oldID = catalog[0].measure[i].imageID;
     if (oldID == 0) continue;
 
-    if (!IDmap->old) {
-      fprintf (stderr, "input database has image IDs, but no Image table\n");
-    }
-
     newID = dvo_map_image_ID (IDmap, oldID);
     if (newID == 0) {
+      if (oldID > lastID) {
+	fprintf (stderr, "problem with image IDs : input out of range\n");
+	fprintf (stderr, "old ID: "OFF_T_FMT", last ID: "OFF_T_FMT"\n", oldID, lastID);
+	exit (2);
+      }
       if (!IDmap->notFound[oldID]) {
 	fprintf (stderr, "cannot find image ID "OFF_T_FMT"\n",  oldID);
Index: trunk/Ohana/src/dvomerge/src/dvomergeUpdate.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 36515)
+++ trunk/Ohana/src/dvomerge/src/dvomergeUpdate.c	(revision 36528)
@@ -111,5 +111,5 @@
   SetPhotcodeTable(NULL);
 
-  dvomergeUpdate_catalogs (input, output, outsky, inlist, NsecfiltInput, NsecfiltOutput, &IDmap, secfiltMap);
+  int status = dvomergeUpdate_catalogs (input, output, outsky, inlist, NsecfiltInput, NsecfiltOutput, &IDmap, secfiltMap);
 
   // save the output sky table copy
@@ -123,6 +123,11 @@
   gettimeofday (&stop, NULL);
   dtime = DTIME (stop, start);
+
+  if (!status) {
+    fprintf (stderr, "ERROR: elapsed time %9.4f sec\n", dtime);
+    exit (3);
+  }
+
   fprintf (stderr, "SUCCESS: elapsed time %9.4f sec\n", dtime);
-
   exit (0);
 }
Index: trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c
===================================================================
--- trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 36515)
+++ trunk/Ohana/src/dvomerge/src/dvomergeUpdate_catalogs.c	(revision 36528)
@@ -140,4 +140,6 @@
     }
 
+    dvo_update_image_IDs (IDmap, &incatalog);
+
     // merge input into the appropriate output tables
     for (j = 0; j < outlist[0].Nregions; j++) {
@@ -156,10 +158,9 @@
       LoadCatalog (&outcatalog, outlist[0].regions[j], outcatalog.filename, "w", NsecfiltOutput);
 
-      dvo_update_image_IDs (IDmap, &incatalog);
       merge_catalogs_old (outlist[0].regions[j], &outcatalog, &incatalog, RADIUS, secfiltMap);
 
       outcatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
 
-      if (outstat[i].missed) {
+      if (outstat[j].missed) {
 	dmhObjectAdd (outstat[j].history, &outcatalog.header, inStats);
       }
@@ -280,5 +281,9 @@
   }
   if (!PARALLEL_MANUAL && !PARALLEL_SERIAL) {
-    HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
+    int status = HostTableWaitJobsGetIO (table, __FILE__, __LINE__, VERBOSE);
+    if (!status) {
+      fprintf (stderr, "error running one of the remote clients\n");
+      return status;
+    }
   }
 
Index: trunk/Ohana/src/libdvo/include/dvo.h
===================================================================
--- trunk/Ohana/src/libdvo/include/dvo.h	(revision 36515)
+++ trunk/Ohana/src/libdvo/include/dvo.h	(revision 36528)
@@ -412,4 +412,39 @@
 } MeasureTiny;
 
+/** STRUCT DEFINITION **/
+typedef struct {
+  double           R;                    // RA (decimal degrees )
+  double           D;                    // DEC (decimal degrees )
+  float            dR;                   // RA error (arcsec)
+  float            dD;                   // DEC error (arcsec)
+  float            uR;                   // RA*cos(D) proper-motion (arcsec/year)
+  float            uD;                   // DEC proper-motion (arcsec/year)
+  float            duR;                  // RA*cos(D) p-m error (arcsec/year)
+  float            duD;                  // DEC p-m error (arcsec/year)
+  float            P;                    // parallax (arcsec)
+  float            dP;                   // parallax error (arcsec)
+  float            ChiSqAve;             // astrometry analysis chisq
+  float            ChiSqPM;              // astrometry analysis chisq
+  float            ChiSqPar;             // astrometry analysis chisq
+  int              Tmean;                // mean epoch (PM,PAR ref) (unix time seconds)
+  int              Trange;               // mean epoch (PM,PAR ref) (unix time seconds)
+  float            Xp;                   // unused
+  unsigned short   Npos;                 // number of detections used for astrometry
+  unsigned short   Nmeasure;             // number of psf measurements
+  unsigned short   Nmissing;             // number of missings
+  unsigned short   Nextend;              // number of extended measurements
+  uint32_t         measureOffset;        // offset to first psf measurement
+  uint32_t         missingOffset;        // offset to first missing obs
+  uint32_t         extendOffset;         // offset to first extended measurement
+  uint32_t         flags;                // average object flags (star; ghost; etc)
+  uint32_t         photFlagsUpper;       // upper bit of 2 bit summary of per-measure photflags
+  uint32_t         photFlagsLower;       // lower bit of 2 bit summary of per-measure photflags
+  unsigned int     objID;                // unique ID for object in table
+  unsigned int     catID;                // unique ID for table in which object was first realized
+  uint64_t         extID;                // external ID for object (eg PSPS objID)
+} Average_PS1_V4alt;
+
+Average_PS1_V4alt *gfits_table_get_Average_PS1_V4alt (FTable *table, off_t *Ndata, char *swapped);
+Average *Average_PS1_V4alt_ToInternal (Average_PS1_V4alt *in, off_t Nvalues);
 
 /** STRUCT DEFINITION **/
@@ -592,4 +627,5 @@
 
 float PhotAperInst (Measure *measure);
+float PhotAperAve (PhotCode *code, Average *average, SecFilt *secfilt);
 float PhotKronInst (Measure *measure);
 float PhotKronAve (PhotCode *code, Average *average, SecFilt *secfilt);
Index: trunk/Ohana/src/libdvo/src/dbExtractAverages.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 36515)
+++ trunk/Ohana/src/libdvo/src/dbExtractAverages.c	(revision 36528)
@@ -243,4 +243,8 @@
 	  break;
 
+	case MAG_APER:
+	  value.Flt = PhotAperAve (field->photcode, average, secfilt);
+	  break;
+
 	case MAG_KRON:
 	  value.Flt = PhotKronAve (field->photcode, average, secfilt);
Index: trunk/Ohana/src/libdvo/src/dvo_convert.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 36515)
+++ trunk/Ohana/src/libdvo/src/dvo_convert.c	(revision 36528)
@@ -63,4 +63,18 @@
     fprintf (stderr, "EXTNAME missing for average table\n");
     return (FALSE);
+  }
+
+  // block to convert broken tables (PS1_V4 made before the Xfix addition)
+  if (!strcmp (extname, "DVO_AVERAGE_PS1_V4") && (ftable[0].header[0].Naxis[0] == 120)) {
+    Average_PS1_V4alt *tmpAverage;
+    tmpAverage = gfits_table_get_Average_PS1_V4alt (ftable, Naverage, NULL);
+    if (!tmpAverage) {
+      fprintf (stderr, "ERROR: failed to read averages\n");
+      exit (2);
+    }
+    average = Average_PS1_V4alt_ToInternal (tmpAverage, *Naverage);
+    free (tmpAverage);
+    *format = DVO_FORMAT_PS1_V4;
+    return (average); 
   }
 
Index: trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 36515)
+++ trunk/Ohana/src/libdvo/src/dvo_convert_PS1_V4.c	(revision 36528)
@@ -647,2 +647,125 @@
 }
 
+// 'primary' is needed to conform with the API for Loneos and Elixir, but is not used
+Average *Average_PS1_V4alt_ToInternal (Average_PS1_V4alt *in, off_t Nvalues) {
+
+  off_t i;
+  Average *out;
+
+  ALLOCATE_ZERO (out, Average, Nvalues);
+
+  for (i = 0; i < Nvalues; i++) {
+    dvo_average_init (&out[i]);
+
+    out[i].R        	 = in[i].R;      
+    out[i].D        	 = in[i].D;      
+    out[i].dR       	 = in[i].dR;
+    out[i].dD       	 = in[i].dD;
+    out[i].uR       	 = in[i].uR;
+    out[i].uD       	 = in[i].uD;
+    out[i].duR      	 = in[i].duR;
+    out[i].duD      	 = in[i].duD;
+    out[i].P        	 = in[i].P;
+    out[i].dP       	 = in[i].dP;
+    out[i].ChiSqAve    	 = in[i].ChiSqAve;     
+    out[i].ChiSqPM    	 = in[i].ChiSqPM;     
+    out[i].ChiSqPar    	 = in[i].ChiSqPar;     
+    out[i].Tmean    	 = in[i].Tmean;     
+    out[i].Trange   	 = in[i].Trange;     
+    out[i].Npos       	 = in[i].Npos;     
+    out[i].Nmeasure      = in[i].Nmeasure;     
+    out[i].Nmissing      = in[i].Nmissing;     
+    out[i].Nextend       = in[i].Nextend;     
+    out[i].measureOffset = in[i].measureOffset; 
+    out[i].missingOffset = in[i].missingOffset;
+    out[i].extendOffset  = in[i].extendOffset;
+    out[i].flags     	 = in[i].flags;   
+    out[i].photFlagsUpper = in[i].photFlagsUpper;   
+    out[i].photFlagsLower = in[i].photFlagsLower;   
+    out[i].objID 	 = in[i].objID;
+    out[i].catID 	 = in[i].catID;
+    out[i].extID 	 = in[i].extID;
+  }
+  return (out);
+}
+
+/******/
+
+int gfits_convert_Average_PS1_V4alt (Average_PS1_V4alt *data, off_t size, off_t nitems) {
+
+  off_t i;
+  unsigned char *byte, tmp;
+
+  if (size != 120) { 
+    fprintf (stderr, "WARNING: mismatch in data types Average_PS1_V4alt: "OFF_T_FMT" vs %d\n",  size,  120);
+    return (FALSE);
+  }
+
+  /* provide initial values to avoid compiler warnings for non-BYTE_SWAP arch */
+  i = tmp = 0;
+  byte = NULL;
+
+# ifdef BYTE_SWAP
+  byte = (unsigned char *) data;
+  for (i = 0; i < nitems; i++, byte += 129) {
+    /** BYTE SWAP **/
+    SWAP_DBLE (0); // RA
+    SWAP_DBLE (8); // DEC
+    SWAP_WORD (16); // RA_ERR
+    SWAP_WORD (20); // DEC_ERR
+    SWAP_WORD (24); // U_RA
+    SWAP_WORD (28); // U_DEC
+    SWAP_WORD (32); // V_RA_ERR
+    SWAP_WORD (36); // V_DEC_ERR
+    SWAP_WORD (40); // PAR
+    SWAP_WORD (44); // PAR_ERR
+    SWAP_WORD (48); // CHISQ_POS
+    SWAP_WORD (52); // CHISQ_PM
+    SWAP_WORD (56); // CHISQ_PAP
+    SWAP_WORD (60); // MEAN_EPOCH
+    SWAP_WORD (64); // TIME_RANGE
+    SWAP_WORD (68); // SIGMA
+    SWAP_BYTE (72); // NUMBER_POS
+    SWAP_BYTE (74); // NMEASURE
+    SWAP_BYTE (76); // NMISSING
+    SWAP_BYTE (78); // NEXTEND
+    SWAP_WORD (80); // OFF_MEASURE
+    SWAP_WORD (84); // OFF_MISSING
+    SWAP_WORD (88); // OFF_EXTEND
+    SWAP_WORD (92); // FLAGS
+    SWAP_WORD (96); // PHOTFLAGS_U
+    SWAP_WORD (100); // PHOTFLAGS_L
+    SWAP_WORD (104); // OBJ_ID
+    SWAP_WORD (108); // CAT_ID
+    SWAP_DBLE (112); // EXT_ID
+  }
+# endif  
+
+  return (TRUE);
+} 
+
+/*** add test of EXTNAME and header-defined columns? ***/
+/* return internal structure representation */
+Average_PS1_V4alt *gfits_table_get_Average_PS1_V4alt (FTable *ftable, off_t *Ndata, char *swapped) {
+
+  int Ncols;
+  Average_PS1_V4alt *data;
+
+  Ncols = ftable[0].header[0].Naxis[0];
+  if (Ncols != 120) {
+    fprintf (stderr, "ERROR: mis-match in table size: width is %d but should be %d bytes\n", Ncols, 176);
+    return NULL;
+  }
+
+  *Ndata = ftable[0].header[0].Naxis[1];
+  data = (Average_PS1_V4alt *) ftable[0].buffer;
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    if (!gfits_convert_Average_PS1_V4alt (data, sizeof (Average_PS1_V4alt), *Ndata)) {
+      return NULL;
+    }
+    gfits_table_scale_data (ftable);
+    if (swapped != NULL) *swapped = TRUE;
+  }
+  return (data);
+}
+
Index: trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c
===================================================================
--- trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 36515)
+++ trunk/Ohana/src/libdvo/src/dvo_photcode_ops.c	(revision 36528)
@@ -560,4 +560,16 @@
 }
 
+float PhotAperAve (PhotCode *code, Average *average, SecFilt *secfilt) {
+
+  int Ns;
+  float Maper;
+
+  if (code == NULL) return NAN;
+
+  Ns = photcodes[0].hashNsec[code[0].code];
+  Maper = (Ns == -1) ? NAN : secfilt[Ns].Map;
+  return (Maper);
+}
+
 float PhotKronAve (PhotCode *code, Average *average, SecFilt *secfilt) {
 
Index: trunk/Ohana/src/opihi/dvo/dvo_client.c
===================================================================
--- trunk/Ohana/src/opihi/dvo/dvo_client.c	(revision 36515)
+++ trunk/Ohana/src/opihi/dvo/dvo_client.c	(revision 36528)
@@ -90,4 +90,10 @@
   }
 
+  // these are set in 'startup.c' for readline-based programs
+  set_variable ("PID", getpid());
+  set_str_variable ("KAPA", "kapa");
+  set_int_variable ("UNSIGN", 0);
+  gfits_set_unsign_mode (FALSE);
+
   return;
 }
Index: trunk/Ohana/src/opihi/lib.shell/stack_math.c
===================================================================
--- trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 36515)
+++ trunk/Ohana/src/opihi/lib.shell/stack_math.c	(revision 36528)
@@ -1125,5 +1125,5 @@
   if (!strcmp (op, "floor"))  S_FUNC(floor (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "ceil"))   S_FUNC(ceil (M1), ST_SCALAR_FLT);
-  if (!strcmp (op, "rint"))   S_FUNC(nearbyint (M1), ST_SCALAR_FLT);
+  // if (!strcmp (op, "rint"))   S_FUNC(nearbyint (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "exp"))    S_FUNC(exp (M1), ST_SCALAR_FLT);
   if (!strcmp (op, "ten"))    S_FUNC(pow (10.0,M1), ST_SCALAR_FLT);
@@ -1207,5 +1207,5 @@
   if (!strcmp (op, "floor"))  V_FUNC(floor (*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "ceil"))   V_FUNC(ceil (*M1), ST_SCALAR_FLT);
-  if (!strcmp (op, "rint"))   V_FUNC(nearbyint (*M1), ST_SCALAR_FLT);
+  // if (!strcmp (op, "rint"))   V_FUNC(nearbyint (*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "exp"))    V_FUNC(exp(*M1), ST_SCALAR_FLT);
   if (!strcmp (op, "ten"))    V_FUNC(pow(10.0,*M1), ST_SCALAR_FLT);
@@ -1282,5 +1282,5 @@
   if (!strcmp (op, "floor")) { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = floor (*M1); }}
   if (!strcmp (op, "ceil"))  { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = ceil (*M1); }}
-  if (!strcmp (op, "rint"))  { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = nearbyint (*M1); }}
+  // if (!strcmp (op, "rint"))  { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = nearbyint (*M1); }}
 
   if (!strcmp (op, "exp"))   { for (i = 0; i < Nx*Ny; i++, out++, M1++) { *out = exp(*M1);          }}
Index: trunk/Ohana/src/opihi/pcontrol/CheckBusyJob.c
===================================================================
--- trunk/Ohana/src/opihi/pcontrol/CheckBusyJob.c	(revision 36515)
+++ trunk/Ohana/src/opihi/pcontrol/CheckBusyJob.c	(revision 36528)
@@ -99,6 +99,6 @@
 
   // XXX runaway job if output too large?
-  if (job[0].stdout_buf.size > 0x1000000) abort();
-  if (job[0].stderr_buf.size > 0x1000000) abort();
+  if (job[0].stdout_buf.size > 0x10000000) abort();
+  if (job[0].stderr_buf.size > 0x10000000) abort();
 
   // job has exited : move to DONE stack 
Index: trunk/Ohana/src/relphot/include/relphot.h
===================================================================
--- trunk/Ohana/src/relphot/include/relphot.h	(revision 36515)
+++ trunk/Ohana/src/relphot/include/relphot.h	(revision 36528)
@@ -86,10 +86,15 @@
   // others are only used on the final output steps.
 
-  double *list;		      // list of measure.mag values for a given star
-  double *dlist;	      // mag errors for a star
-  double *wlist;	      // weights to use for mean mags
-  double *aplist;	      // ap mags for a star
-  double *kronlist;	      // kron mags for a star
+  double *Mpsflist;           // list of measure.mag values for a given star
+  double *dpsflist;	      // mag errors for a star
+  double *wpsflist;	      // weights to use for mean mags
+
+  double *Maplist;	      // ap mags for a star
+  double *daplist;	      // ap mags for a star
+  double *waplist;	      // ap mags for a star
+
+  double *Mkronlist;	      // kron mags for a star
   double *dkronlist;	      // kron mag errors 
+  double *wkronlist;	      // kron mag errors 
 
   double *psfqf_list;	      // psfqf for all filters
@@ -97,5 +102,5 @@
   double *stargal_list;	      // stargal for all filters
 
-  StatType stats;
+  StatType psfstats;
   StatType apstats;
   StatType kronstats;
Index: trunk/Ohana/src/relphot/src/StarOps.c
===================================================================
--- trunk/Ohana/src/relphot/src/StarOps.c	(revision 36515)
+++ trunk/Ohana/src/relphot/src/StarOps.c	(revision 36528)
@@ -63,19 +63,19 @@
   results->Ngrid = 0;
   if (allocLists) {
-    ALLOCATE (results->list,  double, Nmax);
-    ALLOCATE (results->dlist, double, Nmax);
-    ALLOCATE (results->wlist, double, Nmax);
+    ALLOCATE (results->Mpsflist, double, Nmax);
+    ALLOCATE (results->dpsflist, double, Nmax);
+    ALLOCATE (results->wpsflist, double, Nmax);
   }
 }
 
 void SetMrelInfoFree (SetMrelInfo *results) {
-  free (results->list);
-  free (results->dlist);
-  free (results->wlist);
+  free (results->Mpsflist);
+  free (results->dpsflist);
+  free (results->wpsflist);
 }
 
 void SetMrelInfoAccum (SetMrelInfo *summary, SetMrelInfo *results) {
   summary->Nfew  += results->Nfew ;
-  summary->Ncode  += results->Ncode ;
+  summary->Ncode += results->Ncode ;
   summary->Nsys  += results->Nsys ;
   summary->Nbad  += results->Nbad ;
@@ -158,7 +158,12 @@
   SetMrelInfoInit (&summary, FALSE);
   SetMrelInfoInit (&results, TRUE); // allocates results->list,dlist,wlist
-  ALLOCATE (results.aplist, double, Nmax);
-  ALLOCATE (results.kronlist, double, Nmax);
+
+  ALLOCATE (results.Maplist,  double, Nmax);
+  ALLOCATE (results.daplist,  double, Nmax);
+  ALLOCATE (results.waplist,  double, Nmax);
+
+  ALLOCATE (results.Mkronlist, double, Nmax);
   ALLOCATE (results.dkronlist, double, Nmax);
+  ALLOCATE (results.wkronlist, double, Nmax);
 
   ALLOCATE (results.psfqf_list, double, Nmax);
@@ -183,7 +188,11 @@
 
   SetMrelInfoFree (&results);
-  free (results.aplist);
-  free (results.kronlist);
+  free (results.Maplist);
+  free (results.daplist);
+  free (results.waplist);
+
+  free (results.Mkronlist);
   free (results.dkronlist);
+  free (results.wkronlist);
 
   free (results.psfqf_list);
@@ -331,4 +340,6 @@
   exit (3);
 
+# if (0)
+
   off_t j, k, m, ID;
   int N;
@@ -336,5 +347,5 @@
 
   StatType stats, apstats, kronstats;
-  liststats_setmode (&stats, STATMODE);
+  liststats_setmode (&psfstats, STATMODE);
   liststats_setmode (&apstats, STATMODE);
   liststats_setmode (&kronstats, STATMODE);
@@ -837,4 +848,5 @@
   if (primaryCell) free (primaryCell);
   return (TRUE);
+# endif
 }
 
Index: trunk/Ohana/src/relphot/src/setMrelCatalog.c
===================================================================
--- trunk/Ohana/src/relphot/src/setMrelCatalog.c	(revision 36515)
+++ trunk/Ohana/src/relphot/src/setMrelCatalog.c	(revision 36528)
@@ -34,5 +34,5 @@
   off_t j;
 
-  liststats_setmode (&results->stats, STATMODE);
+  liststats_setmode (&results->psfstats, STATMODE);
   liststats_setmode (&results->apstats, STATMODE);
   liststats_setmode (&results->kronstats, STATMODE);
@@ -67,16 +67,23 @@
 
   off_t k;
-  int N;
   float Msys = 0, Mcal= 0, Mmos = 0, Mgrid = 0;
 
-  double *list      = results->list;
-  double *dlist     = results->dlist;
-  double *wlist     = results->wlist;
-  double *aplist    = results->aplist;
-  double *kronlist  = results->kronlist;
+  // we are measuring means for 3 types of mags: psf, ap, kron.  I am using the psf mag
+  // error for the ap mags, but krons have their own errors.  it is an open question if I
+  // should be doing weighted or unweighted fits (this is a user option)
+  double *Mpsflist  = results->Mpsflist;
+  double *dpsflist  = results->dpsflist;
+  double *wpsflist  = results->wpsflist;
+
+  double *Maplist   = results->Maplist;
+  double *daplist   = results->daplist;
+  double *waplist   = results->waplist;
+
+  double *Mkronlist = results->Mkronlist;
   double *dkronlist = results->dkronlist;
-
-  StatType *stats = &results->stats;
-  StatType *apstats = &results->apstats;
+  double *wkronlist = results->wkronlist;
+
+  StatType *psfstats  = &results->psfstats;
+  StatType *apstats   = &results->apstats;
   StatType *kronstats = &results->kronstats;
 
@@ -125,5 +132,7 @@
     off_t meas = measureOffset;
 
-    N = 0;
+    int Nap = 0;
+    int Npsf = 0;
+    int Nkron = 0;
     for (k = 0; k < averageT[0].Nmeasure; k++, meas++) {
 
@@ -164,4 +173,9 @@
       int myUbercalDist = getUbercalDist(meas, cat);
       minUbercalDist = MIN(minUbercalDist, myUbercalDist);
+
+      int isUbercal = (measureT[k].dbFlags & ID_MEAS_PHOTOM_UBERCAL);
+      float dMpsf = MAX (hypot(measureT[k].dM, code->photomErrSys), MIN_ERROR);
+
+      if (isUbercal) haveUbercal = TRUE; // haveUbercal is set per secfilt, isUbercal is per measure
 
       if (isSetMrelFinal) {
@@ -231,5 +245,5 @@
 	  if (measureT[k].M < MaxMagForceSynth) {
 	    forceSynth = TRUE;
-	    forceSynthEntry = N;
+	    forceSynthEntry = Npsf;
 	  } else {
 	    if (pass < 4) {
@@ -240,12 +254,21 @@
 	}
 
-	// Map (aplist) and Mkron (kronlist,dkronlist) are used to calculate mean mags per filter
+	// Map (Maplist) and Mkron (Mkronlist,dkronlist) are used to calculate mean mags per filter
 	float Map = PhotAper (&measure[k]);
-	aplist[N] = Map - Mcal - Mmos - Mgrid;
+	if (!isnan(Map)) {
+	    Maplist[Nap] = Map - Mcal - Mmos - Mgrid;
+	    daplist[Nap] = dMpsf;
+	    waplist[Nap] = isUbercal ? 10.0 : 1.0;
+	    Nap ++;
+	}
 
 	float Mkron = PhotKron (&measure[k]);
-	kronlist[N] = Mkron - Mcal - Mmos - Mgrid;
-	dkronlist[N] = measure[k].dMkron;
-      }
+	if (!isnan(Mkron)) {
+	  Mkronlist[Nkron] = Mkron - Mcal - Mmos - Mgrid;
+	  dkronlist[Nkron] = measure[k].dMkron;
+	  wkronlist[Nkron] = isUbercal ? 10.0 : 1.0;
+	  Nkron ++;
+	}
+      } // if (isSetMrelFinal)
 
       // dlist gives the error per measurement, wlist gives the weight
@@ -255,23 +278,19 @@
       // 3) UBERCAL measurements can have their weight increased by a big factor to help tie down the averages
       // 4) some reference photcode of some kind can be specified as fixed and have a high weight
-      dlist[N] = MAX (hypot(measureT[k].dM, code->photomErrSys), MIN_ERROR);
-      wlist[N] = 1.0;
-      list[N]  = Msys - Mcal - Mmos - Mgrid;
-
-      // up-weight the ubercal values (or convergence can take a long time...)
-      if (measureT[k].dbFlags & ID_MEAS_PHOTOM_UBERCAL) {
-	haveUbercal = TRUE;
-	wlist[N] = 10.0;
-      }
+      Mpsflist[Npsf] = Msys - Mcal - Mmos - Mgrid;
+      dpsflist[Npsf] = dMpsf;
+      wpsflist[Npsf] = isUbercal ? 10.0 : 1.0;
+
 
       // tie down reference photometry if the -refcode (code) option is selected
       // eg, -refcode g_SDSS
       // this probably makes no sense in the context of multifilter analysis
+      // XXX probably need to use the photocde table to assign reference mag weights.
       if (refPhotcode) {
 	if (code->code == refPhotcode->code) {
-	  wlist[N] = 100.0;
-	}
-      }
-      N++;
+	  wpsflist[Npsf] = 100.0;
+	}
+      }
+      Npsf ++;
     }
 
@@ -288,6 +307,6 @@
 
     // when performing the grid analysis, STAR_TOOFEW should be set to 1;
-    if (N < Nminmeas) { /* too few measurements */
-      // fprintf (f, "%10.6f %10.6f %d %d %d\n", averageT[0].R, averageT[0].D, measureT[0].imageID, N, STAR_TOOFEW); 
+    if (Npsf < Nminmeas) { /* too few measurements */
+      // fprintf (f, "%10.6f %10.6f %d %d %d\n", averageT[0].R, averageT[0].D, measureT[0].imageID, Npsf, STAR_TOOFEW); 
       secfilt[Nsec].flags |= ID_STAR_FEW;
       if (Ncode == 0) {
@@ -303,15 +322,15 @@
     if (forceSynth) {
       // use the single SYNTH value instead of the other mags here
-      myAssert ((forceSynthEntry < N) && (forceSynthEntry >= 0), "programming error");
-      list[0]  = list[forceSynthEntry];
-      dlist[0] = dlist[forceSynthEntry];
-      wlist[0] = wlist[forceSynthEntry];
-      N = 1;
-    }
-    liststats (list, dlist, wlist, N, stats);
-
-    secfilt[Nsec].M  = stats->mean;
-    secfilt[Nsec].dM = stats->error;
-    secfilt[Nsec].Xm = (stats->Nmeas > 1) ? 100.0*log10(stats->chisq + 1e-4) : NAN_S_SHORT;
+      myAssert ((forceSynthEntry < Npsf) && (forceSynthEntry >= 0), "programming error");
+      Mpsflist[0] = Mpsflist[forceSynthEntry];
+      dpsflist[0] = dpsflist[forceSynthEntry];
+      wpsflist[0] = wpsflist[forceSynthEntry];
+      Npsf = 1;
+    }
+    liststats (Mpsflist, dpsflist, wpsflist, Npsf, psfstats);
+
+    secfilt[Nsec].M  = psfstats->mean;
+    secfilt[Nsec].dM = psfstats->error;
+    secfilt[Nsec].Xm = (psfstats->Nmeas > 1) ? 100.0*log10(psfstats->chisq + 1e-4) : NAN_S_SHORT;
 
     // when running -averages, we have no information about the images, so we cannot set this
@@ -323,21 +342,21 @@
       found[Nsec] = TRUE;
 
-      secfilt[Nsec].Mstdev = 1000.0*stats->sigma; // Mstdev is in millimags (not enough space for more precision)
+      secfilt[Nsec].Mstdev = 1000.0*psfstats->sigma; // Mstdev is in millimags (not enough space for more precision)
       // secfilt[Nsec].Ncode = Ncode;
-      secfilt[Nsec].Nused = stats->Nmeas;
-
-      secfilt[Nsec].M_80 = 1000 * stats->Upper80;
-      secfilt[Nsec].M_20 = 1000 * stats->Lower20;
+      secfilt[Nsec].Nused = psfstats->Nmeas;
+
+      secfilt[Nsec].M_80 = 1000 * psfstats->Upper80;
+      secfilt[Nsec].M_20 = 1000 * psfstats->Lower20;
 
       // NOTE : use the modified weight for apmags as well as psf mags
-      liststats (aplist, dlist, wlist, N, apstats);
-      secfilt[Nsec].Map  = apstats->mean; 
-
-      liststats (kronlist, dkronlist, wlist, N, kronstats);
-      secfilt[Nsec].Mkron  = kronstats->mean; 
-      secfilt[Nsec].dMkron = kronstats->error; 
+      liststats (Maplist, daplist, waplist, Nap, apstats);
+      secfilt[Nsec].Map  = Nap > 0 ? apstats->mean : NAN; 
+
+      liststats (Mkronlist, dkronlist, wkronlist, Nkron, kronstats);
+      secfilt[Nsec].Mkron  = Nkron > 0 ? kronstats->mean  : NAN; 
+      secfilt[Nsec].dMkron = Nkron > 0 ? kronstats->error : NAN; 
 
       // NOTE: for 2MASS measurements, Next should be 1, as should N
-      if ((Next > 0) && (Next > 0.5*N)) {
+      if ((Next > 0) && (Next > 0.5*Npsf)) {
 	secfilt[Nsec].flags |= ID_SECF_OBJ_EXT;
       }
