Index: /branches/pap/DataStore/scripts/dsgetfileset
===================================================================
--- /branches/pap/DataStore/scripts/dsgetfileset	(revision 28002)
+++ /branches/pap/DataStore/scripts/dsgetfileset	(revision 28003)
@@ -17,5 +17,5 @@
 use File::Basename qw( basename );
 
-my ($uri, $outdir, $timeout, $skip_checks, $no_proxy, $verbose);
+my ($uri, $outdir, $timeout, $skip_checks, $unpack, $no_proxy, $verbose);
 
 GetOptions(
@@ -24,4 +24,5 @@
     'timeout|t=s'       => \$timeout,
     'skip-checks'       => \$skip_checks,
+    'unpack'            => \$unpack,
     'no-proxy'          => \$no_proxy,
     'verbose|v'         => \$verbose,
@@ -89,4 +90,24 @@
         exit $status;
     }
+
+    if ($unpack) {
+        my $file_type = `file $outfile`;
+        if ($file_type =~ /FITS/) {
+            my $packed_file = "${outfile}.fz";
+            rename $outfile, $packed_file
+                or die "failed to rename $outfile $packed_file";
+
+            # unpack the fits file and delete the input
+            # This works whether or not the file is compressed
+            $command = "funpack -D $packed_file";
+            print "$command\n" if $verbose;
+            $rc = system $command;
+            if ($rc) {
+                my $status = $rc >> 8;
+                print STDERR "failed to funpack $outfile: rc: $rc status: $status\n";
+                exit $status;
+            }
+        }
+    }
 }
 
@@ -129,4 +150,8 @@
 
 Do not load proxy environment variables.
+
+=item * --unpack
+
+Uncompress fits files if compressed
 
 Optional.
Index: /branches/pap/DataStoreServer/scripts/dsprodtool
===================================================================
--- /branches/pap/DataStoreServer/scripts/dsprodtool	(revision 28002)
+++ /branches/pap/DataStoreServer/scripts/dsprodtool	(revision 28003)
@@ -38,4 +38,5 @@
 my $dsroot;
 my $dbname;
+my $dbserver;
 my $dbpass;
 
@@ -61,4 +62,5 @@
 	'ps7=s'		=>	\$ps7,
         'dbname=s'      =>      \$dbname,
+        'dbserver=s'    =>      \$dbserver,
         'dsroot=s'      =>      \$dsroot,
 ) or pod2usage(2);
@@ -124,5 +126,6 @@
     if ($err);
 
-my $dbserver = metadataLookupStr($siteConfig, 'DS_DBSERVER');
+$dbserver = metadataLookupStr($siteConfig, 'DS_DBSERVER') 
+    unless defined $dbserver;
 $dbname      = metadataLookupStr($siteConfig, 'DS_DBNAME')
     unless defined $dbname;
Index: /branches/pap/Ohana/src/addstar/src/find_matches_closest_refstars.c
===================================================================
--- /branches/pap/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 28002)
+++ /branches/pap/Ohana/src/addstar/src/find_matches_closest_refstars.c	(revision 28003)
@@ -159,5 +159,8 @@
     /** in replace mode, search for entry and replace values M, dM, R, D */
     // XXX this fails for unsorted catalogs, right?
-    if (options.replace && replace_match (&catalog[0].average[n], catalog[0].measure, stars[N])) continue;
+    if (options.replace && replace_match (&catalog[0].average[n], catalog[0].measure, stars[N])) {
+	i++;
+	continue;
+    }
 
     /* make sure there is space for next entry */
Index: /branches/pap/Ohana/src/dvomerge/src/merge_catalogs_old.c
===================================================================
--- /branches/pap/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 28002)
+++ /branches/pap/Ohana/src/dvomerge/src/merge_catalogs_old.c	(revision 28003)
@@ -10,5 +10,5 @@
 int merge_catalogs_old (SkyRegion *region, Catalog *output, Catalog *input, double RADIUS) {
 
-  off_t i, j, n, N, Nin, offset, J, Jmin, status, Nstars;
+  off_t i, j, Nin, offset, J, Jmin, status, Nstars;
   double RADIUS2, Rmin, Rin, Din;
   double *X1, *Y1, *X2, *Y2;
@@ -152,6 +152,6 @@
     /*** a match is found, add to average, measure ***/
     Nmatch ++;
-    n = N2[Jmin];
-    N = N1[i];
+    off_t n = N2[Jmin];
+    off_t N = N1[i];
 
     /* make sure there is space for next Nmeasure entries */
@@ -223,4 +223,6 @@
   /* these new entries are all written out in UPDATE mode */ 
   for (i = 0; i < Nstars; i++) {
+    off_t N = N1[i];
+
     /* make sure there is space for next entry */
     if (Nmeas + input[0].average[N].Nmeasure >= NMEAS) {
@@ -235,5 +237,4 @@
     }
 
-    N = N1[i];
     if (input[0].found[N] >= 0) continue;
     if (!IN_REGION (input[0].average[N].R, input[0].average[N].D)) continue;
Index: /branches/pap/Ohana/src/getstar/src/MatchCoords.c
===================================================================
--- /branches/pap/Ohana/src/getstar/src/MatchCoords.c	(revision 28002)
+++ /branches/pap/Ohana/src/getstar/src/MatchCoords.c	(revision 28003)
@@ -54,5 +54,5 @@
 
 #ifdef notdef
-        printf("%d %8.1f %8.1f %s\n", i, x, y, dbImages[i].name);
+        printf("%ld %8.1f %8.1f %s\n", i, x, y, dbImages[i].name);
 #endif
 
Index: /branches/pap/Ohana/src/kapa2/doc/mark.issues.txt
===================================================================
--- /branches/pap/Ohana/src/kapa2/doc/mark.issues.txt	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/doc/mark.issues.txt	(revision 28003)
@@ -1,8 +1,13 @@
+
+* option to set window margin
+* option to add section outer box
+* option to set limits based on associated image (and change dynamically...)
+o need consistency of graph defaults : axis, tick, labels should come from kapa
+o clear should erase current plot
+
 -> The "plot" command needs to be fixed so that boundaries of contours do
 not cause it to draw excessive amounts of lines connecting unrelated
 contours. A specific "contour line type" would be useful.
-
--> DVO is not consistently placing the x/y axis labels, especially in
-user-defined sections of the plot window.
+(-pt 100?)
 
 -> DVO does not plot the end-points of histograms properly (e.g., the
@@ -13,3 +18,47 @@
 relay output to the file in the same order. Also, until DVO is closed, the
 output does not appear in the file.
+(fixed both issues)
 
+-> DVO is not consistently placing the x/y axis labels, especially in
+user-defined sections of the plot window. 
+(fixed)
+* box -labelpad -labelpad[x,y] +labelpad[x,y] -
+
+
+---
+
+
+1)You wanted me to remind you to update ~ipp-svn; this was so I could have
+the latest version of DVO on-hand
+
+2)The plotting of axis labels remains inconsistent; depending on section
+dimensions and the presence/absence of tick-marks, labels will change
+their distance from their corresponding axis. This results in labels
+falling off the screen or overlapping with other plot sections
+
+3)Plot section locations in the plot window shift if labels/tick-marks are
+present or absent
+
+4)It would be useful to have an option for the box or section command that
+causes the background to be opaque. This will allow plots to have insets.
+
+5)It would be useful to have a rectangle plotting command in order to
+shade out regions on plots
+
+6)The limits command combined with box will sometimes produce tick-marks
+with only the zero-point labeled, making the axes difficult to interpret
+
+7)Text is printed to a file at different times when using either the echo
+or fprintf commands alongside the output command. Sometimes output is
+printed to the file immediately, while other times it is printed only when
+the file is closed for output.
+
+8)The use of ^C as an interrupt does not always work when a macro is doing
+for loops.
+
+9)It would be useful for DVO to echo which line of a macro contains an
+error, or at which line it was forced to stop. This would help debugging a
+lot.
+
+10)The cgrid could use an option to print RA/DEC tick-mark labels so that
+image plots would be more informative
Index: /branches/pap/Ohana/src/kapa2/doc/notes.txt
===================================================================
--- /branches/pap/Ohana/src/kapa2/doc/notes.txt	(revision 28003)
+++ /branches/pap/Ohana/src/kapa2/doc/notes.txt	(revision 28003)
@@ -0,0 +1,8 @@
+
+2010.04.14
+
+  * one font per frame
+  * user-settable box padding
+  * user-settable label & axis-label padding
+
+  
Index: /branches/pap/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- /branches/pap/Ohana/src/kapa2/include/prototypes.h	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/include/prototypes.h	(revision 28003)
@@ -26,5 +26,5 @@
 
 /* X drawing utilities */
-void	      DrawFrame		  PROTO((KapaGraphWidget *graph));
+int	      DrawFrame		  PROTO((KapaGraphWidget *graph));
 int           DrawObjects         PROTO((KapaGraphWidget *graph));
 void          DrawLabels          PROTO((KapaGraphWidget *graph));
@@ -39,6 +39,7 @@
 void          DrawXErrors         PROTO((KapaGraphWidget *graph, Gobjects *objects));
 void          DrawYErrors         PROTO((KapaGraphWidget *graph, Gobjects *objects));
-void	      DrawTick		  PROTO((int fx, int fy, int dfx, int dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis));
+void	      DrawTick		  PROTO((Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis));
 void	      AxisTickScale	  PROTO((Axis *axis, double *major, double *minor));
+TickMarkData *CreateAxisTicks     PROTO((Axis *axis, int *nticks));
 
 /* EventLoop */
@@ -47,4 +48,5 @@
 int           Reconfig            PROTO((XEvent *event));
 void          Refresh             PROTO((void));
+void          DrawSectionBG       PROTO((Graphic *graphic, Section *section));
 
 /* CheckPipe */
@@ -61,4 +63,5 @@
 int           SetSection          PROTO((int sock));
 int           ListSection         PROTO((int sock));
+int           SetSectionBG        PROTO((int sock));
 int           MoveSection         PROTO((int sock));
 int           DefineSection       PROTO((int sock));
@@ -84,5 +87,5 @@
 void          FreeSection	  PROTO((Section *section));
 void          FreeSections	  PROTO((void));
-Section      *AddSection	  PROTO((char *name, float x, float y, float dx, float dy));
+Section      *AddSection	  PROTO((char *name, float x, float y, float dx, float dy, int bg));
 int           DelSection	  PROTO((char *name));
 int           GetSectionByName	  PROTO((char *name));
@@ -112,5 +115,5 @@
 void          PSXErrors           PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
 void          PSYErrors           PROTO((KapaGraphWidget *graph, Gobjects *objects, FILE *f));
-void	      PSTick		  PROTO((FILE *f, double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis));
+void	      PSTick		  PROTO((Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis, FILE *f));
 void          ClipLinePS          PROTO((double x0, double y0, double x1, double y1, double X0, double Y1, double X1, double Y0, FILE *f));
 int           PSimage    	  PROTO((KapaImageWidget *image, FILE *f));
@@ -131,5 +134,5 @@
 void	      bDrawXErrors	  PROTO((KapaGraphWidget *graph, Gobjects *object));
 void	      bDrawYErrors	  PROTO((KapaGraphWidget *graph, Gobjects *object));
-void	      bDrawTick		  PROTO((double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis));
+void	      bDrawTick		  PROTO((Axis *axis, int P, TickMarkData *tick, int naxis));
 void	      bDrawClipLine	  PROTO((double x0, double y0, double x1, double y1, double X0, double Y1, double X1, double Y0));
 bDrawBuffer  *bDrawIt		  PROTO((void));
Index: /branches/pap/Ohana/src/kapa2/include/structures.h
===================================================================
--- /branches/pap/Ohana/src/kapa2/include/structures.h	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/include/structures.h	(revision 28003)
@@ -137,8 +137,16 @@
   double min, max;
   char isaxis, areticks, islabel, islog;
+  double pad, labelPad, ticktextPad;
   double fx, dfx, fy, dfy;  /* axis location on graphic */
   double lweight;
   int color;
 } Axis;
+
+// structure to describe the ticks for an axis
+typedef struct {
+  double value;
+  int IsMajor;
+  int IsLabel;
+} TickMarkData;
 
 // a single graph in the display window
@@ -210,4 +218,5 @@
   float  x,  y;
   float dx, dy;
+  int bg;
   char *name;
 } Section;
Index: /branches/pap/Ohana/src/kapa2/src/CheckPipe.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/CheckPipe.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/CheckPipe.c	(revision 28003)
@@ -221,4 +221,10 @@
   }
   
+  if (!strcmp (word, "BSEC")) {
+    status = SetSectionBG (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+  
   if (!strcmp (word, "FONT")) {
     status = SetFont (sock);
Index: /branches/pap/Ohana/src/kapa2/src/DefineSection.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/DefineSection.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/DefineSection.c	(revision 28003)
@@ -4,10 +4,10 @@
 int DefineSection (int sock) {
   
-  int N, MoveSection;
+  int N, MoveSection, bg;
   char name[128];
   double x, y, dx, dy;
   Section *section;
 
-  KiiScanMessage (sock, "%s %lf %lf %lf %lf", name, &x, &y, &dx, &dy);
+  KiiScanMessage (sock, "%s %lf %lf %lf %lf %d", name, &x, &y, &dx, &dy, &bg);
 
   MoveSection = FALSE;
@@ -15,5 +15,5 @@
   N = GetSectionByName (name);
   if (N < 0) {
-    section = AddSection (name, x, y, dx, dy);
+    section = AddSection (name, x, y, dx, dy, bg);
     MoveSection = TRUE;
   } else {
@@ -30,4 +30,5 @@
     section[0].dx = dx;
     section[0].dy = dy;
+    section[0].bg = bg;
   }
 
Index: /branches/pap/Ohana/src/kapa2/src/DrawFrame.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/DrawFrame.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/DrawFrame.c	(revision 28003)
@@ -1,90 +1,66 @@
 # include "Ximage.h"
-# define MIN_RANGE 1e-10
+
 # define DrawLine(X,Y,DX,DY) (XDrawLine (graphic->display, graphic->window, graphic->gc, (int)(X), (int)(Y), (int)(X+DX), (int)(Y+DY)))
   
-static Graphic *graphic;
-
-void DrawFrame (KapaGraphWidget *graph) {
-  
-  int i, fx, fy, dfx, dfy, P, IsLabel, IsMajor;
-  double range, major, minor, first, next, lweight;
+int DrawFrame (KapaGraphWidget *graph) {
+  
+  int i, j, Nticks, P;
+  double fx, fy, dfx, dfy, lweight;
+  Graphic *graphic;
+  TickMarkData *ticks;
+  int color;
 
   graphic = GetGraphic();
 
-  /* each axis is drawn independently, but ticks and labels are placed according to
-     perpendicular distance. */
+  /* each axis is drawn independently, but ticks and labels are placed according to perpendicular distance. */
   for (i = 0; i < 4; i++) {
-    fx = graph[0].axis[i].fx;
-    fy = graph[0].axis[i].fy;
+    fx  = graph[0].axis[i].fx;
+    fy  = graph[0].axis[i].fy;
     dfx = graph[0].axis[i].dfx;
     dfy = graph[0].axis[i].dfy;
-    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
+    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
 
     lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
+    color = MAX (0, MIN (15, graph[0].axis[i].color));
+
     XSetLineAttributes (graphic->display, graphic->gc, lweight, LineSolid, CapNotLast, JoinMiter);
-    
-    graph[0].axis[i].color = MAX (0, MIN (15, graph[0].axis[i].color));
-
-    XSetForeground (graphic->display, graphic->gc, graphic->color[graph[0].axis[i].color]);
-    DrawRotTextInit (graphic->display, graphic->window, graphic->gc, graphic->color[graph[0].axis[i].color], graphic->back);
-
-    // fprintf (stderr, "axis: %d, color: %d, %ld, weight: %f\n", i, graph[0].axis[i].color, graphic->color[graph[0].axis[i].color], lweight);
+    XSetForeground (graphic->display, graphic->gc, graphic->color[color]);
+    DrawRotTextInit (graphic->display, graphic->window, graphic->gc, graphic->color[color], graphic->back);
 
     if (graph[0].axis[i].isaxis) {
       DrawLine (fx, fy, dfx, dfy);
-      // fprintf (stderr, "%d : %d %d - %d %d\n", i, fx, fy, dfx, dfy);
-      // if (i == 0) {
-      // 	int j;
-      // 	for (j = fx; j < fx + dfx; j+= 10) {
-      // 	  DrawLine (j, fy-10, 0, 20);
-      // 	}
-      // }
     }
     
     if (graph[0].axis[i].areticks) {
-      if (isnan(graph[0].axis[i].min) || isinf(graph[0].axis[i].min)) continue;
-      if (isnan(graph[0].axis[i].max) || isinf(graph[0].axis[i].max)) continue;
-
-      range = graph[0].axis[i].max - graph[0].axis[i].min;
-      if (fabs(range) < MIN_RANGE) continue;
-
-      if (fabs(range) < MIN_RANGE) {
-	range = (range < 0) ? -MIN_RANGE : +MIN_RANGE;
+      ticks = CreateAxisTicks (&graph[0].axis[i], &Nticks);
+      for (j = 0; j < Nticks; j++) {
+	DrawTick (graphic, &graph[0].axis[i], P, &ticks[j], i);
       }
-
-      AxisTickScale (&graph[0].axis[i], &major, &minor);
-
-      first = minor*((int)(graph[0].axis[i].min/minor));
-      if ((range > 0) && (first < graph[0].axis[i].min)) {
-	first += minor;
-      }
-      if ((range < 0) && (first > graph[0].axis[i].min)) {
-	first -= minor;
-      }
-      for (next = first; ((range > 0) && (next <= graph[0].axis[i].max)) || ((range < 0) && (next >= graph[0].axis[i].max));) {
-	IsMajor = FALSE;
-	IsMajor |= (fabs((int)(next/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs((int)((next + 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next - 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsLabel = (IsMajor && graph[0].axis[i].islabel);
-	DrawTick (fx, fy, dfx, dfy, P, graph[0].axis[i].min, graph[0].axis[i].max, next, IsLabel, IsMajor, i);
-	if (range > 0) 
-	  next += minor;
-	else 
-	  next -= minor;
-      }
+      FREE (ticks);
     }
   }
-}
-
-void DrawTick (int fx, int fy, int dfx, int dfy, 
-	       int P, double min, double max, 
-	       double value, int IsLabel, int IsMajor, int naxis) {
-  
-  int x, y, dx, dy, pos, dir, fontsize;
-  double size, n;
+  return (TRUE);
+}
+
+void DrawTick (Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis) {
+  
+  double x, y, dx, dy;
+  int pos, dir, fontsize;
+  double size, n, pad;
   char string[64], *fontname;
 
-  if (IsMajor) { 
+  double fx  = axis->fx;
+  double fy  = axis->fy;
+  double dfx = axis->dfx;
+  double dfy = axis->dfy;
+
+  double min = axis->min;
+  double max = axis->max;
+
+  double value = tick->value;
+
+  pos = size = 0;
+
+  if (tick->IsMajor) { 
     size = MAX (0.02, 7.0 / P); 
   } else {
@@ -92,10 +68,15 @@
   }
   
-  n = P / sqrt ((double)(dfx*dfx + dfy*dfy));
+  n = P / hypot(dfx, dfy);
   x = fx + (value-min)*dfx/(max - min);
   y = fy + (value-min)*dfy/(max - min);
 
-  dir = +1;
-  if ((naxis == 0) || (naxis == 1)) dir *= -1;
+  if ((naxis == 0) || (naxis == 2)) {
+    x = MAX(x, fx);
+  }
+  //   y = MAX(y, fy);
+  // }
+
+  dir = ((naxis == 0) || (naxis == 1)) ? -1 : +1;
   dx = dir*size*dfy*n;	
   dy = dir*size*dfx*n;
@@ -103,30 +84,28 @@
   DrawLine (x, y, dx, dy);
 
-# ifdef IN_AND_OUT_TICKS
-# define GAP 0.03
-# else
-# define GAP 0.01
-# endif
-
-  if (IsLabel) {
+  if (tick->IsLabel) {
+    int xt, yt;
+
     fontname = GetRotFont (&fontsize);
-    pos = 0;
+    
+    pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : fontsize + 4.0;
+    // pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : 0.8*fontsize + 1.0;
     
     /* temporarily assume rectilinear axes */
-    if (naxis == 0) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 1; }
-    if (naxis == 2) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 7; }
-
-    if (naxis == 1) { dy = 0; dx = -(0.8*fontsize + 1); pos = 3; }
-    if (naxis == 3) { dy = 0; dx = +(0.8*fontsize + 1); pos = 5; }
-
-    x = fx + (value-min)*dfx/(max - min) + dx;
-    y = fy + (value-min)*dfy/(max - min) + dy;
+    if (naxis == 0) { dx = 0; dy = +1.0*pad; pos = 7; }
+    if (naxis == 2) { dx = 0; dy = -1.0*pad; pos = 1; }
+
+    if (naxis == 1) { dy = 0; dx = -0.5*pad; pos = 3; }
+    if (naxis == 3) { dy = 0; dx = +0.5*pad; pos = 5; }
+
+    xt = fx + (value-min)*dfx/(max - min) + dx;
+    yt = fy + (value-min)*dfy/(max - min) + dy;
     if (fabs(value/(max-min)) < 0.001) { value = 0.0; }
     sprintf (string, "%4g", value);
-    DrawRotText (x, y, string, pos, 0.0);
-  }
-  
-}
-
+    DrawRotText (xt, yt, string, pos, 0.0);
+  }
+}
+
+# define MIN_RANGE 1e-10
 
 void AxisTickScale (Axis *axis, double *major, double *minor) {
@@ -192,2 +171,69 @@
   }
 }
+
+TickMarkData *CreateAxisTicks (Axis *axis, int *nticks) {
+
+  TickMarkData *ticks;
+  double range, major, minor, first, value, dPixels, overshoot;
+  int i, NTICKS, nPixels, done, ifirst;
+
+  *nticks = 0;
+
+  if (isnan(axis->min) || isinf(axis->min)) return NULL;
+  if (isnan(axis->max) || isinf(axis->max)) return NULL;
+  
+  range = axis->max - axis->min;
+
+  // not sure why I skip out here instead of using the MIN_RANGE value
+  if (fabs(range) < MIN_RANGE) return NULL;
+  
+  if (fabs(range) < MIN_RANGE) {
+    range = (range < 0) ? -MIN_RANGE : +MIN_RANGE;
+  }
+
+  // length of the axis in pixels
+  nPixels = hypot(axis->dfx, axis->dfy);
+  dPixels = nPixels / range; // axis pixel-scale
+
+  AxisTickScale (axis, &major, &minor);
+
+  // be a little generous 
+  NTICKS = (int)(fabs(range / minor)) + 2;
+  ALLOCATE (ticks, TickMarkData, NTICKS);
+
+  // value of the tick mark
+  ifirst = (axis->min < 0.0) ? (axis->min/minor - 0.05) : (axis->min/minor + 0.05);
+  first = minor*ifirst;
+  
+  // allow undershoot by 1 pixel
+  overshoot = (axis->min - first) * dPixels;
+  // if (overshoot > 0.5) {
+  //   if (range > 0) {
+  //     first += minor;
+  //   } else {
+  //     first -= minor;
+  //   }
+  // }
+
+  // loop to find the ticks
+  done = FALSE;
+  value = first; 
+  for (i = 0; !done && (i < NTICKS); i++) {
+    ticks[i].IsMajor = FALSE;
+    ticks[i].IsMajor |= (fabs((int)(value/major) - (value/major)) < 0.5*(minor/major));
+    ticks[i].IsMajor |= (fabs((int)((value + 0.5*minor)/major) - (value/major)) < 0.5*(minor/major));
+    ticks[i].IsMajor |= (fabs((int)((value - 0.5*minor)/major) - (value/major)) < 0.5*(minor/major));
+    ticks[i].IsLabel = (ticks[i].IsMajor && axis->islabel);
+    ticks[i].value = value;
+    if (range > 0) 
+      value += minor;
+    else 
+      value -= minor;
+    
+    done |= (range > 0) && (value > axis->max);
+    done |= (range < 0) && (value < axis->max);
+  }
+
+  *nticks = i;
+  return (ticks);
+}
Index: /branches/pap/Ohana/src/kapa2/src/DrawLabels.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/DrawLabels.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/DrawLabels.c	(revision 28003)
@@ -34,6 +34,6 @@
       switch (i) {
       case 0: pos = 7; break;
+      case 2: pos = 1; break;
       case 1: pos = 1; angle = -90; break;
-      case 2: pos = 1; break;
       case 3: pos = 1; angle =  90; break;
       case 4: pos = 2; break;
Index: /branches/pap/Ohana/src/kapa2/src/EraseSections.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/EraseSections.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/EraseSections.c	(revision 28003)
@@ -8,5 +8,5 @@
   
   FreeSections ();
-  AddSection ("default", 0.0, 0.0, 1.0, 1.0);
+  AddSection ("default", 0.0, 0.0, 1.0, 1.0, -1);
 
   if (USE_XWINDOW) XClearWindow (graphic->display, graphic->window);
Index: /branches/pap/Ohana/src/kapa2/src/Graphs.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/Graphs.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/Graphs.c	(revision 28003)
@@ -18,5 +18,20 @@
     graph[0].axis[i].lweight = 0.0;
     graph[0].axis[i].color = 0;
+    graph[0].axis[i].ticktextPad = NAN;
+    graph[0].axis[i].labelPad = NAN;
+    graph[0].axis[i].pad = NAN;
   }    
+  graph[0].data.ticktextPad = NAN;
+
+  graph[0].data.labelPadXm = NAN;
+  graph[0].data.labelPadXp = NAN;
+  graph[0].data.labelPadYm = NAN;
+  graph[0].data.labelPadYp = NAN;
+
+  graph[0].data.padXm = NAN;
+  graph[0].data.padXp = NAN;
+  graph[0].data.padYm = NAN;
+  graph[0].data.padYp = NAN;
+
   for (i = 0; i < 8; i++) {
     strcpy (graph[0].label[i].text, "");
@@ -37,6 +52,18 @@
   graph[0].data.size    = 1.0;		// point size of 1.0
 
-  graph[0].data.flipeast  = 1;		// +East  = -X by default
-  graph[0].data.flipnorth = 0;		// +North = +Y by default
+  graph[0].data.flipeast = TRUE;	// +East  = -X by default
+  graph[0].data.flipnorth = FALSE;	// +North = +Y by default
+
+  graph[0].data.coords.pc1_1 = graph[0].data.coords.pc2_2 = 1.0;
+  graph[0].data.coords.pc1_2 = graph[0].data.coords.pc2_1 = 0.0;
+  graph[0].data.coords.crval1 = 0.0;
+  graph[0].data.coords.crval2 = 0.0;
+  graph[0].data.coords.crpix1 = 0.0;
+  graph[0].data.coords.crpix2 = 0.0;
+  graph[0].data.coords.cdelt1 = graph[0].data.coords.cdelt2 = 1.0;
+  strcpy (graph[0].data.coords.ctype, "RA---LIN");
+  strcpy (graph[0].data.axis, "2222");
+  strcpy (graph[0].data.ticks, "2222");
+  strcpy (graph[0].data.labels, "2222");
 
   graph[0].Nobjects = 0;
Index: /branches/pap/Ohana/src/kapa2/src/Layout.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/Layout.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/Layout.c	(revision 28003)
@@ -43,4 +43,4 @@
 
   /* create basic section, empty of image or graph */
-  section = AddSection ("default", 0.0, 0.0, 1.0, 1.0);
+  section = AddSection ("default", 0.0, 0.0, 1.0, 1.0, -1);
 }
Index: /branches/pap/Ohana/src/kapa2/src/LoadFrame.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/LoadFrame.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/LoadFrame.c	(revision 28003)
@@ -3,7 +3,5 @@
 int LoadFrame (int sock) {
   
-  int i, color;
-  char Axis[16], Labels[16], Ticks[16];
-  double lweight;
+  int i;
   Section *section;
   KapaGraphWidget *graph;
@@ -16,7 +14,5 @@
   graph = section->graph;
 
-  KiiScanMessage (sock, "%lf %lf %lf %lf", 
-		  &graph[0].axis[0].min, &graph[0].axis[0].max, 
-		  &graph[0].axis[1].min, &graph[0].axis[1].max);
+  KapaScanGraphData (sock, &graph[0].data);
 
   graph[0].axis[3].min = graph[0].axis[1].min;
@@ -25,14 +21,24 @@
   graph[0].axis[2].max = graph[0].axis[0].max;
   
-  KiiScanMessage (sock, "%lf %d", &lweight, &color);
-  color = MAX (0, MIN (15, color));
+  // XXX this is fragile
+  graph[0].data.color = MAX (0, MIN (15, graph[0].data.color));
 
-  KiiScanMessage (sock, "%s %s %s", Axis, Labels, Ticks);
+  graph[0].axis[0].pad = graph[0].data.padXm;
+  graph[0].axis[1].pad = graph[0].data.padYm;
+  graph[0].axis[2].pad = graph[0].data.padXp;
+  graph[0].axis[3].pad = graph[0].data.padYp;
+
+  graph[0].axis[0].labelPad = graph[0].data.labelPadXm;
+  graph[0].axis[1].labelPad = graph[0].data.labelPadYm;
+  graph[0].axis[2].labelPad = graph[0].data.labelPadXp;
+  graph[0].axis[3].labelPad = graph[0].data.labelPadYp;
 
   for (i = 0; i < 4; i++) {
-    graph[0].axis[i].lweight = lweight;
-    graph[0].axis[i].color = color;
+    graph[0].axis[i].lweight = graph[0].data.lweight;
+    graph[0].axis[i].color = graph[0].data.color;
 
-    switch (Axis[i]) {
+    graph[0].axis[i].ticktextPad = graph[0].data.ticktextPad;
+
+    switch (graph[0].data.axis[i]) {
     case '0':
       graph[0].axis[i].isaxis = FALSE;
@@ -45,5 +51,5 @@
       break;
     }
-    switch (Ticks[i]) {
+    switch (graph[0].data.ticks[i]) {
     case '0':
       graph[0].axis[i].areticks = FALSE;
@@ -56,5 +62,5 @@
       break;
     }
-    switch (Labels[i]) {
+    switch (graph[0].data.labels[i]) {
     case '0':
       graph[0].axis[i].islabel = FALSE;
@@ -70,6 +76,7 @@
 
   SetSectionSizes (section);
-  if (USE_XWINDOW) DrawFrame (graph);
-  FlushDisplay ();
+  Refresh();
+  // if (USE_XWINDOW) DrawFrame (graph);
+  // FlushDisplay ();
 
   /* XXX why did I do this??? */
Index: /branches/pap/Ohana/src/kapa2/src/PSFrame.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/PSFrame.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/PSFrame.c	(revision 28003)
@@ -4,9 +4,8 @@
 int PSFrame (KapaGraphWidget *graph, FILE *f) {
   
-  int i, P, IsLabel, IsMajor, fontsize;
-  double fx, fy, dfx, dfy, range, major, minor, first, next;
-  char *fontname;
+  int i, Nticks, P;
+  double fx, fy, dfx, dfy, lweight;
   Graphic *graphic;
-  float weight;
+  TickMarkData *ticks;
   bDrawColor color;
 
@@ -14,60 +13,54 @@
 
   /* each axis is drawn independently */
-  fontname = GetRotFont (&fontsize);
   fprintf (f, "1 setlinewidth\n");
   for (i = 0; i < 4; i++) {
-    fx = graph[0].axis[i].fx;
-    fy = graphic->dy - graph[0].axis[i].fy;
+    fx  = graph[0].axis[i].fx;
+    fy  = graphic->dy - graph[0].axis[i].fy;
     dfx = graph[0].axis[i].dfx;
     dfy = -graph[0].axis[i].dfy;
-    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
+    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
 
-    weight = MAX (0, MIN (10, graph[0].axis[i].lweight));
+    lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
     color = MAX (0, MIN (15, graph[0].axis[i].color));
-    fprintf (f, "%.1f setlinewidth\n", weight);
+
+    fprintf (f, "%.1f setlinewidth\n", lweight);
     fprintf (f, "%s setrgbcolor\n", KapaColorRGBString(color));
+    // no need to init rot font
 
-    if (graph[0].axis[i].isaxis) { DrawLine (fx, fy, dfx, dfy); }
+    if (graph[0].axis[i].isaxis) { 
+      DrawLine (fx, fy, dfx, dfy); 
+    }
     
     if (graph[0].axis[i].areticks) {
-      if (isnan(graph[0].axis[i].min) || isinf(graph[0].axis[i].min)) continue;
-      if (isnan(graph[0].axis[i].max) || isinf(graph[0].axis[i].max)) continue;
-
-      range = graph[0].axis[i].max - graph[0].axis[i].min;
-      AxisTickScale (&graph[0].axis[i], &major, &minor);
-
-      first = minor*((int)(graph[0].axis[i].min/minor));
-      if ((range > 0) && (first < graph[0].axis[i].min)) {
-	first += minor;
+      ticks = CreateAxisTicks (&graph[0].axis[i], &Nticks);
+      for (i = 0; i < Nticks; i++) {
+	PSTick (graphic, &graph[0].axis[i], P, &ticks[i], i, f);
       }
-      if ((range < 0) && (first > graph[0].axis[i].min)) {
-	first -= minor;
-      }
-      for (next = first; ((range > 0) && (next <= graph[0].axis[i].max)) || ((range < 0) && (next >= graph[0].axis[i].max));) {
-	IsMajor = FALSE;
-	IsMajor |= (fabs((int)(next/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next + 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next - 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsLabel = (IsMajor && graph[0].axis[i].islabel);
-	PSTick (f, fx, fy, dfx, dfy, P, graph[0].axis[i].min, graph[0].axis[i].max, next, IsLabel, IsMajor, i);
-	if (range > 0) 
-	  next += minor;
-	else 
-	  next -= minor;
-      }
-    }
+      FREE (ticks);
+    }      
   }
   return (TRUE);
 }
 
-void PSTick (FILE *f, double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis) {
+void PSTick (Graphic *graphic, Axis *axis, int P, TickMarkData *tick, int naxis, FILE *f) {
   
+  double x, y, dx, dy;
   int pos, dir, fontsize;
-  double size, n, x, y, dx, dy;
+  double size, n, pad;
   char string[64], *fontname;
+
+  double fx  = axis->fx;
+  double fy  = graphic->dy - axis->fy;
+  double dfx = axis->dfx;
+  double dfy = -axis->dfy;
+
+  double min = axis->min;
+  double max = axis->max;
+
+  double value = tick->value;
 
   pos = size = 0;
 
-  if (IsMajor) { 
+  if (tick->IsMajor) { 
     size = MAX (0.02, 7.0 / P); 
   } else {
@@ -75,10 +68,9 @@
   }
   
-  n = P / sqrt ((double)(dfx*dfx + dfy*dfy));
+  n = P / hypot(dfx, dfy);
   x = fx + (value-min)*dfx/(max - min);
   y = fy + (value-min)*dfy/(max - min);
 
-  dir = -1;
-  if ((naxis == 0) || (naxis == 1)) dir *= -1;
+  dir = ((naxis == 0) || (naxis == 1)) ? -1 : +1;
   dx = dir*size*dfy*n;	
   dy = dir*size*dfx*n;
@@ -86,19 +78,23 @@
   DrawLine (x, y, dx, dy);
 
-  if (IsLabel) {
+  if (tick->IsLabel) {
+    int xt, yt;
+
     fontname = GetRotFont (&fontsize);
 
+    pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : 0.8*fontsize + 1.0;
+    
     /* temporarily assume rectilinear axes */
-    if (naxis == 0) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 1; }
-    if (naxis == 2) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 7; }
+    if (naxis == 0) { dx = 0; dy = +pad; pos = 1; }
+    if (naxis == 2) { dx = 0; dy = -pad; pos = 7; }
 
-    if (naxis == 1) { dy = 0; dx = -(0.8*fontsize + 1); pos = 3; }
-    if (naxis == 3) { dy = 0; dx = +(0.8*fontsize + 1); pos = 5; }
+    if (naxis == 1) { dy = 0; dx = -pad; pos = 3; }
+    if (naxis == 3) { dy = 0; dx = +pad; pos = 5; }
 
-    x = fx + (value-min)*dfx/(max - min) + dx;
-    y = fy + (value-min)*dfy/(max - min) + dy;
-    if (fabs(value) < 1e-14) { value = 0.0; }
-    sprintf (string, "%g", value);
-    PSRotText (f, (int)x, (int)y, string, pos, 0.0);
+    xt = fx + (value-min)*dfx/(max - min) + dx;
+    yt = fy + (value-min)*dfy/(max - min) + dy;
+    if (fabs(value) < 0.001) { value = 0.0; }
+    sprintf (string, "%4g", value);
+    PSRotText (f, xt, yt, string, pos, 0.0);
   }
 }
Index: /branches/pap/Ohana/src/kapa2/src/Refresh.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/Refresh.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/Refresh.c	(revision 28003)
@@ -21,4 +21,5 @@
   for (i = 0; i < Nsection; i++) {
       section = GetSectionByNumber (i);
+      DrawSectionBG (graphic, section);
       DrawImage (section->image);
       DrawGraph (section->graph);
@@ -28,2 +29,25 @@
 }
 
+void DrawSectionBG (Graphic *graphic, Section *section) {
+
+  int Ncolors;
+  int X0, Y0, dX, dY;
+
+  if (section->bg == -1) return;
+
+  Ncolors = KapaColormapSize();
+
+  if (section->bg < 0) return;
+  if (section->bg >= Ncolors) return;
+
+  XSetForeground (graphic->display, graphic->gc, graphic->color[section->bg]);
+
+  dY = graphic[0].dy * section[0].dy;
+  dX = graphic[0].dx * section[0].dx;
+  Y0 = graphic[0].dy - graphic[0].dy * section[0].y - dY;
+  X0 = graphic[0].dx * section[0].x;
+  // fprintf (stderr, "section: (%s) %d %d - %d %d\n", section[0].name, X0, Y0, dX, dY);
+
+  XFillRectangle (graphic[0].display,  graphic[0].window, graphic[0].gc, X0, Y0, dX, dY);
+  return;
+}
Index: /branches/pap/Ohana/src/kapa2/src/Sections.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/Sections.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/Sections.c	(revision 28003)
@@ -16,4 +16,5 @@
   section[0].dx = 0;
   section[0].dy = 0;
+  section[0].bg = -1;
 
   section[0].name = NULL;
@@ -42,5 +43,5 @@
 }
 
-Section *AddSection (char *name, float x, float y, float dx, float dy) {
+Section *AddSection (char *name, float x, float y, float dx, float dy, int bg) {
 
   int N;
@@ -61,4 +62,5 @@
   sections[N][0].dx = dx;
   sections[N][0].dy = dy;
+  sections[N][0].bg = bg;
   ActiveSection = N;
   return (sections[N]);
@@ -155,4 +157,22 @@
 }
 
+int SetSectionBG (int sock) {
+
+  int N, background;
+  char name[128];
+
+  KiiScanMessage (sock, "%s %d", name, &background);
+  
+  N = GetSectionByName (name);
+  if (N < 0) {
+    fprintf (stderr, "section %s not found\n", name);
+    return (TRUE);
+  }
+
+  sections[N][0].bg = background;
+
+  return (TRUE);
+}
+
 // return TRUE even for nonsense cases to avoid quitting kapa
 int MoveSection (int sock) {
Index: /branches/pap/Ohana/src/kapa2/src/SetGraphData.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/SetGraphData.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/SetGraphData.c	(revision 28003)
@@ -18,38 +18,18 @@
   graph = section->graph;
   
-  // get graph data from client 
-  KiiScanMessage (sock, "%d %d %d %d %d %d %lf %lf", 
-		  &graph[0].data.style, 
-		  &graph[0].data.ptype, 
-		  &graph[0].data.ltype, 
-		  &graph[0].data.etype, 
-		  &graph[0].data.ebar, 
-		  &graph[0].data.color, 
-		  &graph[0].data.lweight, 
-		  &graph[0].data.size);
+  KapaScanGraphData (sock, &graph[0].data);
 
-  KiiScanMessage (sock, "%lf %lf %lf %lf", 
-		  &graph[0].data.xmin, 
-		  &graph[0].data.xmax, 
-		  &graph[0].data.ymin, 
-		  &graph[0].data.ymax);
+  for (i = 0; i < 4; i++) {
+    graph[0].axis[i].ticktextPad = graph[0].data.ticktextPad;
+  }    
+  graph[0].axis[0].labelPad = graph[0].data.labelPadXm;
+  graph[0].axis[1].labelPad = graph[0].data.labelPadYm;
+  graph[0].axis[2].labelPad = graph[0].data.labelPadXp;
+  graph[0].axis[3].labelPad = graph[0].data.labelPadYp;
 
-  KiiScanMessage (sock, "%f %f %f %f", 
-		  &graph[0].data.coords.pc1_1, &graph[0].data.coords.pc2_2,
-		  &graph[0].data.coords.pc1_2, &graph[0].data.coords.pc2_1);
-
-  KiiScanMessage (sock, "%d %d %s", 
-		  &graph[0].data.flipeast, &graph[0].data.flipnorth,
-		  graph[0].data.coords.ctype);
-
-  KiiScanMessage (sock, "%lf %lf %f %f %f %f", 
-		  &graph[0].data.coords.crval1,
-		  &graph[0].data.coords.crval2,
-		  &graph[0].data.coords.crpix1,
-		  &graph[0].data.coords.crpix2,
-		  &graph[0].data.coords.cdelt1,
-		  &graph[0].data.coords.cdelt2);
-
-
+  graph[0].axis[0].pad = graph[0].data.padXm;
+  graph[0].axis[1].pad = graph[0].data.padYm;
+  graph[0].axis[2].pad = graph[0].data.padXp;
+  graph[0].axis[3].pad = graph[0].data.padYp;
 
   xmin = graph[0].data.xmin;
@@ -90,29 +70,5 @@
   graph = section->graph;
 
-  KiiSendMessage (sock, "%8d %d %d %d %d %d %f %f", 
-		  graph[0].data.style, 
-		  graph[0].data.ptype, graph[0].data.ltype, 
-		  graph[0].data.etype, graph[0].data.ebar, graph[0].data.color, 
-		  graph[0].data.lweight, graph[0].data.size);
-
-  KiiSendMessage (sock, "%g %g %g %g", 
-		  graph[0].data.xmin, graph[0].data.xmax, 
-		  graph[0].data.ymin, graph[0].data.ymax);
-
-  KiiSendMessage (sock, "%g %g %g %g", 
-		  graph[0].data.coords.pc1_1, graph[0].data.coords.pc2_2,
-		  graph[0].data.coords.pc1_2, graph[0].data.coords.pc2_1);
-
-  KiiSendMessage (sock, "%d %d %s", 
-		  graph[0].data.flipeast, graph[0].data.flipnorth,
-		  graph[0].data.coords.ctype);
-
-  KiiSendMessage (sock, "%g %g %g %g %g %g", 
-		  graph[0].data.coords.crval1,
-		  graph[0].data.coords.crval2,
-		  graph[0].data.coords.crpix1,
-		  graph[0].data.coords.crpix2,
-		  graph[0].data.coords.cdelt1,
-		  graph[0].data.coords.cdelt2);
+  KapaSendGraphData (sock, &graph[0].data);
 
   return (TRUE);
Index: /branches/pap/Ohana/src/kapa2/src/SetGraphSize.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/SetGraphSize.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/SetGraphSize.c	(revision 28003)
@@ -6,12 +6,16 @@
 void SetGraphSize (Section *section) {
 
-  int fontsize, bump, Nc;
-  int textpad, textdY, WdY; 
-  double PADx, PADy, Dx, Dy;
-  double PXm, PXp, PYm, PYp;
+  int i, Nticks;
+  int fontsize, Nc = 0;
+  int textpad, textdY, WdY;
+  int dXm, dXp, dYm, dYp;
+  double padXm, padXp, padYm, padYp;
+  double minPADx, maxPADx, minPADy;
+  double minPAD, maxPAD;
   double X0, Y0, dX, dY;
   char string[64], *fontname;
   KapaGraphWidget *graph;
   Graphic *graphic;
+  TickMarkData *ticks;
 
   if (section == NULL) return;
@@ -22,20 +26,95 @@
   fontname = GetRotFont (&fontsize);
 
-  PADx = MAX (graphic->dx / 20.0, fontsize);
-  PADy = MAX (graphic->dy / 20.0, fontsize);
-  Dx = graphic->dx - 2*PADx;
-  Dy = graphic->dy - 2*PADy;
+  minPAD = 1.0*fontsize + 0;
+  maxPAD = 2.0*fontsize + 4;
 
-  /* each graph has a padding PXm, PXp, PYm, PYp */
-  PXm = (graph[0].axis[1].islabel) ? 4*fontsize : 0;
-  PXp = (graph[0].axis[3].islabel) ? 4*fontsize : 0;
-  PYm = (graph[0].axis[0].islabel) ? 4*fontsize : 0;
-  PYp = (graph[0].axis[2].islabel) ? 4*fontsize : 0;
- 
+  minPADx = 1.5*fontsize;
+  maxPADx = 2.5*fontsize + 4.0;
+
+  minPADy = 1.5*fontsize;
+
+  // dXm : offset to label from lower x-axis, dYp : offset to label from right y-axis, etc
+  // padXm : padding below x-axis, padYp : padding to right of y-axis, etc
+
+  // offset from lower x-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not
+  if (isnan(graph[0].axis[0].labelPad)) {
+    dXm = (graph[0].axis[0].islabel) ? maxPAD  : minPAD;
+  } else {
+    dXm = graph[0].axis[0].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[0].pad)) {
+    padXm = graph[0].axis[0].islabel ? maxPADx : minPADx;
+  } else {
+    padXm = graph[0].axis[0].pad * fontsize;
+  }
+
+  // offset from upper x-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not
+  if (isnan(graph[0].axis[2].labelPad)) {
+    dXp = (graph[0].axis[2].islabel) ? maxPAD : minPAD;
+  } else {
+    dXp = graph[0].axis[2].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[2].pad)) {
+    padXp = graph[0].axis[2].islabel ? maxPADx : minPADx;
+  } else {
+    padXp = graph[0].axis[2].pad * fontsize;
+  }
+
+  // offset from left y-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not.
+  // in the auto-offset case, offset depends on the width of the tick label strings
+  if (graph[0].axis[1].islabel && (isnan(graph[0].axis[1].labelPad) || isnan(graph[0].axis[1].pad))) {
+    /* check for the max size of the axis label */
+    Nc = 0;
+    ticks = CreateAxisTicks (&graph[0].axis[1], &Nticks);
+    for (i = 0; i < Nticks; i++) {
+      if (!ticks[i].IsMajor) continue;
+      sprintf (string, "%g", ticks[i].value);
+      Nc = MAX (Nc, strlen (string));
+    }
+    FREE(ticks);
+  }
+  if (isnan(graph[0].axis[1].labelPad)) {
+    dYm = (graph[0].axis[1].islabel) ? (0.7*(Nc + 1.5)*fontsize) : minPAD;
+  } else {
+    dYm = graph[0].axis[1].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[1].pad)) {
+    padYm = graph[0].axis[1].islabel ? (0.7*(Nc + 2.5)*fontsize) : minPADy;
+  } else {
+    padYm = graph[0].axis[1].pad * fontsize;
+  }
+
+  // offset from right y-axis to labels and tick values
+  // these depend on (a) existence of tick labels and (b) auto-offset or not.
+  // in the auto-offset case, offset depends on the width of the tick label strings
+  if (graph[0].axis[3].islabel && (isnan(graph[0].axis[3].labelPad) || isnan(graph[0].axis[3].pad))) {
+    Nc = 0;
+    ticks = CreateAxisTicks (&graph[0].axis[3], &Nticks);
+    for (i = 0; i < Nticks; i++) {
+      if (!ticks[i].IsMajor) continue;
+      sprintf (string, "%g", ticks[i].value);
+      Nc = MAX (Nc, strlen (string));
+    }
+    FREE(ticks);
+  }
+  if (isnan(graph[0].axis[3].labelPad)) {
+    dYp = (graph[0].axis[3].islabel) ? (0.7*(Nc + 1.5)*fontsize) : minPAD;
+  } else {
+    dYp = graph[0].axis[3].labelPad * fontsize;
+  }
+  if (isnan(graph[0].axis[3].pad)) {
+    padYp = graph[0].axis[3].islabel ? (0.7*(Nc + 2.5)*fontsize) : minPADy;
+  } else {
+    padYp = graph[0].axis[3].pad * fontsize;
+  }
+
   /* basic size of the graph in Xwindow coordinates */
-  X0 = PADx + PXm + (Dx * section[0].x);
-  Y0 = PADy + PYm + (Dy * section[0].y);
-  dX = (Dx * section[0].dx) - PXp - PXm;
-  dY = (Dy * section[0].dy) - PYp - PYm;
+  X0 = graphic[0].dx * section[0].x + padYm;
+  Y0 = graphic[0].dy * section[0].y + padXm;
+  dX = graphic[0].dx * section[0].dx - padYm - padYp;
+  dY = graphic[0].dy * section[0].dy - padXm - padXp;
 
   // if we are tied to an image, make mods as needed
@@ -47,17 +126,17 @@
     switch (section->image->location) {
       case 1:
-	Y0 = graphic[0].dy * section[0].y + 2*PAD1 + WdY + 2; // tied to image in Y
-	dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD + 1;
-	break;
+        Y0 = graphic[0].dy * section[0].y  + 2*PAD1 + WdY + 2; // tied to image in Y
+        dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD + 1;
+        break;
       case 3:
-	dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD - PADy - PYm;
-	break;
+        dY = graphic[0].dy * section[0].dy - 5*PAD1 - WdY - COLORPAD - padYm - padYp;
+        break;
       case 2:
-	X0 = graphic[0].dx * section[0].x  + 2*PAD1 + ZOOM_X;
-	dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X;
-	break;
+        X0 = graphic[0].dx * section[0].x  + 2*PAD1 + ZOOM_X;
+        dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X;
+        break;
       case 4:
-	dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X - PADx - PXm;
-	break;
+        dX = graphic[0].dx * section[0].dx - 3*PAD1 - ZOOM_X - padXm - padXp;
+        break;
     }
   }
@@ -68,5 +147,5 @@
   graph[0].axis[0].dfx = dX;
   graph[0].axis[0].dfy = 0;
-  
+
   graph[0].axis[1].fx  = X0;
   graph[0].axis[1].fy  = graphic->dy - Y0;
@@ -84,45 +163,28 @@
   graph[0].axis[3].dfy = -dY;
 
-  PADx = 0.8*fontsize + 2;
-  PADy = 3.0*fontsize + 4;
+  /* define locations of axis labels */
+  graph[0].label[LABELLL].x = graph[0].axis[0].fx;
+  graph[0].label[LABELLL].y = graph[0].axis[0].fy + dXm;
+  graph[0].label[LABELX0].x = graph[0].axis[0].fx + 0.5*graph[0].axis[0].dfx;
+  graph[0].label[LABELX0].y = graph[0].axis[0].fy + dXm;
+  graph[0].label[LABELLR].x = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+  graph[0].label[LABELLR].y = graph[0].axis[0].fy + dXm;
 
-  /* define locations of axis labels */
-  graph[0].label[LABELX0].x = graph[0].axis[0].fx + 0.5*graph[0].axis[0].dfx;
-  bump = (graph[0].axis[0].islabel) ? PADy : PADx;
-  graph[0].label[LABELX0].y = graph[0].axis[0].fy + bump;
-
+  graph[0].label[LABELUL].x = graph[0].axis[2].fx;
+  graph[0].label[LABELUL].y = graph[0].axis[2].fy - dXp;
   graph[0].label[LABELX1].x = graph[0].axis[2].fx + 0.5*graph[0].axis[2].dfx;
-  bump = (graph[0].axis[2].islabel) ? PADy : PADx;
-  graph[0].label[LABELX1].y = graph[0].axis[2].fy - bump;
-
-  /* check for the max size of the axis label */
-  sprintf (string, "%4g", graph[0].axis[1].min);
-  Nc = strlen (string);
-  sprintf (string, "%4g", graph[0].axis[1].max);
-  Nc = MAX (Nc, strlen (string));
+  graph[0].label[LABELX1].y = graph[0].axis[2].fy - dXp;
+  graph[0].label[LABELUR].x = graph[0].axis[2].fx + graph[0].axis[2].dfx;
+  graph[0].label[LABELUR].y = graph[0].axis[2].fy - dXp;
 
   graph[0].label[LABELY0].y = graph[0].axis[1].fy + 0.5*graph[0].axis[1].dfy;
-  bump = (graph[0].axis[1].islabel) ? (0.8*Nc*fontsize + 1) : PADx;
-  graph[0].label[LABELY0].x = graph[0].axis[1].fx - bump;
-
-  sprintf (string, "%4g", graph[0].axis[3].min);
-  Nc = strlen (string);
-  sprintf (string, "%4g", graph[0].axis[3].max);
-  Nc = MAX (Nc, strlen (string));
+  graph[0].label[LABELY0].x = graph[0].axis[1].fx - dYm;
 
   graph[0].label[LABELY1].y = graph[0].axis[3].fy + 0.5*graph[0].axis[3].dfy;
-  bump = (graph[0].axis[3].islabel) ? (0.8*Nc*fontsize + 1) : PADx;
-  graph[0].label[LABELY1].x = graph[0].axis[3].fx + bump;
-  
+  graph[0].label[LABELY1].x = graph[0].axis[3].fx + dYp;
+
+  // fprintf (stderr, "section %s, %f,%f : %f,%f\n", section->name, X0, Y0, dX, dY);
+
   /* these are wrong and have to be adjusted to sit in the corners */
 
-  graph[0].label[LABELUL].x = graph[0].axis[2].fx - PADx;
-  graph[0].label[LABELUL].y = graph[0].axis[2].fy - PADx;
-  graph[0].label[LABELUR].x = graph[0].axis[2].fx + graph[0].axis[2].dfx + PADx;
-  graph[0].label[LABELUR].y = graph[0].axis[2].fy - PADx;
-  graph[0].label[LABELLL].x = graph[0].axis[0].fx - PADx;
-  graph[0].label[LABELLL].y = graph[0].axis[0].fy + PADx;
-  graph[0].label[LABELLR].x = graph[0].axis[0].fx + graph[0].axis[0].dfx + PADx;
-  graph[0].label[LABELLR].y = graph[0].axis[0].fy + PADx;
-
 }
Index: /branches/pap/Ohana/src/kapa2/src/bDrawFrame.c
===================================================================
--- /branches/pap/Ohana/src/kapa2/src/bDrawFrame.c	(revision 28002)
+++ /branches/pap/Ohana/src/kapa2/src/bDrawFrame.c	(revision 28003)
@@ -1,14 +1,16 @@
 # include "Ximage.h"
+// bDrawLine is a function, not a macro like DrawLine
 
 int bDrawFrame (KapaGraphWidget *graph) {
   
-  int i, P, IsLabel, IsMajor, fontsize;
-  double fx, fy, dfx, dfy, range, major, minor, first, next;
-  char *fontname;
-  int weight;
+  int i, Nticks, P;
+  double fx, fy, dfx, dfy, lweight;
+  // Graphic graphic; is not needed
+  TickMarkData *ticks;
   bDrawColor color;
 
+  // don't need graphic, unlink DrawFrame
+
   /* each axis is drawn independently */
-  fontname = GetRotFont (&fontsize);
   for (i = 0; i < 4; i++) {
     fx  = graph[0].axis[i].fx;
@@ -16,9 +18,12 @@
     dfx = graph[0].axis[i].dfx;
     dfy = graph[0].axis[i].dfy;
-    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
+    P = hypot (graph[0].axis[(i+1)%2].dfx, graph[0].axis[(i+1)%2].dfy);
 
-    weight = MAX (0, MIN (10, graph[0].axis[i].lweight));
+    lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
     color = MAX (0, MIN (15, graph[0].axis[i].color));
-    bDrawSetStyle (color, weight, 0);
+
+    bDrawSetStyle (color, lweight, 0);
+    // function about sets solor and weight
+    // bDrawRotTextInit does not exist
 
     if (graph[0].axis[i].isaxis) { 
@@ -27,30 +32,9 @@
     
     if (graph[0].axis[i].areticks) {
-      if (isnan(graph[0].axis[i].min) || isinf(graph[0].axis[i].min)) continue;
-      if (isnan(graph[0].axis[i].max) || isinf(graph[0].axis[i].max)) continue;
-
-      range = graph[0].axis[i].max - graph[0].axis[i].min;
-
-      AxisTickScale (&graph[0].axis[i], &major, &minor);
-
-      first = minor*((int)(graph[0].axis[i].min/minor));
-      if ((range > 0) && (first < graph[0].axis[i].min)) {
-	first += minor;
+      ticks = CreateAxisTicks (&graph[0].axis[i], &Nticks);
+      for (i = 0; i < Nticks; i++) {
+	bDrawTick (&graph[0].axis[i], P, &ticks[i], i);
       }
-      if ((range < 0) && (first > graph[0].axis[i].min)) {
-	first -= minor;
-      }
-      for (next = first; ((range > 0) && (next <= graph[0].axis[i].max)) || ((range < 0) && (next >= graph[0].axis[i].max));) {
-	IsMajor = FALSE;
-	IsMajor |= (fabs((int)(next/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next + 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsMajor |= (fabs ((int)((next - 0.5*minor)/major) - (next/major)) < 0.5*(minor/major));
-	IsLabel = (IsMajor && graph[0].axis[i].islabel);
-	bDrawTick (fx, fy, dfx, dfy, P, graph[0].axis[i].min, graph[0].axis[i].max, next, IsLabel, IsMajor, i);
-	if (range > 0) 
-	  next += minor;
-	else 
-	  next -= minor;
-      }
+      FREE (ticks);
     }
   }
@@ -58,13 +42,24 @@
 }
 
-void bDrawTick (double fx, double fy, double dfx, double dfy, int P, double min, double max, double value, int IsLabel, int IsMajor, int naxis) {
+void bDrawTick (Axis *axis, int P, TickMarkData *tick, int naxis) {
   
+  double x, y, dx, dy;
   int pos, dir, fontsize;
-  double size, n, x, y, dx, dy;
+  double size, n, pad;
   char string[64], *fontname;
+
+  double fx  = axis->fx;
+  double fy  = axis->fy;
+  double dfx = axis->dfx;
+  double dfy = axis->dfy;
+
+  double min = axis->min;
+  double max = axis->max;
+
+  double value = tick->value;
 
   pos = size = 0;
 
-  if (IsMajor) { 
+  if (tick->IsMajor) { 
     size = MAX (0.02, 7.0 / P); 
   } else {
@@ -72,10 +67,9 @@
   }
   
-  n = P / sqrt ((double)(dfx*dfx + dfy*dfy));
+  n = P / hypot(dfx, dfy);
   x = fx + (value-min)*dfx/(max - min);
   y = fy + (value-min)*dfy/(max - min);
 
-  dir = +1;
-  if ((naxis == 0) || (naxis == 1)) dir *= -1;
+  dir = ((naxis == 0) || (naxis == 1)) ? -1 : +1;
   dx = dir*size*dfy*n;	
   dy = dir*size*dfx*n;
@@ -83,19 +77,23 @@
   bDrawLine (x, y, x+dx, y+dy);
 
-  if (IsLabel) {
+  if (tick->IsLabel) {
+    int xt, yt;
+
     fontname = GetRotFont (&fontsize);
 
+    pad = !isnan(axis->ticktextPad) ? axis->ticktextPad*fontsize : 0.8*fontsize + 1.0;
+    
     /* temporarily assume rectilinear axes */
-    if (naxis == 0) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 1; }
-    if (naxis == 2) { dx = 0; dy = -dir*(0.8*fontsize + 1); pos = 7; }
+    if (naxis == 0) { dx = 0; dy = +pad; pos = 1; }
+    if (naxis == 2) { dx = 0; dy = -pad; pos = 7; }
 
-    if (naxis == 1) { dy = 0; dx = -(0.8*fontsize + 1); pos = 3; }
-    if (naxis == 3) { dy = 0; dx = +(0.8*fontsize + 1); pos = 5; }
+    if (naxis == 1) { dy = 0; dx = -pad; pos = 3; }
+    if (naxis == 3) { dy = 0; dx = +pad; pos = 5; }
 
-    x = fx + (value-min)*dfx/(max - min) + dx;
-    y = fy + (value-min)*dfy/(max - min) + dy;
-    if (fabs(value) < 1e-14) { value = 0.0; }
-    sprintf (string, "%g", value);
-    bDrawRotText ((int)x, (int)y, string, pos, 0.0);
+    xt = fx + (value-min)*dfx/(max - min) + dx;
+    yt = fy + (value-min)*dfy/(max - min) + dy;
+    if (fabs(value) < 0.001) { value = 0.0; }
+    sprintf (string, "%4g", value);
+    bDrawRotText (xt, yt, string, pos, 0.0);
   }
 }
Index: /branches/pap/Ohana/src/libdvo/include/dvo.h
===================================================================
--- /branches/pap/Ohana/src/libdvo/include/dvo.h	(revision 28002)
+++ /branches/pap/Ohana/src/libdvo/include/dvo.h	(revision 28003)
@@ -443,4 +443,5 @@
 void sort_image_subset (Image *image, off_t *subset, off_t N);
 void sort_coords_index (double *X, double *Y, off_t *S, off_t N);
+void sort_coords_indexonly (double *X, double *Y, off_t *S, off_t N);
 void sort_regions (SkyRegion *region, off_t N);
 
Index: /branches/pap/Ohana/src/libdvo/src/coordops.c
===================================================================
--- /branches/pap/Ohana/src/libdvo/src/coordops.c	(revision 28002)
+++ /branches/pap/Ohana/src/libdvo/src/coordops.c	(revision 28003)
@@ -353,5 +353,5 @@
       dY = (dM*dLdX - dL*dMdX) * Do;
 
-      // fprintf (stderr, "X,Y + dX,dY : %f, %f : %f, %f\n", X, Y, dX, dY);
+      // fprintf (stderr, "Xo,Yo + dX,dY : %f, %f : %f, %f\n", Xo, Yo, dX, dY);
 
       Xo += dX;
Index: /branches/pap/Ohana/src/libdvo/src/dvosorts.c
===================================================================
--- /branches/pap/Ohana/src/libdvo/src/dvosorts.c	(revision 28002)
+++ /branches/pap/Ohana/src/libdvo/src/dvosorts.c	(revision 28003)
@@ -46,4 +46,19 @@
 }
 
+/* sort a coordinate pair (X,Y) and the associated index (S) */
+void sort_coords_indexonly (double *X, double *Y, off_t *S, off_t N) {
+  
+# define SWAPFUNC(A,B){ off_t itmp; \
+  itmp = S[A]; S[A] = S[B]; S[B] = itmp; \
+}
+# define COMPARE(A,B)(X[S[A]] < X[S[B]])
+
+  OHANA_SORT (N, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+
+}
+
 void sort_regions (SkyRegion *region, off_t N) {
 
Index: /branches/pap/Ohana/src/libkapa/include/kapa.h
===================================================================
--- /branches/pap/Ohana/src/libkapa/include/kapa.h	(revision 28002)
+++ /branches/pap/Ohana/src/libkapa/include/kapa.h	(revision 28003)
@@ -72,4 +72,5 @@
   float dx;
   float dy;
+  int bg;
 } KapaSection;
 
@@ -78,4 +79,7 @@
   int style, ptype, ltype, etype, ebar, color;
   double lweight, size;
+  double ticktextPad;
+  double labelPadXm, labelPadYm, labelPadXp, labelPadYp;
+  double padXm, padXp, padYm, padYp;
   Coords coords;
   int flipeast, flipnorth;
@@ -173,7 +177,10 @@
 int KapaSelectSection (int fd, char *name);
 int KapaGetSection (int fd, char *name);
+int KapaSectionBG (int fd, char *name, int bg);
 int KapaMoveSection (int fd, char *name, char *direction);
 int KapaSetGraphData (int fd, Graphdata *graphmode);
 int KapaGetGraphData (int fd, Graphdata *graphmode);
+int KapaScanGraphData (int fd, Graphdata *graphmode);
+int KapaSendGraphData (int fd, Graphdata *graphmode);
 int KapaSetImageData (int fd, KapaImageData *graphmode);
 int KapaGetImageData (int fd, KapaImageData *graphmode);
Index: /branches/pap/Ohana/src/libkapa/src/KapaColors.c
===================================================================
--- /branches/pap/Ohana/src/libkapa/src/KapaColors.c	(revision 28002)
+++ /branches/pap/Ohana/src/libkapa/src/KapaColors.c	(revision 28003)
@@ -37,4 +37,6 @@
     }	
   }
+  if (!strcasecmp (name, "none")) return (-1);
+
   fprintf (stderr, "color may be one of:\n");
   for (i = 0; i < N_KAPA_COLORS; i++) {
Index: /branches/pap/Ohana/src/libkapa/src/KapaOpen.c
===================================================================
--- /branches/pap/Ohana/src/libkapa/src/KapaOpen.c	(revision 28002)
+++ /branches/pap/Ohana/src/libkapa/src/KapaOpen.c	(revision 28003)
@@ -31,8 +31,8 @@
   if (status == -1) {
     if (errno == EADDRINUSE) {
-	close (InitSocket);
-	Address[0].sin_port ++;
-	if (Address[0].sin_port > MY_PORT_MAX) exit (2);
-	goto retry_server;
+        close (InitSocket);
+        Address[0].sin_port ++;
+        if (Address[0].sin_port > MY_PORT_MAX) exit (2);
+        goto retry_server;
     }
     perror ("bind: ");
@@ -69,4 +69,5 @@
 
   /* do I need to clear rfds on each pass? */
+  FD_ZERO(&rfds);
   FD_SET (InitSocket, &rfds);
   status = select (InitSocket + 1, &rfds, NULL, NULL, &wait);
@@ -98,7 +99,7 @@
 
   for (i = 0; i < Nvalid; i++) {
-    /* valid IP addresses may be machines (120.90.121.142) or 
+    /* valid IP addresses may be machines (120.90.121.142) or
        class C networks (120.90.121.0) */
-       
+
     /* for machine, address must match */
     if ((0xff & (VALID[i] >> 24)) != 0) {
@@ -138,8 +139,8 @@
   test = TRUE;
   test &= (status == 4);
-  test &= ((ip1 > 0) && (ip1 < 256)); 
-  test &= ((ip2 > 0) && (ip2 < 256)); 
-  test &= ((ip3 > 0) && (ip3 < 256)); 
-  test &= ((ip4 >=0) && (ip4 < 256)); 
+  test &= ((ip1 > 0) && (ip1 < 256));
+  test &= ((ip2 > 0) && (ip2 < 256));
+  test &= ((ip3 > 0) && (ip3 < 256));
+  test &= ((ip4 >=0) && (ip4 < 256));
   if (!test) {
     fprintf (stderr, "invalid IP address %s\n", string);
@@ -205,5 +206,5 @@
 
   // the client uses a BLOCKing socket by default
-  fcntl (InitSocket, F_SETFL, !O_NONBLOCK); 
+  fcntl (InitSocket, F_SETFL, !O_NONBLOCK);
   return (InitSocket);
 }
@@ -211,5 +212,5 @@
 int KapaOpen (char *kapa_exec, char *kapa_name) {
 
-  // kapa_exec may be kapa://host, in which case we attempt to connect to an 
+  // kapa_exec may be kapa://host, in which case we attempt to connect to an
   // already running kapa, or the program path, in which case we are supposed
   // to launch it locally, then connect to it.
@@ -265,10 +266,10 @@
   unlink (socket_name);
 
-  strcpy (Address.sun_path, socket_name); 
-  Address.sun_family = AF_UNIX; 
-  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0); 
+  strcpy (Address.sun_path, socket_name);
+  Address.sun_family = AF_UNIX;
+  InitSocket = socket (AF_UNIX, SOCK_STREAM, 0);
   status = bind (InitSocket, (struct sockaddr *) &Address, sizeof (Address));
   status = listen (InitSocket, 1);
-  
+
   if (name == NULL) {
     sprintf (temp, "%s -socket %s &", kapa_exec, socket_name);
@@ -282,5 +283,5 @@
 
   AddressLength =  sizeof (Address);
-  fcntl (InitSocket, F_SETFL, O_NONBLOCK); 
+  fcntl (InitSocket, F_SETFL, O_NONBLOCK);
 
 # define NTRY 500
@@ -297,5 +298,5 @@
 
   // the client uses a BLOCKing socket by default
-  fcntl (fd, F_SETFL, !O_NONBLOCK); 
+  fcntl (fd, F_SETFL, !O_NONBLOCK);
   return (fd);
 }
@@ -317,5 +318,5 @@
 
   // the server uses an unblocked socket
-  fcntl (sock, F_SETFL, O_NONBLOCK);  
+  fcntl (sock, F_SETFL, O_NONBLOCK);
   unlink (sockpath);
   return (sock);
Index: /branches/pap/Ohana/src/libkapa/src/KapaWindow.c
===================================================================
--- /branches/pap/Ohana/src/libkapa/src/KapaWindow.c	(revision 28002)
+++ /branches/pap/Ohana/src/libkapa/src/KapaWindow.c	(revision 28003)
@@ -38,10 +38,7 @@
 
   KiiSendCommand (fd, 4, "DBOX");
-  KiiSendMessage (fd, "%12.6g %12.6g %12.6g %12.6g", 
-		    graphdata[0].xmin, graphdata[0].xmax, graphdata[0].ymin, graphdata[0].ymax);
-
-  KiiSendMessage (fd, "%lf %d", graphdata[0].lweight, graphdata[0].color);
-
-  KiiSendMessage (fd, "%s %s %s", graphdata[0].axis, graphdata[0].labels, graphdata[0].ticks);
+
+  KapaSendGraphData (fd, graphdata);
+
   KiiWaitAnswer (fd, "DONE");
   return (TRUE);
@@ -84,4 +81,5 @@
 }
 
+// XXX drop this function? : kapa is responsible for the graph initialization
 int KapaInitGraph (Graphdata *graphdata) {
 
@@ -103,7 +101,20 @@
   graphdata[0].flipeast = TRUE;
   graphdata[0].flipnorth = FALSE;
+
   strcpy (graphdata[0].axis, "2222");
   strcpy (graphdata[0].ticks, "2222");
   strcpy (graphdata[0].labels, "2222");
+
+  graphdata[0].ticktextPad = NAN;
+
+  graphdata[0].labelPadXm = NAN;
+  graphdata[0].labelPadXp = NAN;
+  graphdata[0].labelPadYm = NAN;
+  graphdata[0].labelPadYp = NAN;
+
+  graphdata[0].padXm = NAN;
+  graphdata[0].padXp = NAN;
+  graphdata[0].padYm = NAN;
+  graphdata[0].padYp = NAN;
 
   return (TRUE);
@@ -128,10 +139,11 @@
 }
 
-int KapaSetGraphData (int fd, Graphdata *data) {
-
-  /* tell kapa to look for the incoming image */
-  KiiSendCommand (fd, 4, "SSTY"); 
-  
+int KapaSendGraphData (int fd, Graphdata *data) {
+
   /* send kapa the plot details */
+  KiiSendMessage (fd, "%g %g %g %g", 
+		  data[0].xmin, data[0].xmax, 
+		  data[0].ymin, data[0].ymax);
+
   KiiSendMessage (fd, "%8d %d %d %d %d %d %f %f", 
 		  data[0].style, 
@@ -140,7 +152,12 @@
 		  data[0].lweight, data[0].size);
 
+  KiiSendMessage (fd, "%g %g %g %g %g", 
+		  data[0].ticktextPad,
+		  data[0].padXm, data[0].padXp, 
+		  data[0].padYm, data[0].padYp);
+
   KiiSendMessage (fd, "%g %g %g %g", 
-		  data[0].xmin, data[0].xmax, 
-		  data[0].ymin, data[0].ymax);
+		  data[0].labelPadXm, data[0].labelPadXp, 
+		  data[0].labelPadYm, data[0].labelPadYp);
 
   KiiSendMessage (fd, "%g %g %g %g", 
@@ -160,14 +177,16 @@
 		  data[0].coords.cdelt2);
 
-  KiiWaitAnswer (fd, "DONE");
-  return (TRUE);
-}
-
-int KapaGetGraphData (int fd, Graphdata *data) {
-
-  /* tell kapa to look for the incoming image */
-  KiiSendCommand (fd, 4, "GSTY"); 
-  
+  KiiSendMessage (fd, "%s %s %s", data[0].axis, data[0].ticks, data[0].labels);
+
+  return (TRUE);
+}
+
+int KapaScanGraphData (int fd, Graphdata *data) {
+
   /* send kapa the plot details */
+  KiiScanMessage (fd, "%lf %lf %lf %lf", 
+		  &data[0].xmin, &data[0].xmax, 
+		  &data[0].ymin, &data[0].ymax);
+
   KiiScanMessage (fd, "%d %d %d %d %d %d %lf %lf", 
 		  &data[0].style, 
@@ -176,7 +195,12 @@
 		  &data[0].lweight, &data[0].size);
 
+  KiiScanMessage (fd, "%lf %lf %lf %lf %lf", 
+		  &data[0].ticktextPad, 
+		  &data[0].padXm, &data[0].padXp, 
+		  &data[0].padYm, &data[0].padYp);
+
   KiiScanMessage (fd, "%lf %lf %lf %lf", 
-		  &data[0].xmin, &data[0].xmax, 
-		  &data[0].ymin, &data[0].ymax);
+		  &data[0].labelPadXm, &data[0].labelPadXp, 
+		  &data[0].labelPadYm, &data[0].labelPadYp);
 
   KiiScanMessage (fd, "%f %f %f %f", 
@@ -196,8 +220,31 @@
 		  &data[0].coords.cdelt2);
 
+  KiiScanMessage (fd, "%s %s %s", data[0].axis, data[0].ticks, data[0].labels);
+
   // XXX at some point, we need to add polynomials and 2-level mosaic
   // astrometry here.
 
   data[0].coords.Npolyterms = 0;
+
+  return (TRUE);
+}
+
+int KapaSetGraphData (int fd, Graphdata *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "SSTY"); 
+  
+  KapaSendGraphData (fd, data);
+
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaGetGraphData (int fd, Graphdata *data) {
+
+  /* tell kapa to look for the incoming image */
+  KiiSendCommand (fd, 4, "GSTY"); 
+  
+  KapaScanGraphData (fd, data);
 
   KiiWaitAnswer (fd, "DONE");
@@ -312,10 +359,19 @@
 
   KiiSendCommand (fd, 4, "DSEC");
-  KiiSendMessage (fd, "%s %6.3f %6.3f %6.3f %6.3f", 
+  KiiSendMessage (fd, "%s %6.3f %6.3f %6.3f %6.3f %3d", 
 		  section[0].name, 
 		  section[0].x,
 		  section[0].y,
 		  section[0].dx,
-		  section[0].dy);
+		  section[0].dy,
+		  section[0].bg);
+  KiiWaitAnswer (fd, "DONE");
+  return (TRUE);
+}
+
+int KapaSectionBG (int fd, char *name, int bg) {
+
+  KiiSendCommand (fd, 4, "BSEC");
+  KiiSendMessage (fd, "%s %3d", name, bg);
   KiiWaitAnswer (fd, "DONE");
   return (TRUE);
Index: /branches/pap/Ohana/src/libkapa/src/KiiPicture.c
===================================================================
--- /branches/pap/Ohana/src/libkapa/src/KiiPicture.c	(revision 28002)
+++ /branches/pap/Ohana/src/libkapa/src/KiiPicture.c	(revision 28003)
@@ -46,5 +46,5 @@
   Nwrite = write (fd, image[0].data1d, size);
   if (Nwrite != size) {
-    fprintf (stderr, "error reading picture\n");
+    fprintf (stderr, "error sending picture to kapa\n");
     return (FALSE);
   }
@@ -105,5 +105,5 @@
   Nwrite = write (fd, outbuffer, size);
   if (Nwrite != size) {
-    fprintf (stderr, "error reading picture\n");
+    fprintf (stderr, "error sending picture to kapa\n");
     return (FALSE);
   }
@@ -142,6 +142,6 @@
     Nbytes = image[0].Nx*sizeof(float);
     Nwrite = write (fd, image[0].data2d[j], Nbytes);
-    if (Nwrite != size) {
-      fprintf (stderr, "error reading picture\n");
+    if (Nwrite != Nbytes) {
+      fprintf (stderr, "error sending picture to kapa\n");
       return (FALSE);
     }
Index: /branches/pap/Ohana/src/opihi/cmd.basic/break.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.basic/break.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.basic/break.c	(revision 28003)
@@ -1,15 +1,16 @@
 # include "basic.h"
 
+// auto_break is currently a global
 int exec_break (int argc, char **argv) {
 
   int N, value;
 
+  if ((N = get_argument (argc, argv, "-h"))) goto usage;
+  if ((N = get_argument (argc, argv, "-help"))) goto usage;
+  if ((N = get_argument (argc, argv, "--help"))) goto usage;
+
   if ((N = get_argument (argc, argv, "-auto"))) {
     remove_argument (N, &argc, argv);
-    value = -1;
-    if (!strcasecmp (argv[N], "on")) value = 1;
-    if (!strcasecmp (argv[N], "off")) value = 0;
-    if (value == -1) {
-      gprint (GP_ERR, "USAGE: break -auto [on / off]\n");
+    if (N == argc) {
       if (auto_break) 
 	gprint (GP_ERR, "auto break on\n");
@@ -18,10 +19,17 @@
       return (FALSE);
     }
+    value = -1;
+    if (!strcasecmp (argv[N], "on")) value = 1;
+    if (!strcasecmp (argv[N], "off")) value = 0;
+    if (value == -1) goto usage;
     auto_break = value;
     return (TRUE);
   }
-
+  
   loop_break = TRUE;
   return (FALSE);
-
+  
+usage:
+  gprint (GP_ERR, "USAGE: break -auto [on / off]\n");
+  return (FALSE);
 }
Index: /branches/pap/Ohana/src/opihi/cmd.basic/opihi.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.basic/opihi.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.basic/opihi.c	(revision 28003)
@@ -3,8 +3,8 @@
 int opihi_setmode (int argc, char **argv) {
 
-  int value;
+  OpihiVerboseMode value;
 
   if (argc < 2) {
-    gprint (GP_ERR, "USAGE: opihi (verbose) [on/off]\n");
+    gprint (GP_ERR, "USAGE: opihi (verbose) [on/off/error]\n");
     return (FALSE);
   }
@@ -13,17 +13,30 @@
       if (argc == 2) {
 	  value = get_verbose_shell();
-	  if (value) {
-	    gprint (GP_ERR, "opihi verbose mode: on\n");
-	  } else {
-	    gprint (GP_ERR, "opihi verbose mode: off\n");
-	  }
+	  switch (value) {
+	    case OPIHI_VERBOSE_OFF:
+	      gprint (GP_ERR, "opihi verbose mode: off\n");
+	      break;
+	    case OPIHI_VERBOSE_ON:
+	      gprint (GP_ERR, "opihi verbose mode: on\n");
+	      break;
+	    case OPIHI_VERBOSE_ERROR:
+	      gprint (GP_ERR, "opihi verbose mode: error\n");
+	      break;
+	    default:
+	      fprintf (stderr, "impossible condition\n");
+	      abort();
+	  } 
 	  return (TRUE);
       }
       if (!strcasecmp(argv[2], "on")) {
-	set_verbose_shell (TRUE);
+	set_verbose_shell (OPIHI_VERBOSE_ON);
 	return (TRUE);
       }
       if (!strcasecmp(argv[2], "off")) {
-	set_verbose_shell (FALSE);
+	set_verbose_shell (OPIHI_VERBOSE_OFF);
+	return (TRUE);
+      }
+      if (!strcasecmp(argv[2], "error")) {
+	set_verbose_shell (OPIHI_VERBOSE_ERROR);
 	return (TRUE);
       }
Index: /branches/pap/Ohana/src/opihi/cmd.basic/run_for.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.basic/run_for.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.basic/run_for.c	(revision 28003)
@@ -7,5 +7,5 @@
   int ThisList, depth, i, done, status, found, NLINES, j;
   double start, end, delta;
-  char *input;
+  char *input, *endptr;
   double value, sign;
   Macro loop;
@@ -16,8 +16,24 @@
   }
 
-  start = atof (argv[2]);
-  end   = atof (argv[3]);
+  start = strtod (argv[2], &endptr);
+  if (*endptr) {
+    gprint (GP_ERR, "for loop starting value must be numerical (%s)\n", argv[2]);
+    return (FALSE);
+  }
+
+  end = strtod (argv[3], &endptr);
+  if (*endptr) {
+    gprint (GP_ERR, "for loop ending value must be numerical (%s)\n", argv[3]);
+    return (FALSE);
+  }
+
   delta = 1.0;
-  if (argc == 5) delta = atof (argv[4]);
+  if (argc == 5) { 
+    delta = strtod (argv[4], &endptr);
+    if (*endptr) {
+      gprint (GP_ERR, "for loop delta value must be numerical (%s)\n", argv[4]);
+      return (FALSE);
+    }
+  }
   sign = SIGN(delta);
 
Index: /branches/pap/Ohana/src/opihi/cmd.data/Makefile
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/Makefile	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/Makefile	(revision 28003)
@@ -72,4 +72,5 @@
 $(SRC)/lookup.$(ARCH).o	\
 $(SRC)/matrix.$(ARCH).o	\
+$(SRC)/match2d.$(ARCH).o	\
 $(SRC)/mkrgb.$(ARCH).o	\
 $(SRC)/mcreate.$(ARCH).o	\
Index: /branches/pap/Ohana/src/opihi/cmd.data/box.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/box.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/box.c	(revision 28003)
@@ -25,5 +25,5 @@
   } 
 
-  graphmode.lweight = 1;
+  // graphmode.lweight = 1;
   if ((N = get_argument (argc, argv, "-lw"))) {
     remove_argument (N, &argc, argv);
@@ -32,5 +32,5 @@
   }
 
-  graphmode.color = KapaColorByName ("black");
+  // graphmode.color = KapaColorByName ("black");
   if ((N = get_argument (argc, argv, "-c"))) {
     remove_argument (N, &argc, argv);
@@ -40,5 +40,6 @@
   }
 
-  strcpy (graphmode.ticks, "2222");
+  // XXX need to get the current values from kapa
+  // strcpy (graphmode.ticks, "2222");
   if ((N = get_argument (argc, argv, "-ticks"))) {
     remove_argument (N, &argc, argv);
@@ -51,5 +52,5 @@
   }
   
-  strcpy (graphmode.labels, "2222");
+  // strcpy (graphmode.labels, "2222");
   if ((N = get_argument (argc, argv, "-labels"))) {
     remove_argument (N, &argc, argv);
@@ -62,5 +63,5 @@
   }
 
-  strcpy (graphmode.axis, "2222");
+  // strcpy (graphmode.axis, "2222");
   if ((N = get_argument (argc, argv, "-axis"))) {
     remove_argument (N, &argc, argv);
@@ -71,4 +72,72 @@
       if ((graphmode.axis[i] != '0') && (graphmode.axis[i] != '1') && (graphmode.axis[i] != '2')) { goto usage; }
     }
+  }
+
+  if ((N = get_argument (argc, argv, "-tickpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.ticktextPad = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-labelpadx"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadXm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-labelpady"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadYm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "+labelpadx"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadXp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "+labelpady"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-labelpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.labelPadXm = atof(argv[N]);
+    graphmode.labelPadXp = atof(argv[N]);
+    graphmode.labelPadYm = atof(argv[N]);
+    graphmode.labelPadYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+
+  if ((N = get_argument (argc, argv, "-pad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padXm = atof(argv[N]);
+    graphmode.padXp = atof(argv[N]);
+    graphmode.padYm = atof(argv[N]);
+    graphmode.padYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-xpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padXm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "+xpad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padXp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "-ypad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padYm = atof(argv[N]);
+    remove_argument (N, &argc, argv);
+  }
+  if ((N = get_argument (argc, argv, "+ypad"))) {
+    remove_argument (N, &argc, argv);
+    graphmode.padYp = atof(argv[N]);
+    remove_argument (N, &argc, argv);
   }
 
Index: /branches/pap/Ohana/src/opihi/cmd.data/create.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/create.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/create.c	(revision 28003)
@@ -14,5 +14,6 @@
 
   if ((argc != 5) && (argc != 4)) {
-    gprint (GP_ERR, "USAGE: create vector start end [delta]\n");
+    gprint (GP_ERR, "USAGE: create vector start end [delta] [-int]\n");
+    gprint (GP_ERR, " -int : resulting vector is integer type (delta must be integer)\n");
     return (FALSE);
   }
@@ -20,8 +21,9 @@
   if ((vec = SelectVector (argv[1], ANYVECTOR, TRUE)) == NULL) return (FALSE);
 
+  delta = 1;
   start = atof (argv[2]);
   end   = atof (argv[3]);
-  delta = 1;
   if (argc == 5) delta = atof (argv[4]);
+
   if ((start == end) || (delta == 0)) {
     gprint (GP_ERR, "error in value: %f to %f, %f\n", start, end, delta);
Index: /branches/pap/Ohana/src/opihi/cmd.data/fit1d.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/fit1d.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/fit1d.c	(revision 28003)
@@ -53,9 +53,9 @@
     return (FALSE);
   }
-  REQUIRE_VECTOR_FLT (xvec, FALSE); 
-  REQUIRE_VECTOR_FLT (yvec, FALSE); 
+  CastVector (xvec, OPIHI_FLT);
+  CastVector (yvec, OPIHI_FLT);
 
   if (Weight) {
-    REQUIRE_VECTOR_FLT (dyvec, FALSE); 
+    CastVector (dyvec, OPIHI_FLT);
     if (xvec[0].Nelements != dyvec[0].Nelements) {
       gprint (GP_ERR, "vectors must have same length\n");
Index: /branches/pap/Ohana/src/opihi/cmd.data/fit2d.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/fit2d.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/fit2d.c	(revision 28003)
@@ -64,10 +64,10 @@
     return (FALSE);
   }
-  REQUIRE_VECTOR_FLT (xvec, FALSE); 
-  REQUIRE_VECTOR_FLT (yvec, FALSE); 
-  REQUIRE_VECTOR_FLT (zvec, FALSE); 
+  CastVector (xvec, OPIHI_FLT);
+  CastVector (yvec, OPIHI_FLT);
+  CastVector (zvec, OPIHI_FLT);
 
   if (Weight) {
-    REQUIRE_VECTOR_FLT (dzvec, FALSE); 
+    CastVector (dzvec, OPIHI_FLT);
     if (xvec[0].Nelements != dzvec[0].Nelements) {
       gprint (GP_ERR, "vectors must have same length\n");
Index: /branches/pap/Ohana/src/opihi/cmd.data/histogram.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/histogram.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/histogram.c	(revision 28003)
@@ -3,11 +3,18 @@
 int histogram (int argc, char **argv) {
   
-  int i, bin, Nbins;
+  int i, N, bin, Nbins;
   opihi_int *OUT;
   opihi_flt start, end, delta;
-  Vector *xvec, *yvec;
+  Vector *xvec, *yvec, *range;
+
+  range = NULL;
+  if ((N = get_argument (argc, argv, "-range"))) {
+    remove_argument (N, &argc, argv);
+    if ((range = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+  }
 
   if ((argc != 6) && (argc != 5)) {
-    gprint (GP_ERR, "USAGE: hist invec outvec start end [delta]\n");
+    gprint (GP_ERR, "USAGE: hist invec outvec start end [delta] [-range range]\n");
     return (FALSE);
   }
@@ -31,4 +38,11 @@
   if ((xvec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);
   if ((yvec = SelectVector (argv[2], ANYVECTOR, TRUE)) == NULL) return (FALSE);
+
+  if (range) {
+    ResetVector (range, OPIHI_FLT, Nbins);
+    for (i = 0; i < range[0].Nelements; i++) {
+      range[0].elements.Flt[i] = start + i*delta;
+    }
+  }
 
   ResetVector (yvec, OPIHI_INT, Nbins);
Index: /branches/pap/Ohana/src/opihi/cmd.data/init.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/init.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/init.c	(revision 28003)
@@ -61,4 +61,5 @@
 int lookup           PROTO((int, char **));
 int matrix           PROTO((int, char **));
+int match2d          PROTO((int, char **));
 int mkrgb            PROTO((int, char **));
 int mcreate          PROTO((int, char **));
@@ -201,4 +202,5 @@
   {1, "iminterp",     minterp,          "interpolate image pixels"},
   {1, "matrix",       matrix,           "matrix math operations"},
+  {1, "match2d",      match2d,          "match 2 pairs of X,Y vectors and return matched indexes"},
   {1, "mkrgb",        mkrgb,            "convert 3 images to rgb jpeg (use Kapa for better control)"},
   {1, "mset",         mset,             "insert a vector in an image"},
Index: /branches/pap/Ohana/src/opihi/cmd.data/match2d.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/match2d.c	(revision 28003)
+++ /branches/pap/Ohana/src/opihi/cmd.data/match2d.c	(revision 28003)
@@ -0,0 +1,133 @@
+# include "data.h"
+int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2);
+
+// match2d (X1) (Y1) (X2) (Y2) (Radius) [-index1 (index1)] [-index2 (index2)] [-nomatch1 nomatch1] [-nomatch2 nomatch2]
+// X1[Index1] <=> X2[Index2] (etc)
+int match2d (int argc, char **argv) {
+  
+  int N;
+  double Radius;
+  char *endptr;
+  Vector *X1vec, *Y1vec, *X2vec, *Y2vec;
+  Vector *index1, *index2;
+
+  if ((N = get_argument (argc, argv, "-index1"))) {
+    remove_argument (N, &argc, argv);
+    if ((index1 = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+  } else {
+    if ((index1 = SelectVector ("index1", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+  }
+
+  if ((N = get_argument (argc, argv, "-index2"))) {
+    remove_argument (N, &argc, argv);
+    if ((index2 = SelectVector (argv[N], ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+    remove_argument (N, &argc, argv);
+  } else {
+    if ((index2 = SelectVector ("index2", ANYVECTOR, TRUE)) == NULL) return (FALSE);    
+  }
+
+  if (argc != 6) {
+    gprint (GP_ERR, "USAGE: match2d X1 Y1 X2 Y2 Radius [-index1 (index1)] [-index2 (index2)] [-closest]\n");
+    // gprint (GP_ERR, "USAGE: match2d X1 Y1 X2 Y2 Radius [-index1 (index1)] [-index2 (index2)] [-closest]\n");
+    // gprint (GP_ERR, "  if -closest is provided, index1 & index2 will have the same length as X1 and X2 (respectively)\n");
+    // gprint (GP_ERR, "    with either the index of the match or a value of -1 for non-matches\n");
+    return (FALSE);
+  }
+
+  if ((X1vec = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((Y1vec = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((X2vec = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+  if ((Y2vec = SelectVector (argv[4], OLDVECTOR, TRUE)) == NULL) return (FALSE);    
+
+  if (X1vec[0].Nelements != Y1vec[0].Nelements) {
+    gprint (GP_ERR, "X1 & Y1 vectors must have same length\n");
+    return (FALSE);
+  }
+  if (X2vec[0].Nelements != Y2vec[0].Nelements) {
+    gprint (GP_ERR, "X2 & Y2 vectors must have same length\n");
+    return (FALSE);
+  }
+
+  REQUIRE_VECTOR_FLT (X1vec, FALSE); 
+  REQUIRE_VECTOR_FLT (Y1vec, FALSE); 
+  REQUIRE_VECTOR_FLT (X2vec, FALSE); 
+  REQUIRE_VECTOR_FLT (Y2vec, FALSE); 
+
+  Radius = strtod (argv[5], &endptr);
+  if (*endptr) {
+    gprint (GP_ERR, "Radius must be numerical (%s)\n", argv[5]);
+    return (FALSE);
+  }
+
+  find_matches2d (X1vec, Y1vec, X2vec, Y2vec, Radius, index1, index2);
+
+  return (TRUE);
+}
+
+// we are not defining a relative offset DX,DY for now
+int find_matches2d (Vector *X1, Vector *Y1, Vector *X2, Vector *Y2, double Radius, Vector *index1, Vector *index2) {
+  
+  off_t i, j, first_j, I, J, *N1, *N2, Nmatch, NMATCH, DMATCH;
+  double dX, dY, dR, Radius2;
+
+  NMATCH = MAX(MAX(0.01*X1->Nelements, 0.01*X2->Nelements), 100);
+  DMATCH = NMATCH;
+
+  ResetVector (index1, OPIHI_INT, NMATCH);
+  ResetVector (index2, OPIHI_INT, NMATCH);
+
+  ALLOCATE (N1, off_t, X1->Nelements);
+  ALLOCATE (N2, off_t, X2->Nelements);
+
+  for (i = 0; i < X1->Nelements; i++) { N1[i] = i; }
+  for (i = 0; i < X2->Nelements; i++) { N2[i] = i; }
+
+  sort_coords_indexonly (X1->elements.Flt, Y1->elements.Flt, N1, X1->Nelements);
+  sort_coords_indexonly (X2->elements.Flt, Y2->elements.Flt, N2, X2->Nelements);
+
+  Radius2 = Radius*Radius;
+
+  Nmatch = 0;
+  for (i = j = 0; (i < X1->Nelements) && (j < X2->Nelements);) {
+    I = N1[i];
+    J = N2[j];
+
+    dX = X1->elements.Flt[I] - X2->elements.Flt[J];
+
+    if (dX <= -1.02*Radius) { i++; continue; }
+    if (dX >= +1.02*Radius) { j++; continue; }
+
+    // look for all matches of list2() to list1(i)
+    first_j = j;
+    for (j = first_j; (dX > -1.02*Radius) && (j < X2->Nelements); j++) {
+      J = N2[j];
+      dX = X1->elements.Flt[I] - X2->elements.Flt[J];
+      dY = Y1->elements.Flt[I] - Y2->elements.Flt[J];
+      dR = dX*dX + dY*dY;
+      if (dR < Radius2) {
+	index1->elements.Int[Nmatch] = I;
+	index2->elements.Int[Nmatch] = J;
+
+	// XXX track matches 1 and 2 with internal vector, save new nomatch index vectors
+	// after this loop
+
+	Nmatch ++;
+	if (Nmatch >= NMATCH) {
+	  NMATCH += DMATCH;
+	  REALLOCATE (index1->elements.Int, opihi_int, NMATCH);
+	  REALLOCATE (index2->elements.Int, opihi_int, NMATCH);
+	}
+      }
+    }
+    j = first_j;
+    i++;
+  }
+  index1->Nelements = Nmatch;
+  index2->Nelements = Nmatch;
+
+  free (N1);
+  free (N2);
+
+  return (TRUE);
+}
Index: /branches/pap/Ohana/src/opihi/cmd.data/section.c
===================================================================
--- /branches/pap/Ohana/src/opihi/cmd.data/section.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/cmd.data/section.c	(revision 28003)
@@ -1,9 +1,9 @@
 # include "data.h"
 
-enum {NONE, LIST, UP, DOWN, TOP, BOTTOM, TOOL};
+enum {NONE, LIST, UP, DOWN, TOP, BOTTOM, TOOL, BG};
 
 int section (int argc, char **argv) {
   
-  int N, action, kapa;
+  int N, action, kapa, background;
   Graphdata graphmode;
   KapaSection section;
@@ -37,4 +37,16 @@
     location = argv[N];
     remove_argument (N, &argc, argv);
+  }
+
+  background = -1; // invisible
+  if ((N = get_argument (argc, argv, "-bg"))) {
+    remove_argument (N, &argc, argv);
+    if (!strcasecmp (argv[N], "NONE")) {
+      background = -1;
+    } else {
+      background = KapaColorByName(argv[N]);
+    }
+    remove_argument (N, &argc, argv);
+    action = BG;
   }
 
@@ -82,4 +94,8 @@
 	break;
 
+      case BG:
+	KapaSectionBG (kapa, argv[1], background);
+	break;
+
       case TOOL:
 	if (!strcmp(location, "-x")) {
@@ -121,4 +137,5 @@
     section.dx = atof (argv[4]);
     section.dy = atof (argv[5]);
+    section.bg = background;
     KapaSetSection (kapa, &section);
     return (TRUE);
Index: /branches/pap/Ohana/src/opihi/include/shell.h
===================================================================
--- /branches/pap/Ohana/src/opihi/include/shell.h	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/include/shell.h	(revision 28003)
@@ -15,4 +15,5 @@
 typedef enum {GP_FILE, GP_BUFF} gpMode;
 typedef enum {GP_LOG, GP_ERR} gpDest;
+typedef enum {OPIHI_VERBOSE_OFF, OPIHI_VERBOSE_ON, OPIHI_VERBOSE_ERROR} OpihiVerboseMode;
 
 typedef int CommandF (int argc, char **argv);
Index: anches/pap/Ohana/src/opihi/lib.data/open_graph.c
===================================================================
--- /branches/pap/Ohana/src/opihi/lib.data/open_graph.c	(revision 28002)
+++ 	(revision )
@@ -1,176 +1,0 @@
-# include "display.h"
-# include "shell.h"
-# define DEBUG 0
-
-/* we have space for several kapa windows */
-# define NXGRAPH 5
-
-static int       Active;
-static int       Xgraph[NXGRAPH];  
-static Graphdata graphdata[NXGRAPH];
-
-void QuitGraph () {
-
-  int i;
-  
-  for (i = 0; i < NXGRAPH; i++) {
-    KiiClose (Xgraph[i]);
-  }
-}
-
-void InitGraph () {
-
-  int i;
-
-  Active = 0;
-  for (i = 0; i < NXGRAPH; i++) {
-    Xgraph[i] = -1;
-
-    graphdata[i].xmin = graphdata[i].ymin = 0.0;
-    graphdata[i].xmax = graphdata[i].ymax = 1.0;
-    graphdata[i].style = graphdata[i].ptype = 0;
-    graphdata[i].ltype = graphdata[i].color = 0;
-    graphdata[i].etype = graphdata[i].ebar = 0;
-    graphdata[i].lweight = graphdata[i].size = 1.0;
-    
-    graphdata[i].coords.pc1_1 = graphdata[i].coords.pc2_2 = 1.0;
-    graphdata[i].coords.pc1_2 = graphdata[i].coords.pc2_1 = 0.0;
-    strcpy (graphdata[i].coords.ctype, "RA---LIN");
-    graphdata[i].coords.crval1 = 0.0;
-    graphdata[i].coords.crval2 = 0.0;
-    graphdata[i].coords.crpix1 = 0.0;
-    graphdata[i].coords.crpix2 = 0.0;
-    graphdata[i].coords.cdelt1 = graphdata[i].coords.cdelt2 = 1.0;
-    graphdata[i].flipeast = TRUE;
-    graphdata[i].flipnorth = FALSE;
-    strcpy (graphdata[i].axis, "2222");
-    strcpy (graphdata[i].ticks, "2222");
-    strcpy (graphdata[i].labels, "2222");
-  }
-}
-
-/* set SIGPIPE to this function to close cleanly */ 
-void XGraphDead (int input) {
-  signal (SIGPIPE, XGraphDead);
-  gprint (GP_ERR, "kapa is dead, must restart\n");
-  Xgraph[Active] = -1;
-}
-
-/** start socketed connection */
-int open_graph (int N) {
-
-  int fd;
-  char *kapa_exec, name[16];
-  
-  kapa_exec = get_variable ("KAPA");
-  if (kapa_exec == (char *) NULL) {
-    gprint (GP_ERR, "variable KAPA not found\n");
-    return (FALSE);
-  }
-
-  snprintf (name, 16, "[%d]", N);
-  fd = KiiOpen (kapa_exec, name);
-  free (kapa_exec);
-
-  if (fd < 0) {
-    gprint (GP_ERR, "error starting kapa\n");
-    return (FALSE);
-  } 
-
-  Xgraph[N] = fd;
-  return (TRUE);
-}
-
-int close_graph (int N) {
-
-  if (N <  0) return (FALSE);
-  if (N >= NXGRAPH) return (FALSE);
-
-  KiiClose (Xgraph[N]); 
-  Xgraph[N] = -1;
-  return (TRUE);
-}
-
-/* return pointers for current Xgraph, set if desired, test, open if needed */
-int GetGraph (Graphdata *data, int *socket, int *N) {
-
-  int i, n;
-  char buffer[70];
-
-  SetImageDevice (FALSE);
-  if (N == (int *) NULL) {
-    n = Active;
-  } else {
-    if (*N >= NXGRAPH) {
-      gprint (GP_ERR, "invalid Xgraph window %d\n", *N); 
-      return (FALSE);
-    }
-    if (*N < 0) {
-      *N = n = Active;
-    } else {
-      Active = n = *N;
-    }
-  }
-  
-  /* test Xgraph[0], flush junk from pipe */
-  signal (SIGPIPE, XGraphDead);
-  fcntl (Xgraph[n], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Xgraph[n], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Xgraph[n], F_SETFL, !O_NONBLOCK); 
-  
-  if (Xgraph[n] < 1) {
-    if (!open_graph(n)) {
-      return (FALSE);
-    }
-  }
-
-  if (data != (Graphdata *) NULL) *data  = graphdata[n];
-  if (socket != (int *) NULL) *socket = Xgraph[n];
-
-  return (TRUE);
-
-}
-
-/* return pointers for given Xgraph, don't set or open */
-int GetGraphData (Graphdata *data, int *sock, int *N) {
-
-  int n;
-
-  if (N == (int *) NULL) {
-    n = Active;
-  } else {
-    if (*N >= NXGRAPH) {
-      gprint (GP_ERR, "invalid Xgraph window %d\n", *N); 
-      return (FALSE);
-    }
-    if (*N < 0) {
-      n = Active;
-    } else {
-      n = *N;
-    }
-  }
-  
-  if (data != (Graphdata *) NULL) *data  = graphdata[n];
-  if (sock != (int *) NULL) *sock = Xgraph[n];
-
-  return (TRUE);
-
-}
-
-/* assign given values to current Xgraph */
-void SetGraph (Graphdata data) {
-  graphdata[Active] = data;
-}
-
-/** internal tracking of current active device type **/
-
-static int       IsImage = FALSE;
-
-int GetCurrentDevice () {
-  return (IsImage);
-}
-
-void SetImageDevice (int state) {
-  IsImage = state;
-}
-
Index: anches/pap/Ohana/src/opihi/lib.data/open_image.c
===================================================================
--- /branches/pap/Ohana/src/opihi/lib.data/open_image.c	(revision 28002)
+++ 	(revision )
@@ -1,133 +1,0 @@
-# include "display.h"
-# include "shell.h"
-# define DEBUG 0
-
-/* we have space for several kii windows */
-# define NXIMAGE 5
-
-static int       Active;
-static int       Ximage[NXIMAGE];  
-static char      Ximbuffer[NXIMAGE][512];
-static double    Xzero[NXIMAGE];
-static double    Xrange[NXIMAGE];
-
-void QuitImage () {
-
-  int i;
-  
-  for (i = 0; i < NXIMAGE; i++) {
-    KiiClose (Ximage[i]);
-  }
-}
-
-void InitImage () {
-
-  int i;
-
-  Active = 0;
-  for (i = 0; i < NXIMAGE; i++) {
-    Ximage[i] = -1;
-    Xzero[i] = 0;
-    Xrange[i] = 1024;
-    strcpy (Ximbuffer[i], "none");
-  }
-}
-
-/* set SIGPIPE to this function to close cleanly */ 
-void XImageDead (int input) {
-  signal (SIGPIPE, XImageDead);
-  gprint (GP_ERR, "kii is dead, must restart\n");
-  Ximage[Active] = -1;
-}
-
-/** start socketed connection */
-int open_image (int N) {
-
-  int fd;
-  char *kii_exec, name[16];
-
-  kii_exec = get_variable ("KII");
-  if (kii_exec == (char *) NULL) {
-    gprint (GP_ERR, "variable KII not found\n");
-    return (FALSE);
-  }
-
-  snprintf (name, 16, "[%d]", N);
-  fd = KiiOpen (kii_exec, name);
-  free (kii_exec);
-
-  if (fd < 0) {
-    gprint (GP_ERR, "error starting kii\n");
-    return (FALSE);
-  } 
-
-  Ximage[N] = fd;
-  return (TRUE);
-}
-
-int close_image (int N) {
-
-  if (N <  0) return (FALSE);
-  if (N >= NXIMAGE) return (FALSE);
-
-  KiiClose (Ximage[N]); 
-  Ximage[N] = -1;
-  return (TRUE);
-}
-
-/* return pointers for current Ximage, set if desired, test, open if needed */
-int GetImage (int *socket, int *N) {
-
-  int i, n;
-  char buffer[70];
-
-  SetImageDevice (TRUE);
-  if (N == (int *) NULL) {
-    n = Active;
-  } else {
-    if (*N >= NXIMAGE) {
-      gprint (GP_ERR, "invalid Ximage window %d\n", *N); 
-      return (FALSE);
-    }
-    if (*N < 0) {
-      *N = n = Active;
-    } else {
-      Active = n = *N;
-    }
-  }
-  
-  /* test Ximage[0], flush junk from pipe */
-  signal (SIGPIPE, XImageDead);
-  fcntl (Ximage[n], F_SETFL,  O_NONBLOCK); 
-  for (i = 0; (read (Ximage[n], buffer, 64) > 0) && (i < 20); i++);
-  fcntl (Ximage[n], F_SETFL, !O_NONBLOCK); 
-  
-  if (Ximage[n] < 1) {
-    if (!open_image(n)) {
-      return (FALSE);
-    }
-  }
-
-  if (socket != (int *) NULL) *socket = Ximage[n];
-
-  return (TRUE);
-
-}
-
-void SetImageName (char *name) {
-  strcpy (Ximbuffer[Active], name);
-}
-
-char *GetImageName () {
-  return (Ximbuffer[Active]);
-}
- 
-// leave this information on kapa, request when needed? 
-void SetImageScale (double zero, double range) {
-  Xzero[Active] = zero;
-  Xrange[Active] = range;
-}
-void GetImageScale (double *zero, double *range) {
-  *zero = Xzero[Active];
-  *range = Xrange[Active];
-}
Index: /branches/pap/Ohana/src/opihi/lib.shell/command.c
===================================================================
--- /branches/pap/Ohana/src/opihi/lib.shell/command.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/lib.shell/command.c	(revision 28003)
@@ -2,5 +2,5 @@
 # define DEBUG 0
 
-static int VERBOSE_SHELL = FALSE;
+static int VERBOSE_SHELL = OPIHI_VERBOSE_OFF;
 
 int command (char *line, char **outline, int VERBOSE) {
@@ -10,6 +10,6 @@
   Command *cmd;
 
-  rawline = NULL;
-  // rawline = strcreate (line);
+  // rawline = NULL;
+  rawline = strcreate (line);
 
   /* force a space between ! and first word: !ls becomes ! ls */
@@ -24,4 +24,9 @@
   /* expand anything of the form fred[N] */ 
   line = expand_vectors (line);  /* line is freed here, new one allocated */
+
+  // print the line with the variables and vectors expanded, but before evaluating 
+  // any in-line math expression
+  if (VERBOSE_SHELL == OPIHI_VERBOSE_ON) gprint (GP_ERR, "opihi: %s\n", line);
+
   /* solve math expresions, assign variable, if needed */
   line = parse (line);        /* line is freed here, new one allocated */
@@ -31,6 +36,4 @@
   *outline = line;
   
-  if (VERBOSE_SHELL) gprint (GP_ERR, "opihi: %s\n", line);
-
   argv = parse_commands (line, &argc);
   if (argc == 0) {
@@ -60,5 +63,5 @@
     msg = get_variable_ptr ("ERRORMSG");
     if (msg != (char *) NULL) gprint (GP_ERR, "%s\n", msg);
-    if (VERBOSE_SHELL) gprint (GP_ERR, "error on line: %s\n", rawline);
+    if (VERBOSE_SHELL != OPIHI_VERBOSE_OFF) gprint (GP_ERR, "error on line: %s\n", rawline);
   }
 
Index: /branches/pap/Ohana/src/opihi/lib.shell/startup.c
===================================================================
--- /branches/pap/Ohana/src/opihi/lib.shell/startup.c	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/lib.shell/startup.c	(revision 28003)
@@ -124,7 +124,12 @@
     if (LOAD_RC && !is_script) {
       rcfile = get_variable ("RCFILE");
-      sprintf (line, "input %s/%s", home, rcfile);
-      status = command (line, &outline, TRUE);
-      if (outline != (char *) NULL) free (outline);
+      if (rcfile && check_file_access (rcfile, FALSE, FALSE, FALSE)) {
+	sprintf (line, "input %s/%s", home, rcfile);
+	status = command (line, &outline, TRUE);
+	if (outline != (char *) NULL) free (outline);
+	if (status) {
+	  gprint (GP_LOG, "loaded file %s\n", rcfile); 
+	}	  
+      }
       if (rcfile) free (rcfile);
     }
Index: /branches/pap/Ohana/src/opihi/pantasks/Makefile
===================================================================
--- /branches/pap/Ohana/src/opihi/pantasks/Makefile	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/pantasks/Makefile	(revision 28003)
@@ -125,2 +125,6 @@
 
 .PHONY: pantasks pantasks_client pantasks_server
+
+.PRECIOUS: $(SRC)/pantasks.c
+.PRECIOUS: $(SRC)/pantasks_client.c 
+.PRECIOUS: $(SRC)/pantasks_server.c
Index: /branches/pap/Ohana/src/opihi/pantasks/pantasks.c.in
===================================================================
--- /branches/pap/Ohana/src/opihi/pantasks/pantasks.c.in	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/pantasks/pantasks.c.in	(revision 28003)
@@ -18,4 +18,5 @@
   InitBasic ();
   InitData ();
+  InitAstro ();
   InitPantasks ();
 
Index: /branches/pap/Ohana/src/opihi/pantasks/pantasks_server.c.in
===================================================================
--- /branches/pap/Ohana/src/opihi/pantasks/pantasks_server.c.in	(revision 28002)
+++ /branches/pap/Ohana/src/opihi/pantasks/pantasks_server.c.in	(revision 28003)
@@ -13,8 +13,10 @@
 */
 
+void special_init (int *argc, char **argv);
+
 /* program-dependent initialization */
 int main (int argc, char **argv) {
   
-  char log_stdout[128], log_stderr[128];
+  char log_stdout[1024], log_stderr[1024];
   pthread_t JobsAndTasksThread;
   pthread_t clientsThread;
@@ -23,11 +25,40 @@
   SockAddress Address;
 
-  general_init (&argc, argv);
+  strcpy (log_stdout, "stdout");
+  strcpy (log_stderr, "stderr");
 
-  // define server output log files
+  special_init (&argc, argv);
+
+  // 
+  stdin = freopen ("/dev/zero", "r", stdin);
+
+  // this block redirects the actual stderr, stdout steams to the output files
   if (VarConfig ("PANTASKS_SERVER_STDOUT", "%s", log_stdout) != NULL) {
+    if (strcmp (log_stdout, "stdout")) {
+      stdout = freopen (log_stdout, "a", stdout);
+      if (!stdout) {
+	fprintf (stderr, "failed to open %s for output\n", log_stdout);
+	exit (1);
+      }
+    }
+  }
+  if (VarConfig ("PANTASKS_SERVER_STDERR", "%s", log_stderr) != NULL) {
+    if (strcmp (log_stderr, "stderr")) {
+      stderr = freopen (log_stderr, "a", stderr);
+      if (!stderr) {
+	fprintf (stdout, "failed to open %s for error output\n", log_stderr);
+	exit (1);
+      }
+    }
+  }
+
+  /* init for main (or only) thread */
+  gprintInit ();
+
+  // this block changes the target of the gprint output streams
+  if (strcmp (log_stdout, "stdout")) {
       gprintSetFileThisThread (GP_LOG, log_stdout);
   }
-  if (VarConfig ("PANTASKS_SERVER_STDERR", "%s", log_stderr) != NULL) {
+  if (strcmp (log_stderr, "stderr")) {
       gprintSetFileThisThread (GP_ERR, log_stderr);
   }
@@ -41,4 +72,5 @@
   InitBasic ();
   InitData ();
+  InitAstro ();
   InitPantasksServer ();
 
@@ -105,2 +137,24 @@
 void welcome () { }
 void program_init (int *argc, char **argv) {}
+
+// I need to do things in a different order here to have config / freopen / gprint sequenced correctly
+void special_init (int *argc, char **argv) {
+
+  /* init srand for rnd numbers elsewhere */
+  long A, B;
+  A = time(NULL);
+  for (B = 0; A == time(NULL); B++);
+  srand48(B);
+ 
+  /* set signals */
+  signal (SIGINT, SIG_IGN);
+
+  init_error ();
+
+  /* load config data (.ptolemyrc) */
+  if (!ConfigInit (argc, argv)) {
+    fprintf (stderr, "can't find (.ptolemyrc,ptolemy.rc) config file. some functions will be unavailable\n");
+  }
+
+  return;
+}
Index: /branches/pap/Ohana/src/relphot/src/StarOps.c
===================================================================
--- /branches/pap/Ohana/src/relphot/src/StarOps.c	(revision 28002)
+++ /branches/pap/Ohana/src/relphot/src/StarOps.c	(revision 28003)
@@ -225,4 +225,5 @@
 	  }
 
+	  // XXX make it optional to apply Mcal (do I need an extra field for advisory Mcal?)
 	  list[N] = Msys - catalog[i].measure[m].Mcal;
 	  dlist[N] = MAX (catalog[i].measure[m].dM, MIN_ERROR);
Index: /branches/pap/Ohana/src/uniphot/Makefile
===================================================================
--- /branches/pap/Ohana/src/uniphot/Makefile	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/Makefile	(revision 28003)
@@ -1,5 +1,5 @@
-default: uniphot
+default: uniphot setphot
 help:
-	@echo "make options: uniphot (default)"
+@echo "make options: uniphot setphot default help install default (uniphot setphot)"
 
 include ../../Makefile.System
@@ -18,5 +18,6 @@
 
 uniphot: $(BIN)/uniphot.$(ARCH)
-install: $(DESTBIN)/uniphot
+setphot: $(BIN)/setphot.$(ARCH)
+install: $(DESTBIN)/uniphot $(DESTBIN)/setphot 
 
 UNIPHOT = \
@@ -24,5 +25,5 @@
 $(SRC)/initialize.$(ARCH).o	    \
 $(SRC)/ConfigInit.$(ARCH).o	    \
-$(SRC)/args.$(ARCH).o		    \
+$(SRC)/args.$(ARCH).o               \
 $(SRC)/liststats.$(ARCH).o	    \
 $(SRC)/load_images.$(ARCH).o	    \
@@ -39,2 +40,18 @@
 $(UNIPHOT): $(INC)/uniphot.h
 $(BIN)/uniphot.$(ARCH): $(UNIPHOT)
+
+SETPHOT = \
+$(SRC)/setphot.$(ARCH).o	    \
+$(SRC)/initialize.$(ARCH).o	    \
+$(SRC)/ConfigInit.$(ARCH).o	    \
+$(SRC)/args.$(ARCH).o               \
+$(SRC)/liststats.$(ARCH).o	    \
+$(SRC)/load_zpt_table.$(ARCH).o	    \
+$(SRC)/load_images.$(ARCH).o	    \
+$(SRC)/match_zpts_to_images.$(ARCH).o	    \
+$(SRC)/update_catalog_setphot.$(ARCH).o \
+$(SRC)/SetSignals.$(ARCH).o	    \
+$(SRC)/Shutdown.$(ARCH).o	    
+
+$(SETPHOT): $(INC)/uniphot.h
+$(BIN)/setphot.$(ARCH): $(SETPHOT)
Index: /branches/pap/Ohana/src/uniphot/include/uniphot.h
===================================================================
--- /branches/pap/Ohana/src/uniphot/include/uniphot.h	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/include/uniphot.h	(revision 28003)
@@ -39,4 +39,10 @@
 } Group;
 
+typedef struct {
+    float zpt;
+    e_time time;
+    int found;
+} ZptTable;
+
 /* global variables set in parameter file */
 char         ImageCat[256];
@@ -44,4 +50,7 @@
 char         CATMODE[16];    /* raw, mef, split, mysql */
 char         CATFORMAT[16];  /* internal, elixir, loneos, panstarrs */
+char         SKY_TABLE[256];
+int          SKY_DEPTH;  /** XXX EAM : depth of catalog tables, fix usage */
+char         GSCFILE[256];
 char         STATMODE[64];
 int          VERBOSE;
@@ -66,41 +75,50 @@
 
 /***** prototypes ****/
-void          ConfigInit         PROTO((int *argc, char **argv));
-void          DonePlotting       PROTO((Graphdata *graphmode, int N));
-void          JpegPlot           PROTO((Graphdata *graphmode, int N, char *filename));
-void          PSPlot             PROTO((Graphdata *graphmode, int N, char *filename));
-void          PlotLabel          PROTO((char *string, int N));
-void          PlotVector         PROTO((int Npts, double *vect, int mode, int N));
-void          PrepPlotting       PROTO((int Npts, Graphdata *graphmode, int N));
-void          XDead              PROTO((void));
-int           args               PROTO((int argc, char **argv));
-void          dumpresult         PROTO((void));
-Group        *find_image_sgroups PROTO((FITS_DB *db, ImageLink **imlink, int *Nsgroup));
-Group        *find_image_tgroups PROTO((FITS_DB *db, ImageLink **imlink, int *Ntgroup));
-void          fit_sgroup         PROTO((Group *sgroup, int Nsgroup));
-void          fit_tgroup         PROTO((Group *tgroup, int Ntgroup));
-int           gcatalog           PROTO((Catalog *catalog));
-void          initialize         PROTO((int argc, char **argv));
-void          initstats          PROTO((char *mode));
-int           liststats          PROTO((double *value, double *dvalue, int N, StatType *stats));
-int           load_images        PROTO((FITS_DB *db));
-int           main               PROTO((int argc, char **argv));
-int           open_graph         PROTO((int N));
-void          sort               PROTO((unsigned int *X, int N));
-void          sortB              PROTO((double *X, double *Y, int N));
-void          sortD              PROTO((double *X, double *Y, double *Z, int N));
-void          update_dvo_catalog PROTO((Catalog *catalog, Group *sgroup, int warn));
-void          wcatalog           PROTO((Catalog *catalog));
-void          wimages            PROTO((Image *image, int Nimage));
-void 	      check_permissions  PROTO((char *basefile));
-void 	      lock_image_db 	 PROTO((FITS_DB *db, char *filename));
-void	      unlock_image_db 	 PROTO((FITS_DB *db));
-void	      create_image_db 	 PROTO((FITS_DB *db));
-void	      set_db 		 PROTO((FITS_DB *in));
-int 	      Shutdown 		 PROTO((char *format, ...) OHANA_FORMAT(printf, 1, 2) );
-void 	      TrapSignal 	 PROTO((int sig));
-void 	      SetProtect 	 PROTO((int mode));
-int 	      SetSignals 	 PROTO((void));
-int 	      subset_images 	 PROTO((FITS_DB *db));
-void 	      update 		 PROTO((FITS_DB *db, Group *sgroup, int Nsgroup));
-void 	      sort_time 	 PROTO((unsigned int *value, int N));
+void          ConfigInit          PROTO((int *argc, char **argv));
+void          DonePlotting        PROTO((Graphdata *graphmode, int N));
+void          JpegPlot            PROTO((Graphdata *graphmode, int N, char *filename));
+void          PSPlot              PROTO((Graphdata *graphmode, int N, char *filename));
+void          PlotLabel           PROTO((char *string, int N));
+void          PlotVector          PROTO((int Npts, double *vect, int mode, int N));
+void          PrepPlotting        PROTO((int Npts, Graphdata *graphmode, int N));
+void          XDead               PROTO((void));
+int           args_uniphot        PROTO((int argc, char **argv));
+int           args_setphot        PROTO((int argc, char **argv));
+void          dumpresult          PROTO((void));
+Group        *find_image_sgroups  PROTO((FITS_DB *db, ImageLink **imlink, int *Nsgroup));
+Group        *find_image_tgroups  PROTO((FITS_DB *db, ImageLink **imlink, int *Ntgroup));
+void          fit_sgroup          PROTO((Group *sgroup, int Nsgroup));
+void          fit_tgroup          PROTO((Group *tgroup, int Ntgroup));
+int           gcatalog            PROTO((Catalog *catalog));
+void          initialize_uniphot  PROTO((int argc, char **argv));
+void          initialize_setphot  PROTO((int argc, char **argv));
+void          initstats           PROTO((char *mode));
+int           liststats           PROTO((double *value, double *dvalue, int N, StatType *stats));
+int           load_images_uniphot PROTO((FITS_DB *db));
+int           main                PROTO((int argc, char **argv));
+int           open_graph          PROTO((int N));
+void          sort                PROTO((unsigned int *X, int N));
+void          sortB               PROTO((double *X, double *Y, int N));
+void          sortD               PROTO((double *X, double *Y, double *Z, int N));
+void          update_dvo_catalog  PROTO((Catalog *catalog, Group *sgroup, int warn));
+void          wcatalog            PROTO((Catalog *catalog));
+void          wimages             PROTO((Image *image, int Nimage));
+void 	      check_permissions   PROTO((char *basefile));
+void 	      lock_image_db 	  PROTO((FITS_DB *db, char *filename));
+void	      unlock_image_db 	  PROTO((FITS_DB *db));
+void	      create_image_db 	  PROTO((FITS_DB *db));
+void	      set_db 		  PROTO((FITS_DB *in));
+int 	      Shutdown 		  PROTO((char *format, ...) OHANA_FORMAT(printf, 1, 2) );
+void 	      TrapSignal 	  PROTO((int sig));
+void 	      SetProtect 	  PROTO((int mode));
+int 	      SetSignals 	  PROTO((void));
+int 	      subset_images 	  PROTO((FITS_DB *db));
+void 	      update 		  PROTO((FITS_DB *db, Group *sgroup, int Nsgroup));
+void 	      sort_time 	  PROTO((unsigned int *value, int N));
+
+// setphot-specific prototypes
+ZptTable     *load_zpt_table         PROTO((char *filename, int *nzpts));
+Image        *load_images_setphot    PROTO((FITS_DB *db, off_t *Nimage));
+int           match_zpts_to_images   PROTO((Image *image, off_t Nimage, ZptTable *zpts, int Nzpts));
+int           update_setphot         PROTO((Image *image, off_t Nimage));
+void          update_catalog_setphot PROTO((Catalog *catalog, Image *image, off_t *index, off_t Nimage));
Index: /branches/pap/Ohana/src/uniphot/src/ConfigInit.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/ConfigInit.c	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/src/ConfigInit.c	(revision 28003)
@@ -1,3 +1,5 @@
 # include "uniphot.h"
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr);
 
 void ConfigInit (int *argc, char **argv) {
@@ -18,5 +20,5 @@
   if (VERBOSE) fprintf (stderr, "loaded config file: %s\n", file);
 
-  ScanConfig (config, "CATDIR",                 "%s",  0, CATDIR);
+  GetConfig (config, "CATDIR",                 "%s",  0, CATDIR);
   ScanConfig (config, "CATMODE",                "%s",  0, CATMODE);
   ScanConfig (config, "CATFORMAT",              "%s",  0, CATFORMAT);
@@ -24,4 +26,12 @@
 
   sprintf (ImageCat, "%s/Images.dat", CATDIR);
+
+  GetConfig (config, "GSCFILE",                 "%s",  0, GSCFILE);
+  if (!ScanConfig (config, "SKY_DEPTH",         "%d",  0, &SKY_DEPTH)) {
+    SKY_DEPTH = 2;
+  }
+  if (!ScanConfig (config, "SKY_TABLE",         "%s",  0, SKY_TABLE)) {
+    SKY_TABLE[0] = 0;
+  }
 
   ScanConfig (config, "ZERO_PT",                "%lf", 0, &ZERO_POINT);
@@ -42,2 +52,14 @@
 
 }
+
+void GetConfig (char *config, char *field, char *format, int N, void *ptr) {
+
+  char *status;
+
+  status = ScanConfig (config, field, format, N, ptr);
+  if (status == NULL) {
+    fprintf (stderr, "error in config, cannot find %s\n", field);
+    exit (1);
+  }
+  return;
+}
Index: /branches/pap/Ohana/src/uniphot/src/Shutdown.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/Shutdown.c	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/src/Shutdown.c	(revision 28003)
@@ -23,5 +23,5 @@
   SetProtect (TRUE);
   gfits_db_close (db);
-  fprintf (stderr, "ERROR: addstar halted\n");
+  fprintf (stderr, "ERROR: halted\n");
   exit (1);
 }
Index: /branches/pap/Ohana/src/uniphot/src/args.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/args.c	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/src/args.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "uniphot.h"
 
-int args (int argc, char **argv) {
+int args_uniphot (int argc, char **argv) {
 
   int N;
@@ -72,2 +72,26 @@
 }
 
+int args_setphot (int argc, char **argv) {
+
+  int N;
+
+  VERBOSE = FALSE;
+  if ((N = get_argument (argc, argv, "-v"))) {
+    VERBOSE = TRUE;
+    remove_argument (N, &argc, argv);
+  }
+
+  UPDATE = FALSE;
+  if ((N = get_argument (argc, argv, "-update"))) {
+    remove_argument (N, &argc, argv);
+    UPDATE = TRUE;
+  }
+
+  if (argc != 2) {
+    fprintf (stderr, "ERROR: USAGE: setphot (zptfile) [options]\n");
+    exit (2);
+  } 
+
+  return (TRUE);
+}
+
Index: /branches/pap/Ohana/src/uniphot/src/initialize.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/initialize.c	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/src/initialize.c	(revision 28003)
@@ -1,9 +1,9 @@
 # include "uniphot.h"
 
-void initialize (int argc, char **argv) {
+void initialize_uniphot (int argc, char **argv) {
 
   /* are these set correctly? */
   ConfigInit (&argc, argv);
-  args (argc, argv);
+  args_uniphot (argc, argv);
 
   if ((photcode = GetPhotcodebyName (argv[1])) == NULL) {
@@ -21,2 +21,9 @@
 }
 
+void initialize_setphot (int argc, char **argv) {
+
+  /* are these set correctly? */
+  ConfigInit (&argc, argv);
+  args_setphot (argc, argv);
+}
+
Index: /branches/pap/Ohana/src/uniphot/src/load_images.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/load_images.c	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/src/load_images.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "uniphot.h"
 
-int load_images (FITS_DB *db) {
+int load_images_uniphot (FITS_DB *db) {
 
   if (VERBOSE) fprintf (stderr, "finding images\n");
@@ -10,2 +10,19 @@
   return (TRUE);
 }
+
+Image *load_images_setphot (FITS_DB *db, off_t *Nimage) {
+
+  Image *image;
+
+  if (VERBOSE) fprintf (stderr, "finding images\n");
+
+  /* read entire db table */
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
+
+  /* use a vtable to keep the images to be calibrated */
+  image = gfits_table_get_Image (&db[0].ftable, Nimage, &db[0].swapped);
+
+  fprintf (stderr, "loaded %lld images\n", (long long) *Nimage);
+
+  return (image);
+}
Index: /branches/pap/Ohana/src/uniphot/src/load_zpt_table.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/load_zpt_table.c	(revision 28003)
+++ /branches/pap/Ohana/src/uniphot/src/load_zpt_table.c	(revision 28003)
@@ -0,0 +1,41 @@
+# include "uniphot.h"
+
+ZptTable *load_zpt_table (char *filename, int *nzpts) {
+
+  int Nzpts, NZPTS;
+  ZptTable *zpts;
+  double zpt, mjd;
+
+  FILE *f;
+
+  f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "ERROR: cannot open zpt table file %s\n", filename);
+    exit (1);
+  }
+
+  Nzpts = 0;
+  NZPTS = 100;
+  ALLOCATE (zpts, ZptTable, NZPTS);
+
+  // format is fixed: (time) (zpt)
+  int status;
+  while ((status = fscanf (f, "%lf %lf", &mjd, &zpt)) == 2) {
+    zpts[Nzpts].zpt = zpt;
+    zpts[Nzpts].time = ohana_mjd_to_sec (mjd);
+    zpts[Nzpts].found = FALSE;
+
+    Nzpts ++;
+    CHECK_REALLOCATE (zpts, ZptTable, NZPTS, Nzpts, 100);
+  }
+
+  if (status != EOF) {
+    fprintf (stderr, "unexpected formatting on line %d\n", Nzpts);
+    exit (2);
+  }
+
+  fprintf (stderr, "loaded %d zero points\n", Nzpts);
+
+  *nzpts = Nzpts;
+  return zpts;
+}
Index: /branches/pap/Ohana/src/uniphot/src/match_zpts_to_images.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 28003)
+++ /branches/pap/Ohana/src/uniphot/src/match_zpts_to_images.c	(revision 28003)
@@ -0,0 +1,90 @@
+# include "uniphot.h"
+
+/* sort a coordinate pair (X,Y) and the associated index (S) */
+static void sort_zpts_by_time (ZptTable *zpts, int Nzpts) {
+  
+# define SWAPFUNC(A,B){ ZptTable tmp;		\
+    tmp = zpts[A]; zpts[A] = zpts[B]; zpts[B] = tmp;	\
+  }
+# define COMPARE(A,B)(zpts[A].time < zpts[B].time)
+
+  OHANA_SORT (Nzpts, COMPARE, SWAPFUNC);
+
+# undef SWAPFUNC
+# undef COMPARE
+}
+
+# define SCALE 0.001
+
+int match_zpts_to_images (Image *image, off_t Nimage, ZptTable *zpts, int Nzpts) {
+
+  // I have two lists.  I need to match images->tzero to zpts->time.  multiple images may match a single zpt
+  
+  // sort both lists by time (or at least get sorted indices)
+  // sweep through both lists, advancing the one that is lagging
+  // apply the matches
+
+  int dT, NImatch, Nmatch;
+  off_t i, Ni, Nz, *index;
+  PhotCode *code;
+
+  // create index and sort
+  ALLOCATE (index, off_t, Nimage);
+  for (i = 0; i < Nimage; i++) {
+    index[i] = i;
+  }
+  sort_image_subset(image, index, Nimage);  // slightly misnamed sort function from libdvo
+
+  // sort the zpts
+  sort_zpts_by_time (zpts, Nzpts);
+
+  NImatch = 0; // matched images
+  for (i = Nz = 0; (i < Nimage) && (Nz < Nzpts); ) {
+
+    if (i % 1000 == 0) fprintf (stderr, ".");
+    if (Nz % 100 == 0) fprintf (stderr, "!");
+
+    Ni = index[i];
+    dT = image[Ni].tzero - zpts[Nz].time;
+
+    // negative dT, i is too small (allow a 1sec overlap window)
+    if (dT < -1) {
+      i++;
+      continue;
+    }
+
+    // XXX careful about definition of image->tzero and zpt->time
+    // negative dT, i is too small (allow a 1sec overlap window)
+    if (dT > +1) {
+      Nz++;
+      continue;
+    }
+
+    // check that we have a valid photcode (skip mosaic images)
+    code = GetPhotcodebyCode(image[Ni].photcode);
+    if (!code) { 
+      i++;
+      continue;
+    }
+
+    // we have a match: set zpt and record the match
+    image[Ni].Mcal = SCALE*code[0].C - zpts[Nz].zpt;
+    image[Ni].flags &= ~ID_IMAGE_NOCAL; // clear the NOCAL flag
+    zpts[Nz].found = TRUE;
+    NImatch ++;
+
+    // advance the image counter only -- a single zpt may match more than one image
+    i++;
+  }
+
+  // how many zpts have we matched?
+  Nmatch = 0;
+  for (Nz = 0; Nz < Nzpts; Nz++) {
+    if (zpts[Nz].found) Nmatch ++;
+  }
+
+  fprintf (stderr, "found %d zpt matches, %d image matches\n", Nmatch, NImatch);
+
+  return (TRUE);
+}
+
Index: /branches/pap/Ohana/src/uniphot/src/setphot.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/setphot.c	(revision 28003)
+++ /branches/pap/Ohana/src/uniphot/src/setphot.c	(revision 28003)
@@ -0,0 +1,49 @@
+# include "uniphot.h"
+
+int main (int argc, char **argv) {
+
+  off_t Nimage;
+  int status, Nzpts;
+  FITS_DB db;
+  ZptTable *zpts;
+  Image *image;
+
+  /* get configuration info, args, lockfile */
+  initialize_setphot (argc, argv);
+
+  set_db (&db);
+  status = dvo_image_lock (&db, ImageCat, 60.0, (UPDATE ? LCK_XCLD : LCK_SOFT));
+  if (!status) Shutdown ("ERROR: failure to lock image catalog %s", db.filename);
+  if (db.dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db.filename);
+
+  zpts = load_zpt_table (argv[1], &Nzpts);
+
+  // load images 
+  image  = load_images_setphot (&db, &Nimage);
+  if (!UPDATE) dvo_image_unlock (&db); 
+  
+  match_zpts_to_images (image, Nimage, zpts, Nzpts);
+
+  update_setphot(image, Nimage);
+
+  // write image table
+  if (UPDATE) {
+    dvo_image_save (&db, VERBOSE);
+  }
+
+  exit (0);
+}
+  
+
+/* setphot : set the zero points for images in the db (perhaps based on external information)
+   setphot (zpt_table)
+
+ * load text table of zpts, time (photcode?)
+ * load images
+ * match images to zpts
+ * set zpts
+ * load catalogs
+ * update detection (& averages?)
+
+ */
+
Index: /branches/pap/Ohana/src/uniphot/src/uniphot.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/uniphot.c	(revision 28002)
+++ /branches/pap/Ohana/src/uniphot/src/uniphot.c	(revision 28003)
@@ -9,5 +9,5 @@
 
   /* get configuration info, args, lockfile */
-  initialize (argc, argv);
+  initialize_uniphot (argc, argv);
 
   set_db (&db);
@@ -18,5 +18,5 @@
 
   /* load images */
-  load_images (&db);
+  load_images_uniphot (&db);
   
   /* filter image list by selection */
Index: /branches/pap/Ohana/src/uniphot/src/update_catalog_setphot.c
===================================================================
--- /branches/pap/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 28003)
+++ /branches/pap/Ohana/src/uniphot/src/update_catalog_setphot.c	(revision 28003)
@@ -0,0 +1,97 @@
+# include "uniphot.h"
+# include <glob.h>
+
+int update_setphot (Image *image, off_t Nimage) {
+
+  SkyRegion UserPatch;
+  SkyTable *sky = NULL;
+  SkyList *skylist = NULL;
+  Catalog catalog;
+  off_t i, maxID, *index;
+
+  // create an index for the image IDs
+  maxID = 0;
+  for (i = 0; i < Nimage; i++) {
+    maxID = MAX(maxID, image[i].imageID);
+  }
+  ALLOCATE (index, off_t, maxID + 1);
+  for (i = 0; i < Nimage; i++) {
+    if (!image[i].imageID) continue; // images with ID == 0 are virtual
+    index[image[i].imageID] = i;
+  }
+  
+
+  // load the current sky table (layout of all SkyRegions) 
+  sky = SkyTableLoadOptimal (CATDIR, SKY_TABLE, GSCFILE, TRUE, SKY_DEPTH, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  
+  // determine the populated SkyRegions overlapping the requested area (default depth)
+  UserPatch.Rmin = 0;
+  UserPatch.Rmax = 360;
+  UserPatch.Dmin = -90;
+  UserPatch.Dmax = +90;
+  skylist = SkyListByPatch (sky, -1, &UserPatch);
+
+  // update measurements for each populated catalog
+  for (i = 0; i < skylist[0].Nregions; i++) {
+
+    // set up the basic catalog info
+    catalog.filename  = skylist[0].filename[i];
+    catalog.catformat = dvo_catalog_catformat (CATFORMAT);    // set the default catformat from config data
+    catalog.catmode   = dvo_catalog_catmode (CATMODE);        // set the default catmode from config data
+    catalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+    catalog.Nsecfilt  = GetPhotcodeNsecfilt ();
+
+    if (!dvo_catalog_open (&catalog, skylist[0].regions[i], VERBOSE, "w")) {
+      fprintf (stderr, "ERROR: failure reading catalog %s\n", catalog.filename);
+      exit (1);
+    }
+    if (!catalog.Naves_disk) {
+      if (VERBOSE) fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+
+    update_catalog_setphot (&catalog, image, index, Nimage);
+
+    if (!UPDATE) {
+      dvo_catalog_unlock (&catalog);
+      dvo_catalog_free (&catalog);
+      continue;
+    }
+    
+    if (VERBOSE) fprintf (stderr, "saving catalog %s\n", catalog.filename);
+    
+    dvo_catalog_save (&catalog, VERBOSE); 
+    dvo_catalog_unlock (&catalog);
+    dvo_catalog_free (&catalog);
+  }
+  return (TRUE);
+}      
+
+void update_catalog_setphot (Catalog *catalog, Image *image, off_t *index, off_t Nimage) {
+
+  off_t i, j, m, id, idx, found;
+  float Mcal;
+
+  found = 0;    
+  for (i = 0; i < catalog[0].Naverage; i++) {
+
+    m = catalog[0].average[i].measureOffset;
+    for (j = 0; j < catalog[0].average[i].Nmeasure; j++, m++) {
+      idx = catalog[0].measure[m].imageID;
+      if (idx <= 0) continue; // detections with imageID == 0 do not have a valid image (eg, ref photcode)
+
+      id = index[idx];
+      Mcal = image[id].Mcal;
+
+      catalog[0].measure[m].Mcal = image[id].Mcal;
+      found ++;
+    }
+  }
+
+  if (found) {
+    fprintf (stderr, "found %lld matches\n", (long long) found);
+  }
+}
Index: /branches/pap/PS-IPP-Metadata-Config/lib/PS/IPP/Metadata/Config.pm
===================================================================
--- /branches/pap/PS-IPP-Metadata-Config/lib/PS/IPP/Metadata/Config.pm	(revision 28002)
+++ /branches/pap/PS-IPP-Metadata-Config/lib/PS/IPP/Metadata/Config.pm	(revision 28003)
@@ -59,4 +59,36 @@
 }
 
+# Parse a list of METADATAs
+sub parse_list
+{
+    my $self = shift;           # This parser
+
+    # Split input into separate METADATAs because the parser seems to take forever handling those together
+    my @whole = split /\n/, join( '', @_ ); # The whole input
+    my @single;                             # A single METADATA element
+    my @output;                             # Output
+    foreach my $value (@whole) {
+        push @single, $value;
+        if ($value =~ /^\s*END\s*$/) {
+            push @single, "\n";
+
+            my $md = join("\n", @single); # Metadata to parse
+            my $parsed = $self->parse($md) or (carp "Unable to parse input: $md\n" and next);
+            (carp "More than one entry in input: $md\n" and next) if scalar @$parsed > 1;
+            my $metadata = shift @$parsed; # Metadata of interest
+            (carp "MD element is not of type METADATA: $md\n" and next) if $metadata->{class} ne "metadata";
+            my $components = $metadata->{value}; # Components of metadata
+            my %hash;           # Hash for entry
+            foreach my $comp (@$components) {
+                $hash{$comp->{name}} = $comp->{value};
+            }
+            push @output, \%hash;
+            @single = ();
+        }
+    }
+
+    return \@output;
+}
+
 sub _merge_duplicates {
     my ( $self, $tree ) = @_;
@@ -73,5 +105,5 @@
         # stop if the prevous pass removed the last element and called redo
         last unless defined $elem;
-                
+
         # recurse through nested metadata
         if ( $elem->{class} eq "metadata" ) {
@@ -83,5 +115,5 @@
             delete $elem->{multi};
             next;
-        } 
+        }
 
         if ( defined $names{ $elem->{name} } ) {
Index: /branches/pap/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm
===================================================================
--- /branches/pap/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm	(revision 28002)
+++ /branches/pap/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm	(revision 28003)
@@ -17,4 +17,5 @@
                     resolve_project
                     getCamRunByCamID
+                    parse_md_fast
                     );
 our %EXPORT_TAGS = (standard => [@EXPORT_OK]);
@@ -27,4 +28,11 @@
 use PS::IPP::Config qw( :standard );
 use Carp;
+use File::Temp qw(tempfile);
+use File::Basename;
+use POSIX;
+use Time::HiRes qw(gettimeofday);
+
+my $dvo_verbose = 0;
+my $save_temps = 0;
 
 # caches of camProcessedExp objects. 
@@ -34,10 +42,14 @@
 my %camRunByCamIDCache;
 
-### my @images = locate_images($image_db, $req_type, $img_type, $id, $component,
-###            $mjd_min, $mjd_max, $filter);
+# cache of last project looked up
+my $last_project = "";
+
+my ($regtool, $chiptool, $camtool, $warptool, $stacktool, $difftool);
+my ($pstamptool, $dvoImagesAtCoords, $whichimage, $ppConfigDump);
 
 sub locate_images {
     my $ipprc    = shift;   # required
-    my $image_db = shift;   # required
+    my $imagedb = shift;   # required
+    my $rowList  = shift;   # required
     my $req_type = shift;   # required
     my $img_type = shift;   # required
@@ -47,6 +59,4 @@
     my $option_mask  = shift;
     my $need_magic = shift;
-    my $x        = shift;
-    my $y        = shift;
     my $mjd_min  = shift;
     my $mjd_max  = shift;
@@ -56,6 +66,7 @@
 
     # we die in response to bad data in request files
-    # The wrapper script is responsible for updating the database
-    die "Unknown req_type: $req_type" 
+    # The caller is responsible for updating the database
+    # pstampparse.pl error checks now so this shouldn't happen
+    &my_die("Unknown req_type: $req_type", $PS_EXIT_PROG_ERROR) 
         if ($req_type ne "byid") and
            ($req_type ne "byexp") and 
@@ -84,5 +95,10 @@
 
     if ($req_type eq "bycoord") {
-        my $results = lookup_bycoord($ipprc, $image_db, $img_type, $tess_id, $component, $need_magic, $x, $y, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose);
+        my $num_rows = scalar @$rowList;
+        die "Unexpected number of rows found in rowList: $num_rows" if $num_rows != 1;
+        my $row = $rowList->[0];
+        my $x = $row->{CENTER_X};
+        my $y = $row->{CENTER_Y};
+        my $results = lookup_bycoord($ipprc, $rowList, $imagedb, $img_type, $tess_id, $component, $need_magic, $x, $y, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose);
         return $results;
     }
@@ -93,10 +109,12 @@
         # in one place
         $req_type = "bydiff";
-        my $results = lookup_diff($ipprc, $image_db, $id, $component, 1, $option_mask, $img_type, $verbose);
+        my $results = lookup_diff($ipprc, $rowList, $imagedb, $id, $component, 1, $option_mask, $img_type, $verbose);
         return $results;
     }
 
     if ($req_type eq "bydiff") {
-        my $results = lookup_diff($ipprc, $image_db, $id, $component, 0, $option_mask, $img_type, $verbose);
+        # for bydiff reuqests we go look up the diffRun to obtain exp_id, chip_id, warp_id, stack_id, or 
+        # the image from the diffRun
+        my $results = lookup_diff($ipprc, $rowList, $imagedb, $id, $component, 0, $option_mask, $img_type, $verbose);
         if (!$results) {
             return undef;
@@ -130,5 +148,5 @@
             # fall though and lookup by stack_id
         } else {
-            # shouldn't I check this elsewhere?
+            # This is checked this elsewhere?
             print STDERR "Error: $img_type is an unknown image type\n";
             return undef;
@@ -145,16 +163,19 @@
     }
 
-    my $results = lookup($ipprc, $image_db, $req_type, $img_type, $id, $tess_id, $component, $need_magic,
-        $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose);
+    my $results = lookup($ipprc, $rowList, $imagedb, $req_type, $img_type, $id, $tess_id, $component,
+        $need_magic, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose);
 
     return $results;
 }
 
-sub lookup
-{
+# The subroutine lookup handles byexp, byid, and byskycell lookups including lookups that are
+# triggered by a bydiff or bycoord request
+
+sub lookup {
     my $ipprc    = shift;
-    my $image_db = shift;
+    my $rowList    = shift;
+    my $imagedb = shift;
     my $req_type = shift;
-    my $img_type = shift;
+    my $stage = shift;
     my $id       = shift;
     my $tess_id  = shift;
@@ -172,14 +193,4 @@
     my $use_imfile_id = ($req_type eq "byid") && ($option_mask & $PSTAMP_USE_IMFILE_ID);
 
-    my $missing_tools;
-    my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
-    my $chiptool = can_run('chiptool') or (warn "Can't find chiptool" and $missing_tools = 1);
-    my $warptool = can_run('warptool') or (warn "Can't find warptool" and $missing_tools = 1);
-    my $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1);
-    my $stacktool = can_run('stacktool') or (warn "Can't find stacktool" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
     my $command;
     my $id_opt;     # option for the lookup
@@ -195,30 +206,49 @@
     my $class_id;
     my $skycell_id;
-
-    if (isnull($component)) {
-        $component = undef;
-    }
+    my $default_error = $PSTAMP_NO_IMAGE_MATCH;
 
     # note $magic_arg may be cleared below depending on $req_type
     my $magic_arg = $need_magic ? " -destreaked" : "";
 
+    # all rows have the same center type
+    my $skycenter = ! ($rowList->[0]->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
+
     my $component_args;
-    if ($img_type eq "raw") {
-        $class_id = $component;
-        $command = "$regtool -processedimfile -dbname $image_db";
+    my $choose_components = 0;
+    if ($stage eq "raw") {
+        $command = "$regtool -processedimfile -dbname $imagedb";
         # XXX: for now restrict lookups to type object 
         # are stamps of detrend exposures interesting?
         $command .= " -exp_type object";
         $id_opt = $use_imfile_id ? "-raw_imfile_id" : "-exp_id";
-        $component_args = " -class_id $class_id" if $component;
+
+        if ($component and $component ne 'all') {
+            $class_id = $component;
+            $component_args = " -class_id $class_id";
+        }
         $want_astrom = 1;
         $set_class_id = 1;
-    } elsif ($img_type eq "chip") {
-        $class_id = $component;
-        $command = "$chiptool -processedimfile -dbname $image_db";
-        $component_args = " -class_id $class_id" if $class_id;
+    } elsif ($stage eq "chip") {
+        # if the request is such that it will yield a single image per "run" or the
+        # center is specified in pixel coordinates 
+        # use chiptool -processsedimfile. Otherwise use chiptool -listrun and then
+        # choose the chips containing the center pixel by calling selectComponets() below
+        if ($component or $use_imfile_id or !$skycenter) {
+            $command = "$chiptool -processedimfile -dbname $imagedb";
+            if ($component and $component ne 'all') {
+                $class_id = $component;
+                $component_args = " -class_id $class_id";
+            }
+        } else {
+            $command = "$chiptool -listrun -pstamp_order -dbname $imagedb";
+            $choose_components = 1;
+        }
         $id_opt = $use_imfile_id ? "-chip_imfile_id" : "-chip_id";
+        # XXX: perhaps we should stop resolving images to this level here and do it at job run time.
+        # With the mdc file it has all of the information that it needs.
         $image_name   = "PPIMAGE.CHIP";
-        $mask_name    = "PPIMAGE.CHIP.MASK";
+        # $mask_name    = "PPIMAGE.CHIP.MASK";
+        # XXX: really need to handle this properly!
+        $mask_name    = "PSASTRO.OUTPUT.MASK";
         $weight_name  = "PPIMAGE.CHIP.VARIANCE";
         $cmf_name     = "PSPHOT.OUTPUT";
@@ -228,8 +258,15 @@
         $want_astrom  = 1;
         $set_class_id = 1;
-    } elsif ($img_type eq "warp") {
-        $skycell_id = $component;
-        $command = "$warptool -warped -dbname $image_db";
-        $component_args = " -skycell_id $skycell_id" if $skycell_id;
+    } elsif ($stage eq "warp") {
+        if ($component or $use_imfile_id or !$skycenter) {
+            $command = "$warptool -warped -dbname $imagedb";
+            if ($component and $component ne 'all') {
+                $skycell_id = $component;
+                $component_args = " -skycell_id $skycell_id";
+            }
+        } else {
+            $command = "$warptool -listrun -pstamp_order -dbname $imagedb";
+            $choose_components = 1;
+        }
         $id_opt = $use_imfile_id ? "-warp_skyfile_id" : "-warp_id";
         $image_name   = "PSWARP.OUTPUT";
@@ -239,8 +276,15 @@
         $psf_name     = "PSPHOT.PSF.SKY.SAVE";
         $base_name    = "path_base"; # name of the field for the warptool output
-    } elsif ($img_type eq "diff") {
-        $skycell_id = $component;
-        $command = "$difftool -diffskyfile -dbname $image_db";
-        $component_args = " -skycell_id $skycell_id" if $skycell_id;
+    } elsif ($stage eq "diff") {
+        if ($component or $use_imfile_id or !$skycenter) {
+            $command = "$difftool -diffskyfile -dbname $imagedb";
+            if ($component and $component ne 'all') {
+                $skycell_id = $component;
+                $component_args = " -skycell_id $skycell_id";
+            }
+        } else {
+            $command = "$difftool -listrun -pstamp_order -dbname $imagedb";
+            $choose_components = 1;
+        }
         $id_opt = $use_imfile_id ? "-diff_skyfile_id" : "-diff_id";
         $image_name  = "PPSUB.OUTPUT";
@@ -248,9 +292,9 @@
         $weight_name = "PPSUB.OUTPUT.VARIANCE";
         $cmf_name    = "PPSUB.OUTPUT.SOURCES";
-        $psf_name     = "PSPHOT.PSF.SKY.SAVE";
+        $psf_name    = "PSPHOT.PSF.SKY.SAVE";
         $base_name   = "path_base";
-    } elsif ($img_type eq "stack") {
+    } elsif ($stage eq "stack") {
         $skycell_id = $component;
-        $command = "$stacktool -sumskyfile -dbname $image_db";
+        $command = "$stacktool -sumskyfile -dbname $imagedb";
         $id_opt = "-stack_id";
         $component_args = " -skycell_id $skycell_id" if $skycell_id;
@@ -272,7 +316,8 @@
         $base_name   = "path_base";
     } else {
-        die "Unknown img_type supplied: $img_type";
-    }
-
+        die "Unknown IMG_TYPe supplied: $stage";
+    }
+
+    my $filter_runs = 0;
     if ($req_type eq "byid") {
         $command .= " $id_opt $id";
@@ -288,12 +333,15 @@
         # the reason as 'not destreaked'
         $magic_arg = "";
+        # remove duplicate runs for the same exposure.
+        $filter_runs = 1;
     } elsif ($req_type eq "byskycell") {
         die "tess_id and component are required for byskycell" if !$tess_id or ! $skycell_id;
         $command .= " -tess_id $tess_id -skycell_id $skycell_id";
     } else {
-        die "Unknown req_type supplied: $req_type";
-    }
-
-    if ($img_type ne "stack") {
+        # this should be caught by caller
+        &my_die("Unexpected req_type supplied: $req_type", $PS_EXIT_PROG_ERROR);
+    }
+
+    if ($stage ne "stack") {
         $command .= $magic_arg;
         $command .= " -dateobs_begin $dateobs_begin" if $dateobs_begin;
@@ -304,30 +352,32 @@
     $command .= " -data_group $data_group" if !isnull($data_group);
 
-    # run the tool and parse the output
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
-    unless ($success) {
-        # not sure if we should die here
-        print STDERR @$stderr_buf;
+    my $images = runToolAndParse($command, $verbose);
+
+    if (!$images or scalar @$images == 0) {
         return undef;
     }
 
-    my $buf = join "", @$stdout_buf;
-    if (!$buf) {
-        return;
-    }
-
-    my $mdcParser = PS::IPP::Metadata::Config->new;
-    my $images = parse_md_fast($mdcParser, $buf)
-        or die ("Unable to parse metadata config doc");
-
+    if ($filter_runs) {
+        # The image selectors are such that multiple runs my have be returned for the same exposure.
+        # Return only the latest one.
+        $images = filterRuns($stage, $need_magic, $images, $verbose);
+    }
+    if ($choose_components) {
+        # the list of "images" is actually a list of "Runs"
+        # match the coords in the rows to the components in the runs
+        # returns an actual list of images
+        $images = selectComponents($ipprc, $imagedb, $req_type, $stage, $rowList, $images, $verbose);
+    } else {
+        # put index for each of the rows into all of the the images
+        setRowRefs($rowList, $images);
+    }
+
+    my $camera;
     my $output = [];
-
-    my $camera;
     foreach my $image (@$images) {
         my $base;
 
         next if $image->{fault};
-        next if ($img_type ne "raw") and $image->{quality};
+        next if ($stage ne "raw") and $image->{quality};
 
         if ($base_name) {
@@ -348,26 +398,27 @@
             $ipprc->define_camera($camera);
         }
+        # ok it's a keeper
         my $out = $image;
 
         # if uri is nil this will get overridded below
         # (we do this here for raw stage)
-        $out->{image}  = $image->{uri};
+        $out->{image}  = $out->{uri};
 
         if ($set_class_id) {
-            $class_id = $image->{class_id};
+            $class_id = $out->{class_id};
             $out->{component} = $class_id;
         } else {
-            $out->{component} = $image->{skycell_id};
+            $out->{component} = $out->{skycell_id};
         }
         my $stage_id;
-        if ($img_type eq "raw") {
-            $stage_id = $image->{exp_id};
-        } elsif ($img_type eq "chip") {
-            $stage_id = $image->{chip_id};
-        } elsif ($img_type eq "warp") {
-            $stage_id = $image->{warp_id};
-        } elsif ($img_type eq "diff") {
-            $stage_id = $image->{diff_id};
-            if ($inverse && $image->{bothways}) {
+        if ($stage eq "raw") {
+            $stage_id = $out->{exp_id};
+        } elsif ($stage eq "chip") {
+            $stage_id = $out->{chip_id};
+        } elsif ($stage eq "warp") {
+            $stage_id = $out->{warp_id};
+        } elsif ($stage eq "diff") {
+            $stage_id = $out->{diff_id};
+            if ($inverse && $out->{bothways}) {
                 $image_name  = "PPSUB.INVERSE";
                 $mask_name   = "PPSUB.INVERSE.MASK";
@@ -375,20 +426,33 @@
                 $cmf_name    = "PPSUB.INVERSE.SOURCES";
             }
-        } elsif ($img_type eq "stack") {
-            $stage_id = $image->{stack_id};
+        } elsif ($stage eq "stack") {
+            $stage_id = $out->{stack_id};
         }
         $out->{stage_id} = $stage_id;
-        $out->{stage}    = $img_type;
-        $out->{image_db} = $image_db;
+        $out->{stage}    = $stage;
+        $out->{imagedb} = $imagedb;
+
+        my $mask_base;
+        if ($want_astrom) {
+            if (! defined $out->{astrom}) {
+                if (! find_astrometry($ipprc, $imagedb, $out, $verbose)) {
+                    print STDERR "failed to find astrometry for $stage $stage_id\n";
+                    next;
+                }
+            }
+            # XXX: do this right by looking at the recipe
+            $mask_base = $out->{cam_path_base};
+        } else {
+            $mask_base = $base;
+        }
 
         if ($base) {
             $out->{image}  = $ipprc->filename($image_name,  $base, $class_id) if $image_name;
-            $out->{mask}   = $ipprc->filename($mask_name,   $base, $class_id) if $mask_name;
+            $out->{mask}   = $ipprc->filename($mask_name,   $mask_base, $class_id) if $mask_name;
             $out->{weight} = $ipprc->filename($weight_name, $base, $class_id) if $weight_name;
-            $out->{cmf}    = $ipprc->filename($cmf_name, $base, $class_id) if $cmf_name;
-            $out->{psf}    = $ipprc->filename($psf_name, $base, $class_id) if $psf_name;
-            $out->{backmdl}= $ipprc->filename($backmdl_name, $base, $class_id) if $backmdl_name;
-        }
-        $out->{astrom} = find_astrometry($ipprc, $image_db, $image, $verbose) if $want_astrom;
+            $out->{cmf}    = $ipprc->filename($cmf_name,    $base, $class_id) if $cmf_name;
+            $out->{psf}    = $ipprc->filename($psf_name,    $base, $class_id) if $psf_name;
+            $out->{backmdl}= $ipprc->filename($backmdl_name,$base, $class_id) if $backmdl_name;
+        }
 
         push @$output, $out;
@@ -397,7 +461,9 @@
     return $output;
 }
+
 sub lookup_diff {
     my $ipprc    = shift;
-    my $image_db = shift;
+    my $rowList  = shift;
+    my $imagedb = shift;
     my $id       = shift;
     my $skycell_id = shift;
@@ -409,43 +475,32 @@
     my $inverse = $option_mask & $PSTAMP_SELECT_INVERSE;
 
-    my $missing_tools;
-    my $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
-
-    my $command = "$difftool -diffskyfile -dbname $image_db";
+    my $command = "$difftool -dbname $imagedb";
     
+    my $listrun = 0;
     if ($byid) {
-        $command .= " -diff_id $id";
+        if ($skycell_id) {
+            $command .= " -diffskyfile -diff_id $id -skycell_id $skycell_id";
+        } else {
+            $command .= " -listrun -diff_id $id";
+            $listrun = 1;
+        }
     } else {
-        $command .= " -diff_skyfile_id $id";
-    }
-    $command .= " -skycell_id $skycell_id" if $skycell_id;
-
-    # run the tool and parse the output
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
-    unless ($success) {
-        # not sure if we should die here
-        print STDERR @$stderr_buf;
-        return undef;
-    }
-
-    my $buf = join "", @$stdout_buf;
-    if (!$buf) {
-        return undef;
-    }
-
-    my $mdcParser = PS::IPP::Metadata::Config->new;
-    my $images = parse_md_fast($mdcParser, $buf)
-        or die ("Unable to parse metadata config doc");
-
-    my $n = @$images;
-    if (!$byid && ($n > 1)) {
+        $command .= " -diffskyfile -diff_skyfile_id $id";
+    }
+
+    my $output = runToolAndParse($command, $verbose);
+
+    my $n = $output ? scalar @$output : 0;
+    if (!$listrun && ($n > 1)) {
         die ("difftool returned an unexpected number of diffskyfiles: $n");
     } elsif ($n == 0) {
         return undef;
+    }
+
+    my $images;
+    if ($listrun) {
+        $images = selectComponents($ipprc, $imagedb, 'byid', 'diff', $rowList, $output, $verbose);
+    } else {
+        $images = $output;
     }
 
@@ -478,5 +533,7 @@
             if (($img_type ne "diff") and ($img_type ne "stack")) {
                 print STDERR "lookup_diff: cannot lookup IMG_TYPE $img_type bydiff from a stack stack diff run\n";
-                next;
+                setErrorCodes($rowList, $PSTAMP_INVALID_REQUEST);
+                # all images will be the same so we can stop
+                last;
             }
             # stack-stack diff
@@ -527,4 +584,7 @@
 
         if ($img_type eq "diff") {
+            my @imageList = ($image);
+
+            setRowRefs($rowList, \@imageList);
             # the $image is going to be returned directly in this case so we need to duplicate
             # some of processing that lookup does for other img_types
@@ -539,9 +599,9 @@
                 $image->{stage_id} = $image->{diff_id};
                 $image->{stage}    = "diff";
-                $image->{image_db} = $image_db;
+                $image->{imagedb} = $imagedb;
                 $image->{component} = $image->{skycell_id};
             } else {
                 # XXX this will only happen if the minuend is not a warp. See hack above
-                print STDERR "WARNING: cannot resolve camera so cannot get resolve file rules\n";
+                print STDERR "WARNING: cannot resolve camera so cannot find file rules\n";
                 next;
             }
@@ -554,5 +614,6 @@
 sub lookup_bycoord {
     my $ipprc      = shift;
-    my $image_db   = shift;
+    my $rowList    = shift;
+    my $imagedb    = shift;
     my $img_type   = shift;
     my $tess_id    = shift;
@@ -568,23 +629,15 @@
     my $verbose    = shift;
 
-    my $missing_tools;
-    my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
-    my $camtool = can_run('camtool') or (warn "Can't find camtool" and $missing_tools = 1);
-    my $dvoImagesAtCoords = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" and $missing_tools = 1);
-    my $whichimage = can_run('whichimage') or (warn "Can't find whichimage" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
-
     my $results = ();
     if (($img_type eq "raw") or ($img_type eq "chip")) {
 
-        my $runs = lookup_runs_by_camid_and_coords($ipprc, $image_db, $img_type,
+        my $runs = lookup_runs_by_cam_id_and_coords($ipprc, $imagedb, $img_type,
             $ra, $dec, $need_magic, $dateobs_begin, $dateobs_end, $filter, $data_group, $verbose);
 
+        # lookup is going to filter these we don't need to do it here
+#        $runs = filterRuns($img_type, $need_magic, $runs, $verbose);
         foreach my $run (@$runs) {
             next if $component and ($run->{component} ne $component);
-            my $these_results = lookup($ipprc, $image_db, "byid", $img_type, $run->{id},
+            my $these_results = lookup($ipprc, $rowList, $imagedb, "byid", $img_type, $run->{id},
                 $tess_id, $run->{component}, $need_magic, 
                 $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose);
@@ -602,5 +655,5 @@
 
         foreach my $skycell (@$skycells) {
-            my $these_results = lookup($ipprc, $image_db, "byskycell", $img_type, undef,
+            my $these_results = lookup($ipprc, $rowList, $imagedb, "byskycell", $img_type, undef,
                 $skycell->{tess_id}, $skycell->{component}, $need_magic, 
                 $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose);
@@ -614,10 +667,10 @@
 }
 
-# lookup_runs_by_camid_and_coords
+# lookup_runs_by_cam_id_and_coords
 # given an ra, dec, and optionally other paramters, find camera runs for exposures
 # that are within some distance of the coordinates
-sub lookup_runs_by_camid_and_coords {
+sub lookup_runs_by_cam_id_and_coords {
     my $ipprc      = shift;
-    my $image_db   = shift;
+    my $imagedb   = shift;
     my $img_type   = shift;
     my $ra         = shift;
@@ -631,14 +684,7 @@
 
     my $camruns;
-    my $missing_tools;
-    my $camtool = can_run('camtool') or (warn "Can't find camtool" and $missing_tools = 1);
-    my $dvoImagesAtCoords = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
 
     {
-        my $command = "$camtool -dbname $image_db -processedexp";
+        my $command = "$camtool -dbname $imagedb -processedexp -pstamp_order";
            $command .= " -ra $ra -decl $dec -radius 1.6";
            $command .= " -dateobs_begin $dateobs_begin" if $dateobs_begin;
@@ -652,19 +698,7 @@
            $command .= " -data_group $data_group" if $data_group;
            $command .= " -destreaked" if $need_magic;
+
         # run the tool and parse the output
-        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                    run(command => $command, verbose => $verbose);
-        unless ($success) {
-            print STDERR @$stderr_buf;
-            return undef;
-        }
-        my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
-
-        my $output = join "", @$stdout_buf;
-        if (!$output) {
-            print STDERR "no output returned from $command\n" if $verbose;
-            return undef;
-        }
-        $camruns = parse_md_fast($mdcParser, $output);
+        $camruns = runToolAndParse($command, $verbose);
     }
     if (!$camruns) {
@@ -672,11 +706,18 @@
     }
     my $runs;
+    my $last_exp_id = 0;
     foreach my $camRun (@$camruns) {
         my $cam_id = $camRun->{cam_id};
-
-        updateCamRunCache($camRun);
+        my $exp_id = $camRun->{exp_id};
+
+        next if $exp_id eq $last_exp_id;
 
         next if $camRun->{quality};
         next if $camRun->{fault};
+
+        updateCamRunCache($camRun);
+
+        $last_exp_id = $exp_id;
+
         # XXX Use file rule
         my $astrom = $camRun->{path_base} . ".smf";
@@ -684,12 +725,15 @@
         next if !$astrom_resolved;
 
+        my $start_dvo = gettimeofday();
         my $command = "$dvoImagesAtCoords -astrom $astrom_resolved $ra $dec";
         # run the tool and parse the output
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                    run(command => $command, verbose => $verbose);
+                    run(command => $command, verbose => $dvo_verbose);
+        my $dtime_dvo = gettimeofday() - $start_dvo;
+#        print "Time to run dvoImagesAtCoords: $dtime_dvo\n";
         unless ($success) {
             my $result_code = $error_code >> 8;
             if ($result_code == $PSTAMP_NO_OVERLAP) {
-                print STDERR "no overlap for $astrom\n" if $verbose;
+                print "no overlap for $astrom\n" if $verbose;
                 next;
             }
@@ -709,10 +753,14 @@
         my $n = scalar @lines;
         if ($n != 1) {
-            print STDERR "unexpected number of lines returned by dvoImagesAtCoords: $n\n";
-
             # XXX: There is a bug in dvo where each component is listed twice
             # When that gets fixed remove the conditional and just die
-            die "unexpected number lines returned by dvoImagesAtCoords: $n"
-                if ($n != 2) or ($lines[0] ne $lines[1]);
+            if ($n ne 2 or $lines[0] ne $lines[1]) {
+                print STDERR "unexpected number of lines returned by dvoImagesAtCoords: $n\n";
+                print STDERR "OUTPUT:\n$output\n";
+                # actually this seems to happen sometimes. Probably due to a problem with
+                # astrometry. Just skip this camRun
+                print STDERR "skipping: $astrom\n";
+                next;
+            }
         }
 
@@ -721,4 +769,7 @@
             die "unexpected output from dvoImagesAtCoords: $lines[0]";
         }
+
+        print "cam_id $cam_id exp_id $camRun->{exp_id} chip_id $camRun->{chip_id} $class_id\n";
+
         # build the hash to return
         my $run = {
@@ -727,12 +778,16 @@
             chip_id   => $camRun->{chip_id},
             cam_id    => $camRun->{cam_id},
-            astrom    => $astrom_resolved,
+            astrom    => $astrom_resolved,  # XXX: is astrom used?
             class_id  => $class_id,
             component => $class_id
         };
         if ($img_type eq "chip") {
-            $run->{id} = $run->{chip_id};
+            $run->{id} = $camRun->{chip_id};
+            $run->{state} = $camRun->{chip_state};
+            $run->{magicked} = $camRun->{chip_magicked};
         } else {
-            $run->{id} = $run->{exp_id};
+            $run->{id} = $camRun->{exp_id};
+            $run->{state} = 'full';
+            $run->{magicked} = $camRun->{raw_magicked};
         }
         push @$runs, $run;
@@ -749,11 +804,4 @@
     my $dec        = shift;
     my $verbose    = shift;
-
-    my $missing_tools;
-    my $whichimage = can_run('whichimage') or (warn "Can't find whichimage" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
 
     $requested_tess_id = "" if isnull($requested_tess_id);
@@ -810,12 +858,13 @@
 # cache of results of ppConfigDump
 my %astromSources;
-my $last_exp_id = 0;
-my $lastAstromFile;
 
 # find the astrometry file for a given exposure
 # return undef if no completed camRun exists
+# XXX Right now this probably only works cameras where the astrometry is done at the camera stage
+# What other possibilities are there for ASTROM.SOURCE besides PSASTRO.OUTPUT?
+
 sub find_astrometry {
     my $ipprc = shift;
-    my $image_db = shift;
+    my $imagedb = shift;
     my $image = shift;      # hashref to output of the lookup tool
     my $verbose = shift;
@@ -824,22 +873,8 @@
 
     my $exp_id = $image->{exp_id};
-    if (($exp_id eq $last_exp_id) and $lastAstromFile) {
-        # running camtool 60 times is really expensive when the answer is the same
-        return $lastAstromFile;
-    }
-    $last_exp_id = 0;
-    $lastAstromFile = undef;
-
-    my $missing_tools;
-    my $camtool = can_run("camtool") or (warn "Can't find camtool" and $missing_tools = 1);
-    my $ppConfigDump = can_run('ppConfigDump') or (warn "Can't find ppConfigDump" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
 
     my $camRun = getCamRunByExpID($exp_id);
     if (!$camRun) {
-        my $command = "$camtool -dbname $image_db -processedexp -exp_id $exp_id";
+        my $command = "$camtool -dbname $imagedb -processedexp -exp_id $exp_id -pstamp_order";
         # run the tool and parse the output
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -847,5 +882,5 @@
         unless ($success) {
             print STDERR @$stderr_buf;
-            return undef;
+            return 0;
         }
 
@@ -855,20 +890,23 @@
         if (!$output) {
             print STDERR "no output returned from $command\n" if $verbose;
-            return undef;
+            return 0;
         }
         my $camruns = parse_md_fast($mdcParser, $output);
         if (!$camruns) {
-            return undef;
+            return 0;
         }
 
         # If there are multiple cam runs for this exposure, take the last completed one with good quality
         # on the assumption that it has the best astrometry.
-        while ($camRun = pop @$camruns) {
-            last if (($camRun->{quality} eq 0) and ($camRun->{fault} eq 0));
+        foreach my $cr (@$camruns) {
+            if (($cr->{state} eq 'full') and ($cr->{quality} eq 0) and ($cr->{fault} eq 0)) {
+                $camRun = $cr;
+                last;
+            }
         }
         # XXX: this looks like a bug at least if ASTROM.SOURCE eq PSASTRO.OUTPUT
         if (!$camRun) {
             # no cam runs for this exposure id therefore best astrometry is whatever is in the header
-            return undef;
+            return 0;
         }
         updateCamRunCache($camRun);
@@ -899,10 +937,13 @@
     # XXX: Is this code correct if ASTROM.SOURCE ne "PSASTRO.OUTPUT"
     my $astromFile = $ipprc->filename($astromSource, $camRoot);
-    if ($astromFile) {
-        $lastAstromFile = $astromFile;
-        $last_exp_id = $exp_id;
-    }
-
-    return $astromFile;
+    if (!$astromFile) {
+        print STDERR "failed to find astrometry file from $astromSource $camRoot\n";
+        return 0;
+    }
+
+    $image->{astrom} = $astromFile;
+    $image->{cam_path_base} = $camRoot;
+
+    return 1;
 }
 
@@ -959,9 +1000,10 @@
 # resolve_project()
 # get project specific information
-my $last_project = "";
 sub resolve_project {
     my $ipprc = shift;
     my $project_name = shift;
 
+    findTools();
+
     if (!$project_name) {
         carp ("project is not defined");
@@ -969,5 +1011,5 @@
     }
 
-    if ($project_name eq $last_project) {
+    if ($last_project and ($project_name eq ($last_project->{name}))) {
         return $last_project;
     }
@@ -977,31 +1019,14 @@
 
     my $verbose = 0;
-
-    my $missing_tools;
-    my $pstamptool = can_run("pstamptool") or (warn "Can't find pstamptool" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
 
     my $command = "$pstamptool -project -name $project_name";
     $command .= " -dbname $dbname" if defined $dbname;
     $command .= " -dbserver $dbserver" if defined $dbserver;
-    # run the tool and parse the output
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
-    unless ($success) {
-        print STDERR @$stderr_buf;
+
+    my $proj_hash = runToolAndParse($command, $verbose);
+    if (!$proj_hash or scalar @$proj_hash == 0) {
+        print STDERR "Project $project_name not found\n";
         return undef;
     }
-
-    my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
-
-    my $output = join "", @$stdout_buf;
-    if (!$output) {
-        print STDERR "no output returned from $command\n" if $verbose;
-        return undef;
-    }
-    my $proj_hash = parse_md_fast($mdcParser, $output);
 
     $last_project = $proj_hash->[0];
@@ -1035,13 +1060,293 @@
 sub getCamRunByExpID {
     my $exp_id = shift;
-    die "getCamRun: exp_id is nil" if !$exp_id;
+    &my_die ("getCamRun: exp_id is nil", $PS_EXIT_PROG_ERROR) if !$exp_id;
 
     return $camRunByExpIDCache{$exp_id};
 }
+
 sub getCamRunByCamID {
     my $cam_id = shift;
-    die "getCamRun: cam_id is nil" if !$cam_id;
+    &my_die ("getCamRun: cam_id is nil", $PS_EXIT_PROG_ERROR) if !$cam_id;
 
     return $camRunByCamIDCache{$cam_id};
 }
+
+sub selectComponents {
+    my $ipprc = shift;
+    my $imagedb = shift;
+    my $req_type = shift;
+    my $stage  = shift;
+    my $rowList = shift;
+    my $runList = shift;
+    my $verbose = shift;
+    my $results = [];
+    
+    my ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps);
+    my $npoints = 0;
+    foreach my $row (@$rowList) {
+        print $pointsList "$npoints $row->{CENTER_X} $row->{CENTER_Y}\n";
+        $npoints++;
+        # this gets overwitten if an overlapping image is found
+        $row->{error_code} = $PSTAMP_NO_OVERLAP;
+    }
+    close $pointsList;
+
+    # XXX: need to loop over these
+    # my $run = $runList->[0];
+    if (($req_type eq "byid") or ($req_type eq "byexp")) {
+        my ($last_tess_id, $tess_dir_abs, $astrom_file) = ("", "", "");
+        foreach my $run (@$runList) {
+            my $command = "$dvoImagesAtCoords -coords $pointsListName";
+            if (($stage eq "chip") or ($stage eq "raw")) {
+                # XXX: use file rule and handle cameras where the astrometry is solved at
+                # the chip stage.
+                $astrom_file = $run->{cam_path_base} . ".smf";
+                my $astrom_file_resolved = $ipprc->file_resolve($astrom_file);
+                $command .= " -astrom $astrom_file_resolved";
+            } else {
+                my $tess_id = $run->{tess_id};
+                if ($tess_id ne $last_tess_id) {
+                    $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id );
+                    $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs );
+                    $last_tess_id = $tess_id;
+                }
+                $command .= " -D CATDIR $tess_dir_abs"
+            }
+            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                 run(command => $command, verbose => $dvo_verbose);
+            unless ($success) {
+                # don't fail if the program exited normally and exit status was PSTAMP_NO_OVERLAP
+                #                     # That just means that the coordinate didn't match any image/skycell
+                if (!WIFEXITED($error_code) || (WEXITSTATUS($error_code) ne $PSTAMP_NO_OVERLAP)) {
+                    print STDERR @$stderr_buf;
+                    my $rc = WIFEXITED($error_code) ? WEXITSTATUS($error_code) : $PS_EXIT_SYS_ERROR;
+                    &my_die( "dvoImagesAtCoords failed: $rc", $rc);
+                }
+            }
+            my %components;
+            my @lines = split "\n", join "", @$stdout_buf;
+            foreach my $line (@lines) {
+                my ($ptnum, undef, undef, $component) = split " ", $line;
+                my $ref = $components{$component};
+                if (!$ref) {
+                    $ref = $components{$component} = [];
+                }
+                push @$ref, $ptnum;
+                my $row = $rowList->[$ptnum];
+                # this row found a match
+                $row->{error_code} = 0;
+            }
+            if ($verbose) {
+                foreach my $c (keys %components) {
+                    my $ref = $components{$c};
+                    print "component $c contains: ";
+                    foreach my $i (@$ref) {
+                        print "$i ";
+                    }
+                    print "\n";
+                }
+            }
+            # now find the images for this run
+            foreach my $c (keys %components) {
+                my $command;
+                my $stage_id;
+                if ($stage eq 'raw') {
+                    $stage_id = $run->{exp_id};
+                    $command = "$regtool -processedimfile -exp_id $stage_id -class_id $c";
+                } elsif ($stage eq 'chip') {
+                    $stage_id = $run->{chip_id};
+                    $command = "$chiptool -processedimfile -chip_id $stage_id -class_id $c";
+                } elsif ($stage eq 'warp') {
+                    $stage_id = $run->{warp_id};
+                    $command = "$warptool -warped -warp_id $stage_id -skycell_id $c";
+                } elsif ($stage eq 'diff') {
+                    $stage_id = $run->{diff_id};
+                    $command = "$difftool -diffskyfile -diff_id $stage_id -skycell_id $c";
+                }
+                $command .= " -dbname $imagedb";
+                my $images = runToolAndParse($command, $verbose);
+                if (!defined $images) {
+                    print "No components containing coordinates found for ${stage}_id $stage_id\n";
+                    foreach my $row (@$rowList) {
+                        # XXX: This doesn't seem like the correct error code?
+                        $row->{error_code} = $PSTAMP_NO_OVERLAP;
+                    }
+                    next;
+                }
+                if (scalar @$images != 1) {
+                    my $num_images = scalar @$images;
+                    &my_die ("unexpected number of images returned: $num_images\n", $PS_EXIT_PROG_ERROR);
+                }
+                my $image = $images->[0];
+                    
+                my $ref = $components{$c};
+                $image->{row_index} = $ref;
+                if (($stage eq "raw") or ($stage eq 'chip')) {
+                    $image->{astrom} = $astrom_file;
+                    $image->{cam_id} = $run->{cam_id};
+                    $image->{cam_path_base} = $run->{cam_path_base};
+                }
+                push @$results, $image;
+            }
+        }
+    } else {
+        &my_die ("sorry not done with $req_type\n", $PS_EXIT_PROG_ERROR);
+    }
+    return $results;
+}
+
+sub filterRuns {
+    my $stage      = shift;
+    my $need_magic = shift;
+    my $inputs     = shift;
+    my $verbose    = shift;
+
+    if ($inputs and (scalar @$inputs) == 1)  {
+        # one run nothing to do
+        return $inputs;
+    }
+
+    my $output = [];
+
+    return $output if (!$inputs or scalar @$inputs == 0);
+
+    my $id_name = $stage . "_id";
+
+    # input list is "order by exp_id, run_id DESC"   run_id is one of (chip_id, warp_id, diff_id)
+    print "Starting filterRuns\n";
+    my $last_exp_id = 0;
+    my $last_run_id = 0;
+    my $printed = 0;
+    foreach my $input (@$inputs) {
+        my $exp_id = $input->{exp_id};
+        my $run_id = $input->{$id_name};
+        my $magicked = $input->{magicked};  # this will be either stageRun.magicked or stage%file.magicked
+        my $state = $input->{state};
+
+        # can't process run in these states
+        if (($state eq 'new') or ($state eq 'purged') or ($state eq 'scrubbed')) {
+            print "skipping ${stage}Run $run_id for exp_id $exp_id in state $state\n";
+            next;
+        }
+
+        $printed = 1 if (($exp_id == $last_exp_id) and ($run_id == $last_run_id));
+
+        # skip if we need magicked run and this one has never been magicked
+        if ($need_magic and !$magicked) {
+            print "skipping ${stage}Run $run_id for exp_id $exp_id not magicked\n" if !$printed;
+            next;
+        }
+
+        if (($exp_id == $last_exp_id) and ($run_id != $last_run_id)) {
+            print "Skipping duplicate ${stage}Run $run_id for $exp_id\n" if !$printed;
+            next;
+        }
+        print "Keeping ${stage}Run $run_id for $exp_id\n";
+        push @$output, $input;
+        $last_exp_id = $exp_id;
+        $last_run_id = $run_id;
+        $printed = 0;
+    }
+
+    my $num_runs = scalar @$output;
+    print "filterRuns returning $num_runs ${stage}Run\n";
+
+    return $output;
+}
+
+# run a command that produces metadata output and parse the results into an array of objects
+sub runToolAndParse {
+    my $command = shift;
+    my $verbose = shift;
+
+    my ($program) = split " ", $command;
+    $program = basename($program);
+
+    print "Running $command\n" if !$verbose;
+    my $start_tool = gettimeofday();
+    # run the command and parse the output
+
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                run(command => $command, verbose => $verbose);
+    unless ($success) {
+        # not sure if we should die here
+        print STDERR @$stderr_buf;
+        return undef;
+    }
+
+    my $now = gettimeofday();
+    my $dtime_tool = $now - $start_tool;
+    print "Time to run $program: $dtime_tool\n";
+
+    my $buf = join "", @$stdout_buf;
+    if (!$buf) {
+        return undef;
+    }
+
+    my $start_parse = gettimeofday();
+
+    my $mdcParser = PS::IPP::Metadata::Config->new;
+    my $results = parse_md_fast($mdcParser, $buf)
+        or die ("Unable to parse metadata config doc");
+
+    my $dtime_parse = gettimeofday() - $start_parse;
+    print "Time to parse results from $program: $dtime_parse\n";
+
+    return $results;
+}
+
+sub findTools {
+    return if ($regtool);
+
+    my $missing_tools;
+    $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
+    $chiptool = can_run('chiptool') or (warn "Can't find chiptool" and $missing_tools = 1);
+    $camtool = can_run('camtool') or (warn "Can't find camtool" and $missing_tools = 1);
+    $warptool = can_run('warptool') or (warn "Can't find warptool" and $missing_tools = 1);
+    $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1);
+    $stacktool = can_run('stacktool') or (warn "Can't find stacktool" and $missing_tools = 1);
+    $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools = 1);
+    $dvoImagesAtCoords = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" 
+                                                                and $missing_tools = 1);
+    $whichimage = can_run('whichimage') or (warn "Can't find whichimage" and $missing_tools = 1);
+    $ppConfigDump = can_run('ppConfigDump') or (warn "Can't find ppConfigDump" and $missing_tools = 1);
+    if ($missing_tools) {
+        warn("Can't find required tools.");
+        exit ($PS_EXIT_CONFIG_ERROR);
+    }
+}
+
+# add a row_index array to a set of images with entries for each of the rows in a list
+sub setRowRefs {
+    my $rowList = shift;
+    my $images  = shift;
+
+    my $row_index = [];
+    for (my $i = 0; $i < scalar @$rowList; $i++) {
+        push @$row_index, $i;
+    }
+    foreach my $image (@$images) {
+        $image->{row_index} = $row_index;
+    }
+}
+# set error_code for an array of rows to a given value
+sub setErrorCodes {
+    my $rowList = shift;
+    my $code = shift;
+    foreach my $row (@$rowList) {
+        $row->{error_code} = $code;
+    }
+}
+
+sub my_die
+{
+    my $msg = shift;
+    my $fault = shift;
+
+    carp $msg;
+
+    # we don't fault the request here pstamp_parser_run.pl handles that if necessary
+
+    return $fault;
+}
 1;
Index: /branches/pap/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm
===================================================================
--- /branches/pap/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm	(revision 28002)
+++ /branches/pap/PS-IPP-PStamp/lib/PS/IPP/PStamp/RequestFile.pm	(revision 28003)
@@ -29,5 +29,5 @@
                     $PSTAMP_SELECT_UNCONV
                     $PSTAMP_USE_IMFILE_ID
-                    $PSTAMP_WAIT_FOR_UPDATE
+                    $PSTAMP_NO_WAIT_FOR_UPDATE
                     $PSTAMP_SUCCESS
                     $PSTAMP_SYSTEM_ERROR
@@ -63,5 +63,5 @@
 our $PSTAMP_USE_IMFILE_ID    = 16384;
 
-our $PSTAMP_WAIT_FOR_UPDATE  = 32768;
+our $PSTAMP_NO_WAIT_FOR_UPDATE  = 32768;
 
 # job and result codes
@@ -145,8 +145,5 @@
         }
         if (@$stdout_buf) {
-            my $table =  $mdcParser->parse(join "", @$stdout_buf) or
-                die("Unable to parse metdata config doc");
-
-            $rows = parse_md_list($table);
+            $rows = parse_md_fast($mdcParser, join "", @$stdout_buf);
         } else {
             print STDERR "$request_file_name contains empty request table\n";
@@ -180,3 +177,31 @@
     return (\%header, \%req_specs);
 }
+
+sub parse_md_fast {
+    my $mdcParser = shift;
+    my $input = shift;
+    my $output = ();
+
+    my @whole = split /\n/, $input;
+    my @single = ();
+
+    my $n;
+    while ( ($n = @whole) > 0) {
+        my $value = shift @whole;
+        push @single, $value;
+        if ($value =~ /^\s*END\s*$/) {
+	    push @single, "\n";
+
+            my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or
+                print STDERR "Unable to parse metdata config doc" and return undef;
+#            my $num = @$list;
+#            print STDERR "list has $num elments\n";
+            push @$output, $list->[0];
+
+            @single = ();
+        }
+    }
+    return $output;
+}
+
 1;
Index: /branches/pap/dbconfig/changes.txt
===================================================================
--- /branches/pap/dbconfig/changes.txt	(revision 28002)
+++ /branches/pap/dbconfig/changes.txt	(revision 28003)
@@ -1554,5 +1554,5 @@
       note VARCHAR(255),             -- note
       registered TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- time run was registered
-      PRIMARY KEY(dqstats_id),
+      PRIMARY KEY(ss_id),
       KEY(state),
       KEY(label),
@@ -1586,4 +1586,32 @@
       KEY(fault),
       KEY(quality),
-      FOREIGN KEY(ss_id) REFERENCES staticskyRun(ss_id),
-) ENGINE=innodb DEFAULT CHARSET=latin1;
+      FOREIGN KEY(ss_id) REFERENCES staticskyRun(ss_id)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+ALTER TABLE pstampDependent ADD COLUMN component VARCHAR(64) after stage_id;
+ALTER TABLE pstampDependent CHANGE COLUMN no_magic need_magic TINYINT;
+ALTER TABLE pstampDependent ADD COLUMN fault SMALLINT after need_magic;
+ALTER TABLE pstampDependent ADD COLUMN outdir VARCHAR(255) after imagedb;
+ALTER TABLE pstampDependent ADD KEY (state);
+ALTER TABLE pstampDependent ADD KEY (stage);
+ALTER TABLE pstampDependent ADD KEY (stage_id);
+ALTER TABLE pstampDependent ADD KEY (component);
+ALTER TABLE pstampDependent ADD KEY (imagedb);
+
+ALTER TABLE magicDSRun ADD KEY(stage);
+ALTER TABLE magicDSRun ADD KEY(stage_id);
+
+ALTER TABLE distRun ADD KEY(stage), ADD KEY(stage_id), ADD KEY(magic_ds_id), ADD KEY(fault), ADD KEY(data_group);
+ALTER TABLE distTarget ADD KEY(stage), ADD KEY(dist_group), ADD KEY(filter), ADD KEY(state);
+
+CREATE TABLE Label (
+    label       VARCHAR(64),
+    priority    INT,
+    active      TINYINT,
+    comment     VARCHAR(80),
+    PRIMARY KEY(label),
+    KEY(priority),
+    KEY(active)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+ALTER TABLE pstampRequest ADD COLUMN outdir VARCHAR(64) after uri;
Index: /branches/pap/dbconfig/ipp.m4
===================================================================
--- /branches/pap/dbconfig/ipp.m4	(revision 28002)
+++ /branches/pap/dbconfig/ipp.m4	(revision 28003)
@@ -21,4 +21,5 @@
 include(stack.md)
 include(det.md)
+include(label.md)
 include(magic.md)
 include(calibration.md)
Index: /branches/pap/dbconfig/label.md
===================================================================
--- /branches/pap/dbconfig/label.md	(revision 28003)
+++ /branches/pap/dbconfig/label.md	(revision 28003)
@@ -0,0 +1,6 @@
+Label   METADATA
+    label       STR     64  # Primary Key
+    priority    S32      0
+    active      BOOL     t
+    comment     STR     80
+END
Index: /branches/pap/dbconfig/pstamp.md
===================================================================
--- /branches/pap/dbconfig/pstamp.md	(revision 28002)
+++ /branches/pap/dbconfig/pstamp.md	(revision 28003)
@@ -30,4 +30,5 @@
     outProduct  STR         64
     uri         STR         255
+    outdir      STR         255
     fault       S32         0
 END
@@ -51,6 +52,9 @@
     stage       STR         64
     stage_id    S64         0
+    component   STR         64
     imagedb     STR         64
     rlabel      STR         64
-    no_magic    BOOL        f
+    need_magic  BOOL        f
+    outdir      STR         255
+    fault       S16         0
 END
Index: /branches/pap/dbconfig/staticsky.md
===================================================================
--- /branches/pap/dbconfig/staticsky.md	(revision 28002)
+++ /branches/pap/dbconfig/staticsky.md	(revision 28003)
@@ -2,5 +2,5 @@
 
 staticskyRun METADATA
-    ss_id       S64         0       # Primary Key AUTO_INCREMENT
+    sky_id      S64         0       # Primary Key AUTO_INCREMENT
     state       STR         64      # Key
     workdir     STR         255
@@ -14,10 +14,10 @@
 
 staticskyInput METADATA
-    ss_id       S64         0       # Primary Key fkey(ss_id) ref staticskyRun(ss_id)
+    sky_id      S64         0       # Primary Key fkey(sky_id) ref staticskyRun(sky_id)
     stack_id    S64         0       # Primary Key fkey(stack_id) ref stackSumSkyfile(stack_id)
 END
 
-staticSkyResult METADATA
-    ss_id              S64    0       # Primary Key fkey(ss_id) ref staticskyRun(ss_id)
+staticskyResult METADATA
+    sky_id             S64    0       # Primary Key fkey(sky_id) ref staticskyRun(sky_id)
     path_base          STR    255
     dtime_phot         F32    0.0
Index: /branches/pap/doc/pslib/psLibSDRS.tex
===================================================================
--- /branches/pap/doc/pslib/psLibSDRS.tex	(revision 28002)
+++ /branches/pap/doc/pslib/psLibSDRS.tex	(revision 28003)
@@ -7449,8 +7449,10 @@
 \end{prototype}
 
-The following function changes the given rotation to its inverse:
-
-\begin{prototype}
-psSphereRot *psSphereRotInvert(psSphereRot *rot);
+The following function constructs a the \code{psSphereRot} with the
+inverse rotation of the given euler angles.  This is equivalent to
+applying \code{psSphereRotConjugate} on a \code{psSphereRot} object:
+
+\begin{prototype}
+psSphereRot *psSphereRotInvert(double alphaP, double deltaP, double phiP);
 \end{prototype}
 
Index: /branches/pap/ippMonitor/Makefile.in
===================================================================
--- /branches/pap/ippMonitor/Makefile.in	(revision 28002)
+++ /branches/pap/ippMonitor/Makefile.in	(revision 28003)
@@ -13,5 +13,8 @@
 
 PROGRAMS = \
-$(DESTBIN)/skyplot.dvo
+$(DESTBIN)/skyplot.dvo \
+$(DESTBIN)/getLabels.pl \
+$(DESTBIN)/checkServer.pl \
+$(DESTBIN)/getServerStatus.pl
 
 RAWSRC = \
@@ -43,5 +46,7 @@
 $(DESTWWW)/simplePlotraw.php \
 $(DESTWWW)/skyplot.php \
-$(DESTWWW)/getimage.php
+$(DESTWWW)/getimage.php \
+$(DESTWWW)/czartool.php \
+
 
 DEFSRC = \
Index: /branches/pap/ippMonitor/def/camIQstats.d
===================================================================
--- /branches/pap/ippMonitor/def/camIQstats.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camIQstats.d	(revision 28003)
@@ -20,4 +20,6 @@
 FIELD rawExp.exp_name,     	 5, %s,     Exp Name
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.dateobs,        	19, %T,     Date/Time
 FIELD rawExp.filter,         	10, %s,     FILTER
Index: /branches/pap/ippMonitor/def/camPendingExp.d
===================================================================
--- /branches/pap/ippMonitor/def/camPendingExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camPendingExp.d	(revision 28003)
@@ -22,4 +22,6 @@
 FIELD camRun.state,              5,   %s,     State
 FIELD camRun.label,              5,   %s,     Label
+FIELD camRun.data_group,              5,   %s,     data grp
+FIELD camRun.dist_group,              5,   %s,     dist grp
 FIELD rawExp.telescope,      	10,   %s,     Telescope
 FIELD rawExp.camera,         	10,   %s,     Camera
Index: /branches/pap/ippMonitor/def/camProcessedExp.d
===================================================================
--- /branches/pap/ippMonitor/def/camProcessedExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camProcessedExp.d	(revision 28003)
@@ -30,4 +30,6 @@
 FIELD camRun.state,                      5,   %s,     state,        value,  	 camProcessedImfile.php,  ARG4
 FIELD camRun.label,             	 5,   %s,     Label
+FIELD camRun.data_group,             	 5,   %s,     data grp
+FIELD camRun.dist_group,             	 5,   %s,     dist grp
 FIELD rawExp.telescope,      		10,   %s,     Telescope
 FIELD rawExp.camera,         		10,   %s,     Camera
Index: /branches/pap/ippMonitor/def/camProcessedExp_Images.d
===================================================================
--- /branches/pap/ippMonitor/def/camProcessedExp_Images.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camProcessedExp_Images.d	(revision 28003)
@@ -33,4 +33,6 @@
 FIELD camRun.cam_id,             	 5,   %d,     Cam ID,       value,  	 camProcessedExp_Images.php,     ARG3
 FIELD camRun.label,             	 5,   %s,     Label
+FIELD camRun.data_group,             	 5,   %s,     data grp
+FIELD camRun.dist_group,             	 5,   %s,     dist grp
 FIELD *,    	                	 8,   %s,     image,        image=JPEG2, camProcessedImfile.php,  ARG4
 FIELD rawExp.telescope,      		10,   %s,     Telescope
Index: /branches/pap/ippMonitor/def/camProcessedExp_NoImages.d
===================================================================
--- /branches/pap/ippMonitor/def/camProcessedExp_NoImages.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camProcessedExp_NoImages.d	(revision 28003)
@@ -30,4 +30,6 @@
 FIELD camRun.state,                      5,   %s,     state,        value,  	 camProcessedImfile.php,  ARG4
 FIELD camRun.label,                      5,   %s,     label
+FIELD camRun.data_group,                      5,   %s,     data grp
+FIELD camRun.dist_group,                      5,   %s,     dist grp
 FIELD rawExp.telescope,      		10,   %s,     Telescope
 FIELD rawExp.camera,         		10,   %s,     Camera
Index: /branches/pap/ippMonitor/def/camProcessedExp_failure.d
===================================================================
--- /branches/pap/ippMonitor/def/camProcessedExp_failure.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camProcessedExp_failure.d	(revision 28003)
@@ -29,4 +29,6 @@
 FIELD camRun.state,                      5,   %s,     state,        value,       camProcessedImfile.php,      ARG4
 FIELD camRun.label,                      5,   %s,     label
+FIELD camRun.data_group,                      5,   %s,     data grp
+FIELD camRun.dist_group,                      5,   %s,     dist grp
 FIELD rawExp.telescope,      		10,   %s,     Telescope
 FIELD rawExp.camera,         		10,   %s,     Camera
Index: /branches/pap/ippMonitor/def/camProcessedImfile.d
===================================================================
--- /branches/pap/ippMonitor/def/camProcessedImfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camProcessedImfile.d	(revision 28003)
@@ -27,4 +27,6 @@
 FIELD camRun.cam_id,            	 5,   %s,     Cam ID,       value,       camProcessedExp.php,     ARG3
 FIELD camRun.label,             	 5,   %s,     Label
+FIELD camRun.data_group,             	 5,   %s,     data grp
+FIELD camRun.dist_group,             	 5,   %s,     dist grp
 FIELD rawExp.telescope,      		10,   %s,     Telescope
 FIELD rawExp.camera,         		10,   %s,     Camera
Index: /branches/pap/ippMonitor/def/camStageExp.d
===================================================================
--- /branches/pap/ippMonitor/def/camStageExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/camStageExp.d	(revision 28003)
@@ -21,4 +21,6 @@
 FIELD camRun.state,              5,   %s,     state
 FIELD camRun.label,              5,   %s,     label
+FIELD camRun.data_group,              5,   %s,     data grp
+FIELD camRun.dist_group,              5,   %s,     dist grp
 FIELD rawExp.telescope,      	10,   %s,     Telescope
 FIELD rawExp.camera,         	10,   %s,     Camera
Index: /branches/pap/ippMonitor/def/chipIQstats.d
===================================================================
--- /branches/pap/ippMonitor/def/chipIQstats.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipIQstats.d	(revision 28003)
@@ -20,4 +20,6 @@
 FIELD chipRun.chip_id,    	 5, %d,     Ch ID,       value,  chipProcessedImfile.php, ARG2
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.dateobs,        	19, %T,     Date/Time
 FIELD rawExp.filter,         	10, %s,     FILTER
Index: /branches/pap/ippMonitor/def/chipPendingExp.d
===================================================================
--- /branches/pap/ippMonitor/def/chipPendingExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipPendingExp.d	(revision 28003)
@@ -20,4 +20,6 @@
 FIELD chipRun.state,    	 7, %s,     State
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/chipPendingImfile.d
===================================================================
--- /branches/pap/ippMonitor/def/chipPendingImfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipPendingImfile.d	(revision 28003)
@@ -25,4 +25,6 @@
 FIELD chipRun.state,    	 7, %s,     State
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/chipProcessedExp.d
===================================================================
--- /branches/pap/ippMonitor/def/chipProcessedExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipProcessedExp.d	(revision 28003)
@@ -20,4 +20,6 @@
 FIELD chipRun.state,    	 7, %s,     State
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/chipProcessedImfile.d
===================================================================
--- /branches/pap/ippMonitor/def/chipProcessedImfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipProcessedImfile.d	(revision 28003)
@@ -30,4 +30,6 @@
 FIELD chipRun.state,        	   	  7, %s,     State,       value,  chipProcessedImfile.php, ARG3
 FIELD chipRun.label,        	   	  7, %s,     Label
+FIELD chipRun.data_group,        	   	  7, %s,     data grp
+FIELD chipRun.dist_group,        	   	  7, %s,     dist grp
 FIELD rawExp.telescope,      	   	 10, %s,     Telescope
 FIELD rawExp.camera,         	   	 10, %s,     Camera
Index: /branches/pap/ippMonitor/def/chipProcessedImfile_failure.d
===================================================================
--- /branches/pap/ippMonitor/def/chipProcessedImfile_failure.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipProcessedImfile_failure.d	(revision 28003)
@@ -30,4 +30,6 @@
 FIELD chipRun.state,        	   	  7, %s,     State,       value,  chipProcessedImfile_failure.php, ARG3
 FIELD chipRun.label,        	   	  7, %s,     Label
+FIELD chipRun.data_group,        	   	  7, %s,     data grp
+FIELD chipRun.dist_group,        	   	  7, %s,     dist grp
 FIELD chipProcessedImfile.fault,      	  2, %d,     Fault
 FIELD rawExp.telescope,      	   	 10, %s,     Telescope
Index: /branches/pap/ippMonitor/def/chipStageExp.d
===================================================================
--- /branches/pap/ippMonitor/def/chipStageExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/chipStageExp.d	(revision 28003)
@@ -18,4 +18,6 @@
 FIELD chipRun.state,    	 7, %s,     State
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/destreakRun.d
===================================================================
--- /branches/pap/ippMonitor/def/destreakRun.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/destreakRun.d	(revision 28003)
@@ -19,5 +19,5 @@
 FIELD magicDSRun.cam_id,       5, %d,     Camera ID
 FIELD magicDSRun.label,        10, %s,     Label
-FIELD magicDSRun.data_group,   8, %s,     Data Group
+FIELD magicDSRun.data_group,        10, %s,     data grp
 FIELD magicDSRun.outroot,      10, %s,     Out Root
 FIELD magicDSRun.recoveryroot, 5, %d,     Recov. Root
Index: /branches/pap/ippMonitor/def/diffFailedSkyfile.d
===================================================================
--- /branches/pap/ippMonitor/def/diffFailedSkyfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/diffFailedSkyfile.d	(revision 28003)
@@ -16,4 +16,6 @@
 FIELD diffSkyfile.skycell_id,          5, %s,     Skycell ID
 FIELD diffRun.label,    	       5, %s,     Label
+FIELD diffRun.data_group,    	       5, %s,     data grp
+FIELD diffRun.dist_group,    	       5, %s,     dist grp
 # FIELD diffRun.filter,    	       5, %s,     Filter
 FIELD diffRun.tess_id,    	       5, %s,     Tess ID
Index: /branches/pap/ippMonitor/def/diffInputSkyfile.d
===================================================================
--- /branches/pap/ippMonitor/def/diffInputSkyfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/diffInputSkyfile.d	(revision 28003)
@@ -12,4 +12,6 @@
 FIELD    diffRun.state,         	    7, %s,     state
 FIELD    diffRun.label,	    		    7, %s,     label
+FIELD    diffRun.data_group,   		    7, %s,     data grp
+FIELD    diffRun.dist_group,  		    7, %s,     dist grp
 FIELD    diffRun.magicked,	     	    4, %d,     Magicked
 FIELD    diffInputSkyfile.warp1,	    5, %d,     warp 1
Index: /branches/pap/ippMonitor/def/diffProcessedSkyfile.d
===================================================================
--- /branches/pap/ippMonitor/def/diffProcessedSkyfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/diffProcessedSkyfile.d	(revision 28003)
@@ -17,4 +17,6 @@
 FIELD diffSkyfile.skycell_id,          4, %s,     Skycell ID
 FIELD diffRun.label,    	       5, %s,     Label
+FIELD diffRun.data_group,    	       5, %s,     data grp
+FIELD diffRun.dist_group,    	       5, %s,     dist grp
 # FIELD diffRun.filter,    	       5, %s,     Filter
 FIELD diffRun.tess_id,    	       5, %s,     Tess ID
Index: /branches/pap/ippMonitor/def/diffProcessedSkyfile_Images.d
===================================================================
--- /branches/pap/ippMonitor/def/diffProcessedSkyfile_Images.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/diffProcessedSkyfile_Images.d	(revision 28003)
@@ -22,4 +22,6 @@
 FIELD diffSkyfile.skycell_id,          5, %s,     Skycell ID
 FIELD diffRun.label,    	       5, %s,     Label
+FIELD diffRun.data_group,    	       5, %s,     data grp
+FIELD diffRun.dist_group,    	       5, %s,     dist grp
 FIELD *,    	                       8, %s,     image,         image=JPEG2, diffProcessedSkyfile_Images.php,  ARG7
 # FIELD diffRun.filter,    	       5, %s,     Filter
Index: /branches/pap/ippMonitor/def/diffRun.d
===================================================================
--- /branches/pap/ippMonitor/def/diffRun.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/diffRun.d	(revision 28003)
@@ -8,4 +8,6 @@
 FIELD    state,		 7, %s,     state
 FIELD    label,		 7, %s,     label
+FIELD    data_group,	 7, %s,     data grp
+FIELD    dist_group,	 7, %s,     dist grp
 FIELD    magicked,	 4, %d,     Magicked
 FIELD    tess_id,	 8, %s,     tess ID
Index: /branches/pap/ippMonitor/def/distRun.d
===================================================================
--- /branches/pap/ippMonitor/def/distRun.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/distRun.d	(revision 28003)
@@ -15,4 +15,5 @@
 FIELD distRun.magic_ds_id,    5, %d,     Magic DS ID
 FIELD distRun.label,          5, %s,     Label
+FIELD distRun.data_group,          5, %s,     data grp
 FIELD distRun.outroot,        5, %s,     Outroot
 FIELD distRun.outdir,         5, %s,     Outdir
Index: /branches/pap/ippMonitor/def/distSummary.d
===================================================================
--- /branches/pap/ippMonitor/def/distSummary.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/distSummary.d	(revision 28003)
@@ -6,4 +6,5 @@
 #     field                   size  format  name         show    link to                  extras
 FIELD distRun.label,          15, %s,     Label
+FIELD distRun.data_group,          15, %s,     data grp
 FIELD distRun.stage,          5, %s,     Stage
 FIELD distRun.state,          5, %s,     State
Index: /branches/pap/ippMonitor/def/fakePendingExp.d
===================================================================
--- /branches/pap/ippMonitor/def/fakePendingExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/fakePendingExp.d	(revision 28003)
@@ -26,4 +26,6 @@
 FIELD fakeRun.state,    	 7, %s,     state
 FIELD fakeRun.label,    	 7, %s,     label
+FIELD fakeRun.data_group,    	 7, %s,     data grp
+FIELD fakeRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/fakePendingImfile.d
===================================================================
--- /branches/pap/ippMonitor/def/fakePendingImfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/fakePendingImfile.d	(revision 28003)
@@ -27,4 +27,6 @@
 FIELD fakeRun.state,    	 7, %s,     State
 FIELD fakeRun.label,    	 7, %s,     label
+FIELD fakeRun.data_group,    	 7, %s,     data grp
+FIELD fakeRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/fakeProcessedExp.d
===================================================================
--- /branches/pap/ippMonitor/def/fakeProcessedExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/fakeProcessedExp.d	(revision 28003)
@@ -26,4 +26,6 @@
 FIELD fakeRun.state,    	 7, %s,     state
 FIELD fakeRun.label,    	 7, %s,     label
+FIELD fakeRun.data_group,    	 7, %s,     data grp
+FIELD fakeRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/fakeProcessedImfile.d
===================================================================
--- /branches/pap/ippMonitor/def/fakeProcessedImfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/fakeProcessedImfile.d	(revision 28003)
@@ -34,4 +34,6 @@
 FIELD fakeRun.state,                   7, %s,     State,       value,  fakeProcessedImfile.php, ARG5
 FIELD fakeRun.label,                   7, %s,     Label
+FIELD fakeRun.data_group,                   7, %s,     data grp
+FIELD fakeRun.dist_group,                   7, %s,     dist grp
 FIELD rawExp.telescope,               10, %s,     Telescope
 FIELD rawExp.camera,                  10, %s,     Camera
Index: /branches/pap/ippMonitor/def/fakeProcessedImfile_failure.d
===================================================================
--- /branches/pap/ippMonitor/def/fakeProcessedImfile_failure.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/fakeProcessedImfile_failure.d	(revision 28003)
@@ -34,4 +34,6 @@
 FIELD fakeRun.state,                   7, %s,     State,       value,  fakeProcessedImfile_failure.php, ARG5
 FIELD fakeRun.label,                   7, %s,     Label
+FIELD fakeRun.data_group,                   7, %s,     data grp
+FIELD fakeRun.dist_group,                   7, %s,     dist grp
 FIELD rawExp.telescope,               10, %s,     Telescope
 FIELD rawExp.camera,                  10, %s,     Camera
Index: /branches/pap/ippMonitor/def/fakeStageExp.d
===================================================================
--- /branches/pap/ippMonitor/def/fakeStageExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/fakeStageExp.d	(revision 28003)
@@ -24,4 +24,6 @@
 FIELD fakeRun.state,    	 7, %s,     state
 FIELD fakeRun.label,    	 7, %s,     label
+FIELD fakeRun.data_group,    	 7, %s,     data grp
+FIELD fakeRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/flatcorrCamera.d
===================================================================
--- /branches/pap/ippMonitor/def/flatcorrCamera.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/flatcorrCamera.d	(revision 28003)
@@ -19,4 +19,6 @@
 FIELD camRun.state,    	         7, %s,     State
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/flatcorrChip.d
===================================================================
--- /branches/pap/ippMonitor/def/flatcorrChip.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/flatcorrChip.d	(revision 28003)
@@ -18,4 +18,6 @@
 FIELD chipRun.state,    	 7, %s,     State
 FIELD chipRun.label,    	 7, %s,     Label
+FIELD chipRun.data_group,    	 7, %s,     data grp
+FIELD chipRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/magicFailedMasks.d
===================================================================
--- /branches/pap/ippMonitor/def/magicFailedMasks.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicFailedMasks.d	(revision 28003)
@@ -12,4 +12,5 @@
 FIELD    magicRun.diff_id,	 5,   %d,     Diff ID
 FIELD    magicRun.label, 	 5,   %s,     Label
+FIELD    magicRun.data_group, 	 5,   %s,     data grp
 FIELD    magicRun.inverse,	 5,   %d,     Inverse
 FIELD    magicRun.state,	 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicFailedNodes.d
===================================================================
--- /branches/pap/ippMonitor/def/magicFailedNodes.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicFailedNodes.d	(revision 28003)
@@ -14,4 +14,5 @@
 FIELD    magicRun.diff_id,	 5,   %d,     Diff ID
 FIELD    magicRun.label, 	 5,   %s,     Label
+FIELD    magicRun.data_group, 	 5,   %s,     data grp
 FIELD    magicRun.inverse,	 5,   %d,     Inverse
 FIELD    magicRun.state,	 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicFailedTrees.d
===================================================================
--- /branches/pap/ippMonitor/def/magicFailedTrees.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicFailedTrees.d	(revision 28003)
@@ -11,4 +11,5 @@
 FIELD    diff_id,	 5,   %d,     Diff ID
 FIELD    label,	 	 5,   %s,     Label
+FIELD    data_group, 	 5,   %s,     Data Grp
 FIELD    inverse,	 5,   %d,     Inverse
 FIELD    state,		 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicProcessedMasks.d
===================================================================
--- /branches/pap/ippMonitor/def/magicProcessedMasks.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicProcessedMasks.d	(revision 28003)
@@ -11,4 +11,5 @@
 FIELD    magicRun.diff_id,	 5,   %d,     Diff ID
 FIELD    magicRun.label, 	 5,   %s,     Label
+FIELD    magicRun.data_group, 	 5,   %s,     data grp
 FIELD    magicRun.inverse,	 5,   %d,     Inverse
 FIELD    magicRun.state,	 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicProcessedMasks_Images.d
===================================================================
--- /branches/pap/ippMonitor/def/magicProcessedMasks_Images.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicProcessedMasks_Images.d	(revision 28003)
@@ -19,4 +19,5 @@
 # FIELD    *,                      8,   %s,     image,         image=JPEG2, diffProcessedSkyfile_Images.php,  ARG7
 FIELD    magicRun.label, 	 5,   %s,     Label
+FIELD    magicRun.data_group, 	 5,   %s,     data grp
 FIELD    magicRun.inverse,	 5,   %d,     Inverse
 FIELD    magicRun.state,	 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicProcessedNodes.d
===================================================================
--- /branches/pap/ippMonitor/def/magicProcessedNodes.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicProcessedNodes.d	(revision 28003)
@@ -13,4 +13,5 @@
 FIELD    magicRun.diff_id,	 5,   %d,     Diff ID
 FIELD    magicRun.label, 	 5,   %s,     Label
+FIELD    magicRun.data_group, 	 5,   %s,     data grp
 FIELD    magicRun.inverse,	 5,   %d,     Inverse
 FIELD    magicRun.state,	 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicRun.d
===================================================================
--- /branches/pap/ippMonitor/def/magicRun.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicRun.d	(revision 28003)
@@ -9,4 +9,5 @@
 FIELD    diff_id,	 5,   %d,     Diff ID
 FIELD    label,	 	 5,   %s,     Label
+FIELD    data_group, 	 5,   %s,     Data Grp
 FIELD    inverse,	 5,   %d,     Inverse
 FIELD    state,		 5,   %s,     State
Index: /branches/pap/ippMonitor/def/magicTrees.d
===================================================================
--- /branches/pap/ippMonitor/def/magicTrees.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/magicTrees.d	(revision 28003)
@@ -11,4 +11,5 @@
 FIELD    magicRun.diff_id,	 5,   %d,     Diff ID
 FIELD    magicRun.label, 	 5,   %s,     Label
+FIELD    magicRun.data_group, 	 5,   %s,     data grp
 FIELD    magicRun.inverse,	 5,   %d,     Inverse
 FIELD    magicRun.state,	 5,   %s,     State
Index: /branches/pap/ippMonitor/def/stackFailedSkyfile.d
===================================================================
--- /branches/pap/ippMonitor/def/stackFailedSkyfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/stackFailedSkyfile.d	(revision 28003)
@@ -16,4 +16,6 @@
 FIELD stackRun.skycell_id,          5, %s,     Skycell ID
 FIELD stackRun.label,    	    5, %s,     Label
+FIELD stackRun.data_group,    	    5, %s,     data grp
+FIELD stackRun.dist_group,    	    5, %s,     dist grp
 FIELD stackRun.filter,    	    5, %s,     Filter
 FIELD stackRun.tess_id,    	    5, %s,     Tess ID
Index: /branches/pap/ippMonitor/def/stackInputSkyfile.d
===================================================================
--- /branches/pap/ippMonitor/def/stackInputSkyfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/stackInputSkyfile.d	(revision 28003)
@@ -34,4 +34,6 @@
 FIELD stackRun.state,    	    7, %s,     State
 FIELD stackRun.label,    	    7, %s,     Label
+FIELD stackRun.data_group,    	    7, %s,     data grp
+FIELD stackRun.dist_group,    	    7, %s,     dist grp
 FIELD rawExp.telescope,      	   10, %s,     Telescope
 FIELD rawExp.camera,         	   10, %s,     Camera
Index: /branches/pap/ippMonitor/def/stackProcessedSkyfile.d
===================================================================
--- /branches/pap/ippMonitor/def/stackProcessedSkyfile.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/stackProcessedSkyfile.d	(revision 28003)
@@ -17,4 +17,6 @@
 FIELD stackRun.skycell_id,          5, %s,     Skycell ID
 FIELD stackRun.label,    	    5, %s,     Label
+FIELD stackRun.data_group,    	    5, %s,     data grp
+FIELD stackRun.dist_group,    	    5, %s,     dist grp
 FIELD stackRun.filter,    	    5, %s,     Filter
 FIELD stackRun.tess_id,    	    5, %s,     Tess ID
Index: /branches/pap/ippMonitor/def/stackProcessedSkyfile_Images.d
===================================================================
--- /branches/pap/ippMonitor/def/stackProcessedSkyfile_Images.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/stackProcessedSkyfile_Images.d	(revision 28003)
@@ -21,4 +21,6 @@
 FIELD stackRun.skycell_id,          5, %s,     Skycell ID
 FIELD stackRun.label,    	    5, %s,     Label
+FIELD stackRun.data_group,    	    5, %s,     data grp
+FIELD stackRun.dist_group,    	    5, %s,     dist grp
 FIELD *,    	                    8, %s,     image,         image=JPEG2, stackProcessedSkyfile_Images.php,  ARG7
 FIELD stackRun.filter,    	    5, %s,     Filter
Index: /branches/pap/ippMonitor/def/stackRun.d
===================================================================
--- /branches/pap/ippMonitor/def/stackRun.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/stackRun.d	(revision 28003)
@@ -9,4 +9,6 @@
 FIELD    filter,	 5,   %s,     Filter
 FIELD    label,	 	 5,   %s,     Label
+FIELD    data_group, 	 5,   %s,     Data grp
+FIELD    dist_group,	 5,   %s,     Dist grp
 FIELD    tess_id,	 5,   %s,     Tess ID
 FIELD    state,		 5,   %s,     State
Index: /branches/pap/ippMonitor/def/warpFailedSkyfiles.d
===================================================================
--- /branches/pap/ippMonitor/def/warpFailedSkyfiles.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpFailedSkyfiles.d	(revision 28003)
@@ -36,4 +36,6 @@
 FIELD warpRun.state,    	  7, %s,     state,        value,  warpFailedSkyfiles.php,  ARG7
 FIELD warpRun.label,    	  7, %s,     label
+FIELD warpRun.data_group,    	  7, %s,     data grp
+FIELD warpRun.dist_group,    	  7, %s,     dist grp
 FIELD warpSkyfile.tess_id,    	 10, %s,     tess
 FIELD warpSkyfile.good_frac,  	  5, %s,     good_frac
Index: /branches/pap/ippMonitor/def/warpProcessedSkyfiles.d
===================================================================
--- /branches/pap/ippMonitor/def/warpProcessedSkyfiles.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpProcessedSkyfiles.d	(revision 28003)
@@ -39,4 +39,6 @@
 FIELD warpRun.state,    	  7, %s,     state,        value,  warpProcessedSkyfiles.php, ARG7
 FIELD warpRun.label,    	  7, %s,     label,        value
+FIELD warpRun.data_group,    	  7, %s,     data grp
+FIELD warpRun.dist_group,    	  7, %s,     dist grp
 FIELD warpSkyfile.tess_id,    	 10, %s,     tess
 FIELD warpSkyfile.good_frac,  	  5, %s,     good_frac
Index: /branches/pap/ippMonitor/def/warpProcessedSkyfiles_Images.d
===================================================================
--- /branches/pap/ippMonitor/def/warpProcessedSkyfiles_Images.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpProcessedSkyfiles_Images.d	(revision 28003)
@@ -43,4 +43,6 @@
 FIELD warpRun.state,    	  7, %s,     state,        value,  warpProcessedSkyfiles.php, ARG7
 FIELD warpRun.label,    	  7, %s,     label,        value
+FIELD warpRun.data_group,    	  7, %s,     label,        data grp
+FIELD warpRun.dist_group,    	  7, %s,     label,        dist grp
 FIELD warpSkyfile.tess_id,    	 10, %s,     tess
 FIELD warpSkyfile.good_frac,  	  5, %s,     good_frac
Index: /branches/pap/ippMonitor/def/warpSkycellMap.d
===================================================================
--- /branches/pap/ippMonitor/def/warpSkycellMap.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpSkycellMap.d	(revision 28003)
@@ -20,4 +20,6 @@
 FIELD    warpRun.state,               5,    %s,     State
 FIELD    warpRun.label,               5,    %s,     Label
+FIELD    warpRun.data_group,               5,    %s,     data grp
+FIELD    warpRun.dist_group,               5,    %s,     dist grp
 FIELD    warpSkyCellMap.skycell_id,   5,    %s,     Skycell ID
 FIELD    warpSkyCellMap.tess_id,      5,    %s,     Tessellation ID
Index: /branches/pap/ippMonitor/def/warpStageExp.d
===================================================================
--- /branches/pap/ippMonitor/def/warpStageExp.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpStageExp.d	(revision 28003)
@@ -27,4 +27,6 @@
 FIELD warpRun.state,    	 7, %s,     state
 FIELD warpRun.label,    	 7, %s,     label
+FIELD warpRun.data_group,    	 7, %s,     data grp
+FIELD warpRun.dist_group,    	 7, %s,     dist grp
 FIELD rawExp.telescope,      	10, %s,     Telescope
 FIELD rawExp.camera,         	10, %s,     Camera
Index: /branches/pap/ippMonitor/def/warpStageSkyfileInputs.d
===================================================================
--- /branches/pap/ippMonitor/def/warpStageSkyfileInputs.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpStageSkyfileInputs.d	(revision 28003)
@@ -40,4 +40,6 @@
 FIELD warpRun.state,    	  7, %s,     state
 FIELD warpRun.label,    	  7, %s,     label
+FIELD warpRun.data_group,    	  7, %s,     data grp
+FIELD warpRun.dist_group,    	  7, %s,     dist grp
 FIELD warpSkyCellMap.skycell_id, 10, %s,     skycell
 FIELD warpSkyCellMap.tess_id,    10, %s,     tess
Index: /branches/pap/ippMonitor/def/warpStageSkyfiles.d
===================================================================
--- /branches/pap/ippMonitor/def/warpStageSkyfiles.d	(revision 28002)
+++ /branches/pap/ippMonitor/def/warpStageSkyfiles.d	(revision 28003)
@@ -30,4 +30,6 @@
 FIELD warpRun.state,    	  7, %s,     state
 FIELD warpRun.label,    	  7, %s,     label
+FIELD warpRun.data_group,    	  7, %s,     data grp
+FIELD warpRun.dist_group,    	  7, %s,     dist grp
 FIELD warpSkyCellMap.tess_id,    10, %s,     tess
 FIELD warpSkyCellMap.fault,      10, %s,     fault
Index: /branches/pap/ippMonitor/raw/czartool.php
===================================================================
--- /branches/pap/ippMonitor/raw/czartool.php	(revision 28003)
+++ /branches/pap/ippMonitor/raw/czartool.php	(revision 28003)
@@ -0,0 +1,315 @@
+<?php
+include 'ipp.php';
+include 'site.php';
+
+$ID = checkID ();
+
+// require an explicit project
+if (! $ID['proj']) { projectform ($ID); }
+
+$db = dbconnect($ID['proj']);
+
+if ($ID['menu']) {$myMenu = $ID['menu'];} 
+else {$myMenu = "ipp.imfiles.dat";}
+
+menu($myMenu, 'Czartool', 'ipp.css', $ID['link'], $ID['proj']);
+
+$pass = $ID['pass'];
+$proj = $ID['proj'];
+$menu = $ID['menu'];
+
+$userSelection = $_GET[label];
+
+if ($userSelection == "") {$userSelection = $_POST['state'];}
+if ($userSelection == "") {$userSelection = "new";}
+
+$debug = 0;
+
+$PATH = getenv("PATH");
+putenv("PATH=$BINDIR:$PATH");
+
+$LD_LIBRARY_PATH = getenv("LD_LIBRARY_PATH");
+putenv("LD_LIBRARY_PATH=$LIBDIR:$LD_LIBRARY_PATH");
+
+exec("getLabels.pl -s stdscience", $stdsLabels, $status);
+exec("getLabels.pl -s distribution", $distLabels, $status);
+
+if ($debug) {
+    echo "prog returned $status, and output:<br>";
+    for ($i = 0; $i < count($distLabels); $i++) { 
+        echo "$distLabels[$i]<br>";
+    }           
+}
+
+$states=array("full","new","drop","wait");
+$stages=array("chip","cam","fake","warp","stack","diff","magic","destreak","dist");
+$servers=array("addstar", "cleanup", "detrend", "distribution", "pstamp", "publishing", "registration", "replication", "stdscience", "summitcopy");
+$separator = "-----";
+// set up the form
+echo "<form action=\"czartool.php\" method=\"POST\">\n";
+echo "<select name=state >\n";
+echo "<option value=\"none\">Select one...</option>\n";
+echo "<option value=\"none\">$separator</option>\n";
+foreach ($states as &$state) {echo "<option value=\"$state\">'$state' for all labels</option>\n";}
+echo "<option value=\"none\">$separator</option>\n";
+echo "<option value=\"servers\">Check all pantasks servers</option>\n";
+foreach ($servers as &$server) {echo "<option value=\"$server\">Status for '$server' server</option>\n";}
+echo "<option value=\"none\">$separator</option>\n";
+foreach ($stdsLabels as &$label) {echo "<option value=\"$label\">$label</option>\n";}
+
+echo "</select>\n";
+echo "<input type=submit value=Go>\n";
+
+echo "<input type=\"hidden\" name=\"pass\" value=\"$pass\">\n";
+echo "<input type=\"hidden\" name=\"proj\" value=\"$proj\">\n";
+echo "<input type=\"hidden\" name=\"menu\" value=\"$menu\">\n";
+echo "</form>\n";
+
+
+$stateChosen = 0;
+foreach ($states as &$state) {
+
+    if ($userSelection == $state) {
+        showAllLabels($pass, $proj, $db, $stdsLabels, $distLabels, $stages, $states, $state); 
+        $stateChosen=1;
+        break;
+    }
+}
+
+$serverChosen = 0;
+foreach ($servers as &$server) {
+
+    if ($userSelection == $server) {
+        showServerStatus($server); 
+        $serverChosen=1;
+        break;
+    }
+}
+if (!$stateChosen && !$serverChosen) {
+
+    if ($userSelection == "servers") {showAllServerStatus($servers); }// TODO
+    elseif ($userSelection == $separator) {}
+    else { showOneLabel($pass, $proj, $db, $userSelection, $stages, $states);}
+
+}
+menu_end();
+
+###########################################################################
+#
+# Shows the status of the provided pantasks server 
+#
+###########################################################################
+function showServerStatus($server) {
+
+    echo "<p> Status for $server server </p>";
+
+    $results=array();
+    exec("getServerStatus.pl -s $server", $results, $status);
+
+    foreach ($results as &$line) {
+        echo "<pre>\n";
+        echo "$line\n";
+        echo "</pre>\n";
+
+    }
+
+}
+
+###########################################################################
+#
+# Checks the status of all the pantasks servers 
+#
+###########################################################################
+function showAllServerStatus($servers) {
+
+    echo "<p> Status for all pantasks servers </p>";
+
+    // set up table columns
+    $class = "list";
+    echo "<table class=list>\n";
+    echo "<tr><td></td>\n";
+    write_header_cell($class, "Server");
+    write_header_cell($class, "Alive?");
+    write_header_cell($class, "Scheduler running?");
+    echo "</tr>\n";
+
+    foreach ($servers as &$server) {
+
+        $results=array();
+        exec("checkServer.pl -s $server", $results, $status);
+
+        echo "<tr><td></td>\n";
+        write_table_cell($class, '%s', "", $server);
+        write_table_cell($class, '%s', "", $results[0]);
+        write_table_cell($class, '%s', "", $results[1]);
+        echo "</tr>\n";
+    }
+
+    echo "</table>\n";
+}
+
+
+###########################################################################
+#
+# Checks one label and prints results in a table
+#
+###########################################################################
+function showOneLabel($pass, $proj, $db, $label, $stages, $states) {
+
+    echo "<p> Current status for label '$label' (any faults are shown in parentheses) </p>";
+
+    // set up table columns
+    $class = "list";
+    echo "<table class=list>\n";
+    echo "<tr><td></td>\n";
+    write_header_cell($class, "state");
+    foreach ($stages as &$stage) {write_header_cell($class, $stage);}
+    echo "</tr>\n";
+
+    // write rows
+    foreach ($states as &$state) {
+
+        $link = "czartool.php?pass=" . $pass . "&proj=" . $proj . "&label=" . $state;
+
+        echo "<tr><td></td>\n";
+        write_table_cell($class, '%s', $link, $state);
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"chipRun", $state, "chip"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"camRun", $state, "cam"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"fakeRun", $state, "fake"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"warpRun", $state, "warp"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"stackRun", $state, "stack"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"diffRun", $state, "diff"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"magicRun", $state, "magic"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"magicDSRun", $state, "magicDS"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $label,"distRun", $state, "dist"));
+        echo "</tr>\n";
+    }
+
+    echo "</table>\n";
+}
+
+###########################################################################
+#
+# Creates table for all labels showing all stages for given 'state'
+#
+###########################################################################
+function showAllLabels($pass, $proj, $db, $stdsLabels, $distLabels, $stages, $states, $selectedState) {
+
+    echo "<p> Current stdscience labels for '$selectedState' (any faults are shown in parentheses)</p>";
+
+    // set up table columns
+    $class = "list";
+    echo "<table class=list>\n";
+    echo "<tr><td></td>\n";
+    write_header_cell($class, "label");
+    write_header_cell($class, "distributing?");
+    //    echo "<td class=\"$class\"><a href=\"$link\"> $myValue </a></td>\n";
+    //    echo "<th class=\"$class\"><a href=\"czartool.php\">label</th>\n";
+
+    foreach ($stages as &$stage) {write_header_cell($class, $stage);}
+    //foreach ($stages as &$stage) {
+
+    //  $link = "czartool.php?pass=" . $pass . "&proj=" . $proj . "&label=" . $stage;
+    // echo "<th class=\"$class\"><a href=\"$link\">$stage</th>\n";
+    // }
+
+    echo "</tr>\n";
+
+    // write rows
+    foreach ($stdsLabels as &$stdsLabel) {
+
+        $distributing = false;
+        foreach ($distLabels as &$distLabel) {
+
+            if ($stdsLabel == $distLabel) { $distributing = true; break;}
+        }
+
+
+        // create link to label summary page for each label
+        $link = "czartool.php?pass=" . $pass . "&proj=" . $proj . "&label=" . $stdsLabel;
+
+        echo "<tr><td></td>\n";
+        write_table_cell($class, '%s', $link, $stdsLabel);
+        write_table_cell($class, '%s', "", $distributing ? "yes" : "NO");
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"chipRun", $selectedState, "chip"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"camRun", $selectedState, "cam"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"fakeRun", $selectedState, "fake"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"warpRun", $selectedState, "warp"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"stackRun", $selectedState, "stack"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"diffRun", $selectedState, "diff"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"magicRun", $selectedState, "magic"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"magicDSRun", $selectedState, "magicDS"));
+        write_table_cell($class, '%s', "", getStateAndFaults($db, $stdsLabel,"distRun", $selectedState, "dist"));
+        echo "</tr>\n";
+    }
+
+    echo "</table>\n";
+}
+
+###########################################################################
+#
+# Returns state and fault-count (if new) as a string
+#
+###########################################################################
+function getStateAndFaults($db, $label, $table, $state, $stage) {
+
+    $new = checkLabel($db, $label, $table, $state, $stage);
+
+    if ($state != "new") {return $new;}
+
+    $faults = countFaults($db, $label,$table,$stage);
+
+    if ($faults < 1) {return $new;}
+
+    return $new."(".$faults.")";
+}
+
+###########################################################################
+#
+# Returns count of exposures with this state for this label
+#
+###########################################################################
+function checkLabel($db, $label, $table, $state, $stage) {
+
+    $sql = "SELECT COUNT(state) FROM $table WHERE label LIKE '$label' AND state = '$state'";
+    if ($debug) {echo "$sql<br>";}
+
+    $qry = $db->query($sql);
+    if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}
+    if (!$qry->fetchInto($row)) {echo "<b>error with $sql </b><br>\n";}
+    return $row[0];
+}
+
+###########################################################################
+#
+# Returns count of faults for this stage and label
+#
+###########################################################################
+function countFaults($db, $label, $table, $stage) {
+
+    $joinTable = 0;
+    $id = $stage."_id";
+
+    if ($stage == "chip") {$joinTable="chipProcessedImfile";}
+    elseif ($stage == "cam") {$joinTable="camProcessedExp";}
+    elseif ($stage == "fake") {$joinTable="fakeProcessedImfile";}
+    elseif ($stage == "warp") {$joinTable="warpSkyfile";}
+    elseif ($stage == "stack") {$joinTable="stackSumSkyfile";}
+    elseif ($stage == "diff") {$joinTable="diffSkyfile";}
+    elseif ($stage == "magic") {$joinTable="magicNodeResult";}
+    elseif ($stage == "magicDS") {$id = "magic_ds_id"; $joinTable="magicDSFile";}
+    elseif ($stage == "dist") {$joinTable="distComponent";}
+    else {return -1;}
+
+    $faultCol =  $joinTable.".fault";
+
+    $sql = "SELECT COUNT(DISTINCT $id) FROM $table JOIN $joinTable USING ($id) WHERE label LIKE '$label' AND $faultCol != 0 AND $table.state = 'new'";
+    if ($debug) {echo "$sql<br>";}
+
+    $qry = $db->query($sql);
+    if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}
+    if (!$qry->fetchInto($row)) {echo "<b>error with $sql </b><br>\n";}
+    return $row[0];
+}
+?>
+
Index: /branches/pap/ippMonitor/raw/ipp.imfiles.dat
===================================================================
--- /branches/pap/ippMonitor/raw/ipp.imfiles.dat	(revision 28002)
+++ /branches/pap/ippMonitor/raw/ipp.imfiles.dat	(revision 28003)
@@ -21,2 +21,4 @@
 menutop   | menutop      | link    | simple plot - chip           | simplePlot.php
 menutop   | menutop      | link    | simple plot - cam            | simplePlotcam.php
+menutop   | menutop      | link    | czartool                     | czartool.php
+
Index: /branches/pap/ippMonitor/scripts/checkServer.pl
===================================================================
--- /branches/pap/ippMonitor/scripts/checkServer.pl	(revision 28003)
+++ /branches/pap/ippMonitor/scripts/checkServer.pl	(revision 28003)
@@ -0,0 +1,25 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+use Getopt::Long;
+
+my $server = undef;
+GetOptions ("server|s=s" => \$server);
+
+my @cmdOut = `echo "status ;quit" | pantasks_client -c ~ipp/$server/ptolemy.rc 2>&1`;
+my $line;
+my $foundStatus = 0;
+my $isRunning = 0;
+foreach $line (@cmdOut) {
+
+    chomp($line);
+    if ($line =~ m/Scheduler is stopped/) {$isRunning = 0; $foundStatus=1;last;}
+    if ($line =~ m/Scheduler is running/) {$isRunning = 1; $foundStatus=1;last;}
+    if ($line =~ m/Task Staus/) {last;}
+
+}
+
+($foundStatus) ? print "yes\n" : print "no\n";
+($isRunning) ? print "yes\n" : print "no\n";
+
Index: /branches/pap/ippMonitor/scripts/getLabels.pl
===================================================================
--- /branches/pap/ippMonitor/scripts/getLabels.pl	(revision 28003)
+++ /branches/pap/ippMonitor/scripts/getLabels.pl	(revision 28003)
@@ -0,0 +1,25 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+use Getopt::Long;
+
+my $server = undef;
+GetOptions ("server|s=s" => \$server);
+
+my @cmdOut = `echo "show.labels;quit" | pantasks_client -c ~ipp/$server/ptolemy.rc 2>&1`;
+my $line;
+my $passedHeader=0;
+foreach $line (@cmdOut) {
+
+    chomp($line);
+    if ($line =~ m/pantasks:\s+(.*)/) {
+  
+        # HACK to get around 'dummy' label in stdscience
+        if ($1 !~ m/.*dummy.*/) {print "$1\n"};
+        $passedHeader=1; 
+        next;
+    }
+
+    if ($passedHeader){print "$line\n";}
+}
Index: /branches/pap/ippMonitor/scripts/getServerStatus.pl
===================================================================
--- /branches/pap/ippMonitor/scripts/getServerStatus.pl	(revision 28003)
+++ /branches/pap/ippMonitor/scripts/getServerStatus.pl	(revision 28003)
@@ -0,0 +1,18 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+use Getopt::Long;
+
+my $server = undef;
+GetOptions ("server|s=s" => \$server);
+
+my @cmdOut = `echo "status;quit" | pantasks_client -c ~ipp/$server/ptolemy.rc 2>&1`;
+my $line;
+my $passedHeader=0;
+foreach $line (@cmdOut) {
+
+    chomp($line);
+    if ($line =~ m/.*Task Status.*/) {$passedHeader=1;next;}
+    if ($passedHeader){print "$line<br>";}
+}
Index: /branches/pap/ippScripts/scripts/addstar_run.pl
===================================================================
--- /branches/pap/ippScripts/scripts/addstar_run.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/addstar_run.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/automate_stacks.pl
===================================================================
--- /branches/pap/ippScripts/scripts/automate_stacks.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/automate_stacks.pl	(revision 28003)
@@ -56,5 +56,5 @@
 # Grab options
 my ( $date, $camera, $dbname, $logfile, $verbose, $manual);
-my ( $help, $isburning, $force_stack_count, $test_mode, $this_target_only, $this_filter_only);
+my ( $help, $isburning, $force_stack_count, $test_mode, $this_target_only, $this_filter_only, $check_mode);
 my ( $check_registration, $define_burntool, $queue_burntool, $check_chips, $queue_chips);
 my ( $check_stacks, $queue_stacks, $check_diffs, $queue_diffs, $clean_old);
@@ -67,6 +67,8 @@
     'logfile=s'            => \$logfile,
     'verbose'              => \$verbose,
+    'debug'                => \$debug,
     'isburning'            => \$isburning,
     'force_stack_count'    => \$force_stack_count,
+    'check'                => \$check_mode,
     'test_mode'            => \$test_mode,
     'this_target_only=s'   => \$this_target_only,
@@ -115,5 +117,5 @@
     defined $queue_chips or defined $queue_stacks or
     defined $check_chips or defined $check_stacks or
-    defined $test_mode or defined $clean_old;
+    defined $test_mode or defined $clean_old or defined $check_mode;
 
 # Configurable parameters from our config file.
@@ -126,6 +128,7 @@
 my %stackable_list = ();
 my %reduction_class = ();
-my $retention_time = 9000;
-
+my %clean_commands = ();
+my %clean_retention = ();
+my %noclean_list = ();
 # Grab the configuration data.
 my $conf_cmd = "$ppConfigDump -dump-recipe NIGHTLY_SCIENCE -";
@@ -140,7 +143,22 @@
 my $metadata = $mdcParser->parse(join "", @$stdout_buf);
 foreach my $entry (@{ $metadata }) {
-    if (${ $entry }{name} eq 'RETENTION_TIME') {
-        $retention_time = ${ $entry }{value};
-    }
+    if (@{ $entry }{name} eq 'CLEAN_MODES') {
+	my @mode_data = @{ ${ $entry }{value} };
+	my $this_mode = '';
+	foreach my $mentry (@mode_data) {
+	    if (${ $mentry }{name} eq 'MODE') {
+		$this_mode = ${ $mentry }{value};
+	    }
+	    elsif (${ $mentry }{name} eq 'COMMAND') {
+		$clean_commands{$this_mode} = ${ $mentry }{value};
+	    }
+	    elsif (${ $mentry }{name} eq 'RETENTION_TIME') {
+		$clean_retention{$this_mode} = ${ $mentry }{value};
+	    }
+	}
+    }
+#    if (${ $entry }{name} eq 'RETENTION_TIME') {
+#        $retention_time = ${ $entry }{value};
+#    }
     elsif (${ $entry }{name} eq 'FILTERS') {
         push @filter_list, ${ $entry }{value};
@@ -172,4 +190,7 @@
 		$reduction_class{$this_target} = ${ $tentry }{value};
 	    }
+	    elsif (${ $tentry }{name} eq 'NOCLEAN') {
+		$noclean_list{$this_target} = ${ $tentry }{value};
+	    }
         }
     }
@@ -217,11 +238,22 @@
 if (defined($test_mode)) {
     $debug = 1;
-}
-
-if (defined($check_registration) || defined($test_mode)) {
+    my $z;
+    foreach $z (@target_list) {
+	print "TARGET: $z $tessID_list{$z} $obsmode_list{$z} $object_list{$z} $comment_list{$z} $stackable_list{$z} $reduction_class{$z}\n";
+    }
+    foreach $z (@filter_list) {
+	print "FILTER: $z\n";
+    }
+    foreach $z (keys (%clean_commands)) {
+	print "CLEAN: $z $clean_commands{$z} $clean_retention{$z}\n";
+    }
+    
+}
+
+if (defined($check_registration) || defined($test_mode) || defined($check_mode)) {
     $metadata_out{nsState} = 'NEW';
     my ($Nsummit_exp,$Nfaults) = check_summit_copy($date);
     return_metadata($date);
-    unless (defined($test_mode)) { exit(0); }
+    unless (defined($test_mode) || defined($check_mode)) { exit(0); }
 }
 if (defined($define_burntool) || defined($test_mode)) {
@@ -236,5 +268,5 @@
     unless (defined($test_mode)) { exit(0); }
 }
-if (defined($check_chips) || defined($test_mode)) {
+if (defined($check_chips) || defined($test_mode) || defined($check_mode)) {
     $metadata_out{nsState} = 'QUEUECHIPS';
     &execute_chips($date,"pretend");
@@ -243,5 +275,5 @@
     }
     return_metadata($date);
-    unless (defined($test_mode)) { exit(0); }
+    unless (defined($test_mode) || defined($check_mode)) { exit(0); }
 }
 if (defined($queue_chips)) {
@@ -251,5 +283,5 @@
     exit(0);
 }
-if (defined($check_stacks) || defined($test_mode)) {
+if (defined($check_stacks) || defined($test_mode) || defined($check_mode)) {
     $metadata_out{nsState} = 'TOWARP';
     &execute_stacks($date,"pretend");
@@ -258,9 +290,12 @@
     }
     return_metadata($date);
-    unless (defined($test_mode)) { exit(0); }
+    unless (defined($test_mode) || defined($check_mode)) { exit(0); }
 }
 if (defined($queue_stacks)) {
     $metadata_out{nsState} = 'STACKING';
     &execute_stacks($date);
+    if ($metadata_out{nsState} eq 'QUEUESTACKING') {
+	$metadata_out{nsState} = 'STACKING_POSSIBLE_ERROR';
+    }
     return_metadata($date);
     exit(0);
@@ -420,8 +455,8 @@
     }
 
-    if ($#{ $stderr_buf } > -1) {
-        $metadata_out{nsState} = 'ERROR';
-        return(1);
-    }
+#    if ($#{ $stderr_buf } > -1) {
+#        $metadata_out{nsState} = 'ERROR';
+#        return(1);
+#    }
 
     my $N = 0;
@@ -429,6 +464,9 @@
     foreach my $row (@burntool_entries) {
         my ($trash,$start,$end);
-        ($trash,$trash,$start,$end) = (split /\s+/,$row);
-
+        (undef,$trash,$start,$end) = (split /\s+/,$row);
+	if ($trash ne 'burntool') {
+	    $metadata_out{nsState} = 'ERROR';
+	    return(1);
+	}
         for (my $class_counter = 0; $class_counter < 60; $class_counter++) {
             $metadata_out{"bt${N}Begin"} = $start;
@@ -650,5 +688,5 @@
     my @input_exposures = split /\n/, (join '', @$stdout_buf);
     foreach my $entry (@input_exposures) {
-        my ($skycell, @trash) = split /\s+/, $entry;
+        my ($warp_tess_id,$skycell, @trash) = split /\s+/, $entry;
         @trash = verify_uniqueness_stack($skycell,$date,$target,$filter);
         $Nalready += $trash[0];
@@ -681,21 +719,32 @@
                 my ($Nexposures,$NprocChips,$NprocWarps,$Nalready) = pre_stack_queue($date,$target,$filter);
                 if ((!defined($force_stack_count))&&($NprocChips != $NprocWarps)) { # This makes me sad. :(
-                    # print STDERR "execute_stacks: Target $target on $date is not fully processed. ($NprocChips $NprocWarps)\n";
+		    if ($debug == 1) {
+			print STDERR "execute_stacks: Target $target on $date is not fully processed. ($NprocChips $NprocWarps)\n";
+		    }
                     $metadata_out{nsState} = 'FORCETOWARP';
                     next;
                 }
                 if ($Nexposures == 0) {
-                    # print STDERR "execute_stacks: Target $target in filter $filter on $date has no exposures.\n";
+		    if ($debug == 1) {
+			print STDERR "execute_stacks: Target $target in filter $filter on $date has no exposures.\n";
+		    }
                     next;
                 }
                 if ($Nalready != 0) {
-                    # print STDERR "execute_stacks: Not queueing $target in filter $filter on $date due to already existing stacks.\n";
+		    if ($debug == 1) {
+			print STDERR "execute_stacks: Not queueing $target in filter $filter on $date due to already existing stacks.\n";
+		    }
+		    unless ($metadata_out{nsState} eq 'FORCETOWARP') {
+			$metadata_out{nsState} = 'STACKING';
+		    }
                     next;
                 }
-                unless ($metadata_out{nsState} eq 'FORCETOWARP') {
+                unless (($metadata_out{nsState} eq 'FORCETOWARP')||($metadata_out{nsState} eq 'STACKING')) {
                     $metadata_out{nsState} = 'QUEUESTACKS';
                 }
                 unless(defined($pretend)) {
-                    # print STDERR "execute_stacks: Target $target in filter $filter on $date has exposures and will be queued.\n";
+		    if ($debug == 1) {
+			print STDERR "execute_stacks: Target $target in filter $filter on $date has exposures and will be queued.\n";
+		    }
                     stack_queue($date,$target,$filter);
                 }
@@ -716,4 +765,8 @@
     my $date = shift;
     my $target = shift;
+    my $mode = shift;
+
+    my $command = $clean_commands{$mode};
+    my $retention_time = $clean_retention{$mode};
 
     my ($year,$month,$day) = split /-/,$date;
@@ -725,6 +778,6 @@
 
     my ($label,$workdir,$obs_mode,$object,$comment,$tess_id,$dist_group,$data_group,$reduction) = get_tool_parameters($cleaning_date,$target);
-
-    my $args .= " -dbname gpc1 -updaterun -set_state goto_cleaned -state full -data_group $data_group ";
+    my $args = $command;
+    $args .= " -dbname gpc1 -updaterun -set_state goto_cleaned -state full -set_label goto_cleaned -label $label -data_group $data_group ";
     if ($debug == 1) {
         $args .= ' -pretend ';
@@ -737,29 +790,22 @@
     my $pretend = shift;
 
-    foreach my $target (@target_list) {
-        my ($cleaning_date,$args) = construct_cleantool_args($date,$target);
-
-        my $command = $chiptool . $args;
-        print STDERR "$command\n";
-        if (!(defined($pretend) || $debug == 1)) {
+    foreach my $mode (keys (%clean_commands)) {
+	foreach my $target (@target_list) {
+	    if (exists($noclean_list{$target})) {
+		next;
+	    }
+	    my ($cleaning_date,$command) = construct_cleantool_args($date,$target,$mode);
+
+	    print STDERR "$command\n";
+	    if (!(defined($pretend) || $debug == 1)) {
 #           print STDERR "BEAR IS DRIVING!?\n";
-            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run ( command => $command, verbose => $verbose );
-            unless ($success) {
-                $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-                &my_die("Unable to perform stacktool: $error_code", 0,0,$date, $PS_EXIT_SYS_ERROR);
-            }
-        }
-        $command = $warptool . $args;
-        print STDERR "$command\n";
-        if (!(defined($pretend) || $debug == 1)) {
-#           print STDERR "BEAR IS DRIVING $pretend $debug!?\n";
-            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run ( command => $command, verbose => $verbose );
-            unless ($success) {
-                $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-                &my_die("Unable to perform stacktool: $error_code", 0,0,$date, $PS_EXIT_SYS_ERROR);
-            }
-        }
+		my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+		    run ( command => $command, verbose => $verbose );
+		unless ($success) {
+		    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+		    &my_die("Unable to perform stacktool: $error_code", 0,0,$date, $PS_EXIT_SYS_ERROR);
+		}
+	    }
+	}
     }
     return(0);
Index: /branches/pap/ippScripts/scripts/calibrate_dvo.pl
===================================================================
--- /branches/pap/ippScripts/scripts/calibrate_dvo.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/calibrate_dvo.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/camera_exp.pl
===================================================================
--- /branches/pap/ippScripts/scripts/camera_exp.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/camera_exp.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/chip_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/chip_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/chip_imfile.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/detrend_correct_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_correct_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_correct_imfile.pl	(revision 28003)
@@ -8,7 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
-print "command: @ARGV\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_norm_apply.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_norm_apply.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_norm_apply.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_norm_calc.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_norm_calc.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_norm_calc.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -56,5 +57,5 @@
 
 # force det_type to be upper-case in this script
-my $det_type = uc($det_type);
+$det_type = uc($det_type);
 
 my $ipprc = PS::IPP::Config->new() or my_die( "Unable to set up", $det_id, $iter, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
Index: /branches/pap/ippScripts/scripts/detrend_norm_exp.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_norm_exp.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_norm_exp.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_process_exp.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_process_exp.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_process_exp.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_process_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_process_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_process_imfile.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_reject_exp.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_reject_exp.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_reject_exp.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_resid_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_resid_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_resid_imfile.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/detrend_stack.pl
===================================================================
--- /branches/pap/ippScripts/scripts/detrend_stack.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/detrend_stack.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/diff_skycell.pl
===================================================================
--- /branches/pap/ippScripts/scripts/diff_skycell.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/diff_skycell.pl	(revision 28003)
@@ -7,6 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
@@ -398,8 +399,8 @@
             $command .= " -hostname $host" if defined $host;
             $command .= " -path_base $outroot" if defined $outroot;
-            $command .= " -dbname $dbname" if defined $dbname;
         } else {
             $command .= " -updatediffskyfile";
         }
+        $command .= " -dbname $dbname" if defined $dbname;
         run(command => $command, verbose => $verbose);
     }
Index: /branches/pap/ippScripts/scripts/dist_advancerun.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dist_advancerun.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dist_advancerun.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -174,10 +175,10 @@
         }
         &my_die("unable to find path",  $dist_id, $PS_EXIT_UNKNOWN_ERROR) if !$path;
-        my $component_dir = find_componentdir($destdir, $path); 
+        my $component_dir = find_componentdir($destdir, $path);
 #        print MANIFEST "$component METADATA\n";
         print MANIFEST "\t" , "$component", "\tSTR\t", $component_dir, "\n";
     }
     print MANIFEST "END\n\n";
-    close MANIFEST or 
+    close MANIFEST or
         &my_die("Unable to close dirinfo file $dirinfo",  $dist_id, $PS_EXIT_UNKNOWN_ERROR);
 }
Index: /branches/pap/ippScripts/scripts/dist_bundle.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dist_bundle.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dist_bundle.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 # print "\n\n";
-# print "Starting script $0 on $host\n\n";
+# print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -115,5 +116,5 @@
 
 # Get the list of data products for this component
-# note: We my_die in get_file_list if something goes wrong. 
+# note: We my_die in get_file_list if something goes wrong.
 
 my $file_list = get_file_list($stage, $component, $path_base, $clean);
@@ -193,5 +194,5 @@
     $num_files++;
     if ($image_type && $nan_masked_pixels) {
-        # save the 
+        # save the
         if ($image_type eq 'image') {
             $image = $file_name;
@@ -222,5 +223,5 @@
     # One last check as to whether magic has been applied to the inputs
 
-    # Note: the sql for disttool -pendingcomponent won't select a component that 
+    # Note: the sql for disttool -pendingcomponent won't select a component that
     # requires magic and hasn't been magicked, but we check again here
 
@@ -327,5 +328,5 @@
 ### Pau.
 
-# return the image type (image, mask, or variance) if this file rule refers to 
+# return the image type (image, mask, or variance) if this file rule refers to
 # one of the big fits files that are not included in a clean distribution
 sub get_image_type {
@@ -360,5 +361,5 @@
 sub open_with_retries {
     my $name = shift;
-    
+
     my $tries = 1;
     my $max_tries = 5;
@@ -372,5 +373,5 @@
         }
     }
-    
+
     &my_die("failed to open $name after $max_tries tries\n", $component,
                     $PS_EXIT_DATA_ERROR) if (!$opened);
Index: /branches/pap/ippScripts/scripts/dist_cleanup.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dist_cleanup.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dist_cleanup.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/dist_component.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dist_component.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dist_component.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/dist_defineruns.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dist_defineruns.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dist_defineruns.pl	(revision 28003)
@@ -11,6 +11,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/dist_make_fileset.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dist_make_fileset.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dist_make_fileset.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -46,5 +47,5 @@
            'dist_id=s'      => \$dist_id,    # distribution run identifier
            'dist_dir=s'     => \$dist_dir,   # directory containing dist run outputs
-           'target_id=s'    => \$target_id,  # 
+           'target_id=s'    => \$target_id,  #
            'stage=s'        => \$stage,      # raw, chip, camera, fake, warp, stack, or diff
            'stage_id=s'     => \$stage_id,   # exp_id, chip_id, etc.
@@ -209,5 +210,5 @@
     my $dsn = "DBI:mysql:host=$dbserver;database=$dbname";
 
-    my $dbh = DBI->connect($dsn, $dbuser, $dbpassword) 
+    my $dbh = DBI->connect($dsn, $dbuser, $dbpassword)
         or die "Cannot connect to database.\n";
 
@@ -227,10 +228,10 @@
 
     #
-    # we are a long ways away from the rawExp in the pipeline. Rather than do some 
+    # we are a long ways away from the rawExp in the pipeline. Rather than do some
     # very long joins in disttool, we look up the exp_name in the database using DBI
     #
     my $dbh = getDBHandle($ipprc, $dbname);
 
-    my $query; 
+    my $query;
 
     if ($stage eq 'raw') {
Index: /branches/pap/ippScripts/scripts/dqstats_bundle.pl
===================================================================
--- /branches/pap/ippScripts/scripts/dqstats_bundle.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/dqstats_bundle.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
@@ -37,30 +38,30 @@
 my ( $dqstats_id, $camera, $uri, $dbname, $verbose, $no_update, $no_op, $redirect, $save_temps);
 GetOptions(
-	   'dqstats_id=s'    => \$dqstats_id, # dqstatsrun ID
-	   'camera|c=s'      => \$camera,  # camera
-	   'dbname|d=s'      => \$dbname,  # database name
-	   'uri=s'           => \$uri, # output file destination
-	   'verbose'         => \$verbose, # print to stdout
-	   'no-update'       => \$no_update, # Update the database
-	   'no-op'           => \$no_op,   # don't do the operations
-	   'redirect-output' => \$redirect, 
-	   'save-temps'      => \$save_temps, # save temporary files
-	   ) or pod2usage( 2 );
+           'dqstats_id=s'    => \$dqstats_id, # dqstatsrun ID
+           'camera|c=s'      => \$camera,  # camera
+           'dbname|d=s'      => \$dbname,  # database name
+           'uri=s'           => \$uri, # output file destination
+           'verbose'         => \$verbose, # print to stdout
+           'no-update'       => \$no_update, # Update the database
+           'no-op'           => \$no_op,   # don't do the operations
+           'redirect-output' => \$redirect,
+           'save-temps'      => \$save_temps, # save temporary files
+           ) or pod2usage( 2 );
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
 pod2usage( -msg => "Required options --dqstats_id --camera",
-	   -exitval => 3,
-	   ) unless
+           -exitval => 3,
+           ) unless
     defined $dqstats_id and
     defined $camera;
 
-my $ipprc = PS::IPP::Config->new( $camera ) 
+my $ipprc = PS::IPP::Config->new( $camera )
     or my_die( "Unable to set up", $dqstats_id, $PS_EXIT_CONFIG_ERROR ); # IPP config
-#my $logDest = $ipprc->filename("LOG.EXP", $uri) 
+#my $logDest = $ipprc->filename("LOG.EXP", $uri)
 #    or my_die("Missing entry from camera config", $dqstats_id, $PS_EXIT_CONFIG_ERROR);
 
 if ($redirect) {
-#    $ipprc->redirect_output($logDest) 
-#	or my_die( "Unable to redirect output", $dqstats_id, $PS_EXIT_SYS_ERROR );
+#    $ipprc->redirect_output($logDest)
+#       or my_die( "Unable to redirect output", $dqstats_id, $PS_EXIT_SYS_ERROR );
     print "\n\n";
     print "Starting script $0 on $host\n\n";
@@ -84,16 +85,16 @@
 unless ($no_op) {
     # This bit needs to make the bundle.
-    
+
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $bundle_command, verbose => $verbose);
+        run(command => $bundle_command, verbose => $verbose);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die("Unable to create the bundle.: $error_code", $dqstats_id, $error_code);
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to create the bundle.: $error_code", $dqstats_id, $error_code);
     }
-    
+
     # Parse stdout_buf to get output file name
     ## Begin partial
     my ($tempFile, $tempName) = tempfile( "/tmp/dqstats.XXXX",
-					  UNLINK => !$save_temps, SUFFIX => 'dsin' );
+                                          UNLINK => !$save_temps, SUFFIX => 'dsin' );
     print $tempFile $uri . '|||notset' . "\n";
 
@@ -102,10 +103,10 @@
     # It can't be that simple, can it? This should probably add a fault on failure.
     ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $register_cmd, verbose => $verbose);
+        run(command => $register_cmd, verbose => $verbose);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die("Unable to register the bundle.: $error_code", $dqstats_id, $error_code);
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to register the bundle.: $error_code", $dqstats_id, $error_code);
     }
-    
+
     # We no longer need the file generated by dqstatstool.
     unlink($uri);
@@ -118,9 +119,9 @@
     # This bit needs to set the database state to full
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $update_command, verbose => $verbose);
+        run(command => $update_command, verbose => $verbose);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	warn("Unable to add result to database: $error_code\n");
-	exit($error_code);
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        warn("Unable to add result to database: $error_code\n");
+        exit($error_code);
     }
 } else {
@@ -139,5 +140,5 @@
     carp($msg);
     if (defined $dqstats_id and not $no_update) {
-	# There is no fault handling, which may be a mistake. This is where a fault coding would be.
+        # There is no fault handling, which may be a mistake. This is where a fault coding would be.
 #         my $command = "$addtool -add_id $add_id";
 #         $command .= " -addprocessedexp";
Index: /branches/pap/ippScripts/scripts/fake_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/fake_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/fake_imfile.pl	(revision 28003)
@@ -24,6 +24,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/flatcorr_init.pl
===================================================================
--- /branches/pap/ippScripts/scripts/flatcorr_init.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/flatcorr_init.pl	(revision 28003)
@@ -1,5 +1,5 @@
 #!/usr/bin/env perl
 
-## USAGE:flatcorr_init.pl 
+## USAGE:flatcorr_init.pl
 ## given dbname, dvodb, filter, time range, camera, telescope, etc?
 ## select matching images and register as a new flatcorr run
@@ -24,6 +24,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -68,7 +69,7 @@
 my $caltool  = can_run('caltool')  or (warn "Can't find caltool"  and $missing_tools = 1);
 
-if ($missing_tools) { 
+if ($missing_tools) {
     warn ("Can't find required tools");
-    exit($PS_EXIT_CONFIG_ERROR); 
+    exit($PS_EXIT_CONFIG_ERROR);
 }
 
@@ -90,5 +91,5 @@
         cache_run(command => $command, verbose => 1);
 
-    unless ($success) { 
+    unless ($success) {
         $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
         &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RESORT", $status, $dbname);
@@ -99,15 +100,15 @@
 {
     foreach my $filter (@filters) {
-	my $command = "$relphot $filter";
-	$command .= "-D CATDIR $catdir";
-	$command .= "-region $RAs $RAe $DECs $DECe";
-
-	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    cache_run(command => $command, verbose => 1);
-
-	unless ($success) { 
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RELPHOT", $status, $dbname);
-	}
+        my $command = "$relphot $filter";
+        $command .= "-D CATDIR $catdir";
+        $command .= "-region $RAs $RAe $DECs $DECe";
+
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            cache_run(command => $command, verbose => 1);
+
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RELPHOT", $status, $dbname);
+        }
     }
 }
@@ -117,15 +118,15 @@
 if (0) {
     foreach my $filter (@filters) {
-	my $command = "$uniphot $filter";
-	$command .= "-D CATDIR $catdir";
-	$command .= "-region $RAs $RAe $DECs $DECe";
-
-	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    cache_run(command => $command, verbose => 1);
-
-	unless ($success) { 
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "UNIPHOT", $status, $dbname);
-	}
+        my $command = "$uniphot $filter";
+        $command .= "-D CATDIR $catdir";
+        $command .= "-region $RAs $RAe $DECs $DECe";
+
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            cache_run(command => $command, verbose => 1);
+
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "UNIPHOT", $status, $dbname);
+        }
     }
 }
@@ -137,9 +138,9 @@
 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	cache_run(command => $command, verbose => 1);
-
-    unless ($success) { 
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RELASTRO.OBJECTS", $status, $dbname);
+        cache_run(command => $command, verbose => 1);
+
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RELASTRO.OBJECTS", $status, $dbname);
     }
 }
@@ -151,9 +152,9 @@
 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	cache_run(command => $command, verbose => 1);
-
-    unless ($success) { 
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RELASTRO.IMAGES", $status, $dbname);
+        cache_run(command => $command, verbose => 1);
+
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die ("Unable to perform addstar -resort on region $region: $error_code", $dvo_id, $region, "RELASTRO.IMAGES", $status, $dbname);
     }
 }
@@ -185,14 +186,14 @@
     my $region    = shift;
     my $last_step = shift;
-    my $status 	  = shift;
-    my $dbname 	  = shift;
+    my $status    = shift;
+    my $dbname    = shift;
 
     carp($msg);
     if (defined $dvo_id && defined $region && defined $last_step && defined $status and not $no_update) {
         my $command = "$caltool -addcalrun";
-	$command .= " -dvo_id $dvo_id";
+        $command .= " -dvo_id $dvo_id";
         $command .= " -region $region";
-	$command .= " -last_step $last_step";
-	$command .= " -status $status";
+        $command .= " -last_step $last_step";
+        $command .= " -status $status";
         $command .= " -dbname $dbname" if defined $dbname;
         system ($command);
Index: /branches/pap/ippScripts/scripts/flatcorr_proc.pl
===================================================================
--- /branches/pap/ippScripts/scripts/flatcorr_proc.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/flatcorr_proc.pl	(revision 28003)
@@ -11,7 +11,7 @@
 # dvoMakeCorr -file outgrid.fits -ref ref.fits outcorr
 
-# dettool -register -det_type FLATCORR -filelevel (level) -workdir -inst, etc 
-
-# foreach $imfile () 
+# dettool -register -det_type FLATCORR -filelevel (level) -workdir -inst, etc
+
+# foreach $imfile ()
 #   dettool -register_imfile -uri, etc, etc
 
@@ -23,6 +23,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -74,11 +75,11 @@
 my $addstar     = can_run('addstar')      or (warn "Can't find addstar"      and $missing_tools = 1);
 my $dvoMakeCorr = can_run('dvoMakeCorr')  or (warn "Can't find dvoMakeCorr"  and $missing_tools = 1);
-my $detselect   = can_run('detselect') 	  or (warn "Can't find detselect"    and $missing_tools = 1);
-my $dettool     = can_run('dettool')   	  or (warn "Can't find dettool"      and $missing_tools = 1);
-my $flatcorr    = can_run('flatcorr')  	  or (warn "Can't find flatcorr"     and $missing_tools = 1);
-
-if ($missing_tools) { 
+my $detselect   = can_run('detselect')    or (warn "Can't find detselect"    and $missing_tools = 1);
+my $dettool     = can_run('dettool')      or (warn "Can't find dettool"      and $missing_tools = 1);
+my $flatcorr    = can_run('flatcorr')     or (warn "Can't find flatcorr"     and $missing_tools = 1);
+
+if ($missing_tools) {
     warn ("Can't find required tools");
-    exit($PS_EXIT_CONFIG_ERROR); 
+    exit($PS_EXIT_CONFIG_ERROR);
 }
 
@@ -95,5 +96,5 @@
 $ipprc->outroot_prepare($outcorr);
 
-if (not -e "$dvodb/flatcorr") { 
+if (not -e "$dvodb/flatcorr") {
     mkdir "$dvodb/flatcorr" or &my_die ("Unable to make output directory for relphot $dvodb/flatcorr", $corr_id, 3);
 }
@@ -104,17 +105,17 @@
 my ($DECs, $DECe) = split (",", $coords[1]);
 
-# Run addstar -resort to ensure the db is indexed 
+# Run addstar -resort to ensure the db is indexed
 # XXX addstar should be able to recognize and skip indexed tables
 {
-    my $command = "$addstar -resort"; 
+    my $command = "$addstar -resort";
     $command .= " -D CATDIR $dvodb";
     $command .= " -region $RAs $RAe $DECs $DECe";
 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => $verbose);
-
-    unless ($success) { 
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die ("Unable to perform addstar -resort for dvodb $dvodb on region $region: $error_code", $corr_id, $error_code);
+        run(command => $command, verbose => $verbose);
+
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die ("Unable to perform addstar -resort for dvodb $dvodb on region $region: $error_code", $corr_id, $error_code);
     }
 }
@@ -135,9 +136,9 @@
 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => $verbose);
-
-    unless ($success) { 
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die ("Unable to perform relphot -grid for dvodb $dvodb on region $region: $error_code", $corr_id, $error_code);
+        run(command => $command, verbose => $verbose);
+
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die ("Unable to perform relphot -grid for dvodb $dvodb on region $region: $error_code", $corr_id, $error_code);
     }
 }
@@ -176,5 +177,5 @@
 
 # Push the results into the database
-{ 
+{
     my $command = "$flatcorr -addprocess";
     $command .= " -corr_id $corr_id";
@@ -184,13 +185,13 @@
     unless ($no_update) {
 
-	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    run(command => $command, verbose => $verbose);
-	unless ($success) {
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    warn ("Unable to perform regtool -addprocessedimfile: $error_code");
-	    exit($error_code);
-	}
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            warn ("Unable to perform regtool -addprocessedimfile: $error_code");
+            exit($error_code);
+        }
     } else {
-	print "skipping command: $command\n";
+        print "skipping command: $command\n";
     }
 }
@@ -218,5 +219,5 @@
         &my_die("Unable to parse metadata list", $corr_id, $PS_EXIT_PROG_ERROR);
 
-    # check for existence 
+    # check for existence
     my $file = $$files[0];
     my $chip_id = $file->{chip_id};
@@ -228,5 +229,5 @@
 # flatcorr -inputimfile -chip_id $chip_id
 sub get_imfiles {
-    my $chip_id = shift; 
+    my $chip_id = shift;
 
     my $command = "$flatcorr -inputimfile";
@@ -273,9 +274,9 @@
 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => $verbose);
-
-    unless ($success) { 
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die ("Unable to register new detrend: $error_code", $corr_id, $PS_EXIT_PROG_ERROR);
+        run(command => $command, verbose => $verbose);
+
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die ("Unable to register new detrend: $error_code", $corr_id, $PS_EXIT_PROG_ERROR);
     }
 
@@ -298,39 +299,39 @@
 
     foreach my $file (@$files) {
-	# create the detrend correction for the imfiles based on the input imfiles
-	my $reffile = $file->{uri};
-	my $class_id = $file->{class_id};
-
-	my $uri = $ipprc->filename("DVOCORR.OUTPUT", $outcorr, $class_id);
-	unless ($uri) {
-	    &my_die ("Unable to find DVOCORR.OUTPUT in filerules", $corr_id, $PS_EXIT_PROG_ERROR);
-	}
-
-	my $command = "$dvoMakeCorr $outcorr";
-	$command .= " -file $outgrid.fits";
-	$command .= " -ref $reffile";
-
-	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    run(command => $command, verbose => $verbose);
-
-	unless ($success) { 
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    &my_die ("Unable to perform dvoMakeCorr: $error_code", $corr_id, $PS_EXIT_PROG_ERROR);
-	}
-
-	# register the detrend correction imfile
-	$command = "$dettool -register_detrend_imfile";
-	$command .= " -det_id $det_id";
-	$command .= " -class_id $class_id";
-	$command .= " -uri $uri";
-	$command .= " -dbname $dbname" if defined $dbname;
-
-	( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    run(command => $command, verbose => $verbose);
-
-	unless ($success) { 
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    &my_die ("Unable to register new detrend: $error_code", $corr_id, $PS_EXIT_PROG_ERROR);
-	}
+        # create the detrend correction for the imfiles based on the input imfiles
+        my $reffile = $file->{uri};
+        my $class_id = $file->{class_id};
+
+        my $uri = $ipprc->filename("DVOCORR.OUTPUT", $outcorr, $class_id);
+        unless ($uri) {
+            &my_die ("Unable to find DVOCORR.OUTPUT in filerules", $corr_id, $PS_EXIT_PROG_ERROR);
+        }
+
+        my $command = "$dvoMakeCorr $outcorr";
+        $command .= " -file $outgrid.fits";
+        $command .= " -ref $reffile";
+
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die ("Unable to perform dvoMakeCorr: $error_code", $corr_id, $PS_EXIT_PROG_ERROR);
+        }
+
+        # register the detrend correction imfile
+        $command = "$dettool -register_detrend_imfile";
+        $command .= " -det_id $det_id";
+        $command .= " -class_id $class_id";
+        $command .= " -uri $uri";
+        $command .= " -dbname $dbname" if defined $dbname;
+
+        ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die ("Unable to register new detrend: $error_code", $corr_id, $PS_EXIT_PROG_ERROR);
+        }
     }
 }
@@ -345,5 +346,5 @@
     if (not $no_update) {
         my $command = "$flatcorr -addprocess";
-	$command .= " -corr_id $corr_id";
+        $command .= " -corr_id $corr_id";
         $command .= " -fault $exit_code";
         $command .= " -hostname $host" if defined $host;
Index: /branches/pap/ippScripts/scripts/ipp_cleanup.pl
===================================================================
--- /branches/pap/ippScripts/scripts/ipp_cleanup.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/ipp_cleanup.pl	(revision 28003)
@@ -14,5 +14,4 @@
 use File::Spec;
 use PS::IPP::Config 1.01 qw( :standard );
-use PS::IPP::Metadata::List qw( parse_md_list );
 use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
 use Pod::Usage qw( pod2usage );
@@ -108,10 +107,7 @@
     }
 
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    # extract the metadata for the files into a hash list
+    $imfiles = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "chip", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    # extract the metadata for the files into a hash list
-    $imfiles = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "chip", $stage_id, $PS_EXIT_PROG_ERROR);
 
     # loop over all of the imfiles, determine the path_base and class_id for each
@@ -196,5 +192,5 @@
             # Tell magicdstool that we've cleaned up this data, so it needs to do the same if it needs to do the same.
             my $magicdstool = can_run('magicdstool') or die "Can't find magicdstool";
-            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -state full";
+            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -set_label goto_cleaned";
             $command .= " -dbname $dbname" if defined $dbname;
             ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -249,9 +245,6 @@
         &my_die("Unable to perform camtool: $error_code", "camera", $stage_id, $error_code);
     }
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "camera", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $exps = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "camera", $stage_id, $PS_EXIT_PROG_ERROR);
 
     my $n_exps = @$exps;
@@ -316,5 +309,5 @@
         # Tell magicdstool that we've cleaned up this data, so it needs to do the same if it needs to do the same.
         my $magicdstool = can_run('magicdstool') or die "Can't find magicdstool";
-        $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -state full";
+        $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -set_label goto_cleaned";
         $command .= " -dbname $dbname" if defined $dbname;
         ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -375,9 +368,6 @@
         exit(0);
     }
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    $skyfiles = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "warp", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $skyfiles = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "warp", $stage_id, $PS_EXIT_PROG_ERROR);
 
     my @files = ();
@@ -457,5 +447,5 @@
             # Tell magicdstool that we've cleaned up this data, so it needs to do the same if it needs to do the same.
             my $magicdstool = can_run('magicdstool') or die "Can't find magicdstool";
-            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -state full";
+            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -set_label goto_cleaned";
             $command .= " -dbname $dbname" if defined $dbname;
             ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -515,9 +505,6 @@
     }
 
-    my $metadata = $mdcParser->parse(join "", @{ $stdout_buf }) or
+    $skyfiles = $mdcParser->parse_list(join "", @{ $stdout_buf }) or
         &my_die("Unable to parse metadata config doc", "stack", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $skyfiles = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "stack", $stage_id, $PS_EXIT_PROG_ERROR);
 
     my @files = ();
@@ -594,5 +581,5 @@
             # Tell magicdstool that we've cleaned up this data, so it needs to do the same if it needs to do the same.
             my $magicdstool = can_run('magicdstool') or die "Can't find magicdstool";
-            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -state full";
+            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -set_label goto_cleaned";
             $command .= " -dbname $dbname" if defined $dbname;
             ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -652,9 +639,6 @@
     }
 
-    my $metadata = $mdcParser->parse(join "", @{ $stdout_buf }) or
+    $skyfiles = $mdcParser->parse_list(join "", @{ $stdout_buf }) or
         &my_die("Unable to parse metadata config doc", "diff", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $skyfiles = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "diff", $stage_id, $PS_EXIT_PROG_ERROR);
 
     my @files = ();
@@ -747,5 +731,5 @@
             # Tell magicdstool that we've cleaned up this data, so it needs to do the same if it needs to do the same.
             my $magicdstool = can_run('magicdstool') or die "Can't find magicdstool";
-            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -state full";
+            $command = "$magicdstool -stage $stage -stage_id $stage_id -updaterun -set_state goto_cleaned -set_label goto_cleaned";
             $command .= " -dbname $dbname" if defined $dbname;
             ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -806,10 +790,7 @@
     }
 
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    # extract the metadata for the files into a hash list
+    $imfiles = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "fake", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    # extract the metadata for the files into a hash list
-    $imfiles = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "fake", $stage_id, $PS_EXIT_PROG_ERROR);
 
     # loop over all of the imfiles, determine the path_base and class_id for each
@@ -927,10 +908,7 @@
 
 
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        # extract the metadata for the files into a hash list
+        $imfiles = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
-
-        # extract the metadata for the files into a hash list
-        $imfiles = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
     }
     # loop over all of the imfiles, determine the path_base and class_id for each
@@ -1013,8 +991,6 @@
     }
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        my $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage (detProcessedExp)", $stage_id, $PS_EXIT_PROG_ERROR);
-        my $exps = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage (detProcessedExp)", $stage_id, $PS_EXIT_PROG_ERROR);
 
         foreach my $exp (@$exps) {
@@ -1068,10 +1044,7 @@
     # if there are no detResidImfiles (@$stdout_buf == 0), then silently exit.
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        # extract the metadata for the files into a hash list
+        $imfiles = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
-
-        # extract the metadata for the files into a hash list
-        $imfiles = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
     }
     # loop over all of the imfiles, determine the path_base and class_id for each
@@ -1156,8 +1129,6 @@
     }
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        my $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage (detResidExp)", $stage_id, $PS_EXIT_PROG_ERROR);
-        my $exps = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage (detResidExp)", $stage_id, $PS_EXIT_PROG_ERROR);
 
         foreach my $exp (@$exps) {
@@ -1202,9 +1173,6 @@
         &my_die("Unable to perform dettool: $error_code", "$stage", $stage_id, $error_code);
     }
-    my $metadata = $mdcParser->parse(join "", @{ $stdout_buf }) or
+    $stacks = $mdcParser->parse_list(join "", @{ $stdout_buf }) or
         &my_die("Unable to parse metadata config doc", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $stacks = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
 
     my @files = ();
@@ -1286,8 +1254,6 @@
     }
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        my $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
-        my $exps = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
 
         foreach my $exp (@$exps) {
@@ -1327,9 +1293,6 @@
         &my_die("Unable to perform dettool: $error_code", "$stage", $stage_id, $error_code);
     }
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    my $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    my $exps = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
 
     foreach my $exp (@$exps) {
@@ -1380,8 +1343,6 @@
     }
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
-        $exps = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
 
         foreach my $exp (@$exps) {
@@ -1425,9 +1386,6 @@
         &my_die("Unable to perform dettool: $error_code", "$stage", $stage_id, $error_code);
     }
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $exps = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
 
     foreach my $exp (@$exps) {
@@ -1511,8 +1469,6 @@
     }
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
-        $exps = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
 
         foreach my $exp (@$exps) {
@@ -1559,9 +1515,6 @@
         exit 0;
     }
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
-
-    $exps = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", "$stage", $stage_id, $PS_EXIT_PROG_ERROR);
 
     foreach my $exp (@$exps) {
@@ -1643,8 +1596,6 @@
     }
     if (@$stdout_buf != 0) {
-        $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        $exps = $mdcParser->parse_list(join "", @$stdout_buf) or
             &my_die("Unable to parse metadata config doc", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
-        $exps = parse_md_list($metadata) or
-            &my_die("Unable to parse metadata list", "$stage (detRunSummary)", $stage_id, $PS_EXIT_PROG_ERROR);
 
         foreach my $exp (@$exps) {
Index: /branches/pap/ippScripts/scripts/ipp_detrend_combine.pl
===================================================================
--- /branches/pap/ippScripts/scripts/ipp_detrend_combine.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/ipp_detrend_combine.pl	(revision 28003)
@@ -7,6 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -32,24 +33,24 @@
     $workdir, $dbname, $no_update);
 GetOptions(
-	   'det_type=s'    => \$det_type, # Detrend type for new detrend
-	   'filelevel=s'   => \$filelevel, # File level for new detrend
-	   'inst=s'        => \$inst, # Instrument for new detrend
-	   'telescope=s'   => \$telescope, # Telescope for new detrend
-	   'filter=s'      => \$filter,	# Filter name for new detrend
-	   'det_id1=s'	   => \$det_id1, # Detrend id for detrend 1
-	   'iteration1=s'  => \$iter1, # Iteration for detrend 1
-	   'det_id2=s'	   => \$det_id2, # Detrend id for detrend 2
-	   'iteration2=s'  => \$iter2, # Iteration for detrend 2
-	   'operation=s'   => \$operation, # Operation to perform on files
-	   'mask'          => \$mask, # Operation is on a mask
-	   'workdir=s'     => \$workdir, # Working directory for output files
-	   'dbname=s'      => \$dbname,	# Database name
-	   'no-update'     => \$no_update, # Don't update the database
-	   ) or pod2usage( 2 );
+           'det_type=s'    => \$det_type, # Detrend type for new detrend
+           'filelevel=s'   => \$filelevel, # File level for new detrend
+           'inst=s'        => \$inst, # Instrument for new detrend
+           'telescope=s'   => \$telescope, # Telescope for new detrend
+           'filter=s'      => \$filter, # Filter name for new detrend
+           'det_id1=s'     => \$det_id1, # Detrend id for detrend 1
+           'iteration1=s'  => \$iter1, # Iteration for detrend 1
+           'det_id2=s'     => \$det_id2, # Detrend id for detrend 2
+           'iteration2=s'  => \$iter2, # Iteration for detrend 2
+           'operation=s'   => \$operation, # Operation to perform on files
+           'mask'          => \$mask, # Operation is on a mask
+           'workdir=s'     => \$workdir, # Working directory for output files
+           'dbname=s'      => \$dbname, # Database name
+           'no-update'     => \$no_update, # Don't update the database
+           ) or pod2usage( 2 );
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
 pod2usage( -msg => "Required options --det_type --filelevel --inst --telescope --det_id1 --iteration1 --det_id2 --iteration2 --workdir",
-	   -exitval => 3,
-	   )
+           -exitval => 3,
+           )
     unless defined $det_type
     and defined $filelevel
@@ -65,6 +66,6 @@
 $ipprc->define_camera($inst);
 
-my $STATS = 
-   [   
+my $STATS =
+   [
        #          PPSTATS KEYWORD         STATISTIC          CHIPTOOL FLAG
        { name => "ROBUST_MEDIAN",  type => "mean",  flag => "-bg",             dtype => "float" },
@@ -90,15 +91,15 @@
 die("File lists for detrends have differing lengths") unless scalar keys %$files1 == scalar keys %$files2;
 
-my ($det_id, $iter);	      # Detrend identifier for the new detrend
+my ($det_id, $iter);          # Detrend identifier for the new detrend
 unless ($no_update) {
     my $command = "$dettool -register_detrend -det_type $det_type -filelevel $filelevel -workdir $workdir " .
-	"-inst $inst -telescope $telescope"; # Command to run
+        "-inst $inst -telescope $telescope"; # Command to run
     $command .= " -filter $filter" if defined $filter;
     $command .= " -dbname $dbname" if defined $dbname;
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => 1);
+        run(command => $command, verbose => 1);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	die("Unable to run dettool -register_detrend: $error_code");
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        die("Unable to run dettool -register_detrend: $error_code");
     }
 
@@ -137,8 +138,8 @@
     $command .= " -dbname $dbname" if defined $dbname;
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => 1);
+        run(command => $command, verbose => 1);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	die("Unable to run ppArith: $error_code");
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        die("Unable to run ppArith: $error_code");
     }
 
@@ -149,28 +150,28 @@
     my $stats = PS::IPP::Metadata::Stats->new($STATS); # Stats parser
     {
-	my $statsFile;		# File handle
-	open $statsFile, $ipprc->file_resolve($outStats) or die("Can't open stats file $outStats: $!");
-	my @contents = <$statsFile>; # Contents of file
-	close $statsFile;
-	
-	my $metadata = $mdcParser->parse(join "", @contents) or die("Unable to parse metadata config doc");
-
-	unless ($stats->parse($metadata)) {
-	    &my_die("Failure extracting metadata from the statistics output file.\n");
-	}
+        my $statsFile;          # File handle
+        open $statsFile, $ipprc->file_resolve($outStats) or die("Can't open stats file $outStats: $!");
+        my @contents = <$statsFile>; # Contents of file
+        close $statsFile;
+
+        my $metadata = $mdcParser->parse(join "", @contents) or die("Unable to parse metadata config doc");
+
+        unless ($stats->parse($metadata)) {
+            &my_die("Failure extracting metadata from the statistics output file.\n");
+        }
     }
 
     # Register the imfile
     unless ($no_update) {
-	my $command = "$dettool -register_detrend_imfile -det_id $det_id "; # Command to run
-	$command .= " -class_id $class_id -uri $outName -path_base $outRoot";
-	$command .= $stats->cmdflags();
-	$command .= " -dbname $dbname" if defined $dbname;
-	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    run(command => $command, verbose => 1);
-	unless ($success) {
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    die("Unable to run dettool -register_detrend_imfile: $error_code");
-	}
+        my $command = "$dettool -register_detrend_imfile -det_id $det_id "; # Command to run
+        $command .= " -class_id $class_id -uri $outName -path_base $outRoot";
+        $command .= $stats->cmdflags();
+        $command .= " -dbname $dbname" if defined $dbname;
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => 1);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            die("Unable to run dettool -register_detrend_imfile: $error_code");
+        }
     }
 }
@@ -183,14 +184,14 @@
 sub filelist
 {
-    my $det_id = shift;		# Detrend identifier
-    my $iter = shift;		# Iteration
+    my $det_id = shift;         # Detrend identifier
+    my $iter = shift;           # Iteration
 
     my $command = "$detselect -select -det_id $det_id -iteration $iter"; # Command to run
     $command .= " -dbname $dbname" if defined $dbname;
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => 1);
+        run(command => $command, verbose => 1);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	die("Unable to run detselect: $error_code");
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        die("Unable to run detselect: $error_code");
     }
 
@@ -202,8 +203,8 @@
 
     foreach my $item ( @$list ) {
-	my $class_id = $item->{class_id};
-	die("Multiple definitions of class_id=$class_id found for det_id=$det_id, iteration=$iter\n") if
-	    defined $files{$class_id};
-	$files{$class_id} = parse_md_list($md);
+        my $class_id = $item->{class_id};
+        die("Multiple definitions of class_id=$class_id found for det_id=$det_id, iteration=$iter\n") if
+            defined $files{$class_id};
+        $files{$class_id} = parse_md_list($md);
     }
 
Index: /branches/pap/ippScripts/scripts/lossy_compress_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/lossy_compress_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/lossy_compress_imfile.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -86,36 +87,36 @@
 if ($state eq 'goto_compressed') {
     # Find the actual filename for this run:
-    &my_die("Couldn't find input file: $uri\n", $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR) 
-	unless ($ipprc->file_exists($uri));
+    &my_die("Couldn't find input file: $uri\n", $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR)
+        unless ($ipprc->file_exists($uri));
     my $uriReal = $ipprc->file_resolve( $uri );
 
     # Create a compressed version:
     my $compUri = $uri . ".fz";
-    &my_die("Output compressed file already exists: $compUri\n", $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR) 
-	if ($ipprc->file_exists($compUri));
+    &my_die("Output compressed file already exists: $compUri\n", $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR)
+        if ($ipprc->file_exists($compUri));
     my $compReal= $ipprc->file_resolve( $compUri, 'create');
     # Apparently we need to funpack before fpacking.  Probably should have realized that beforehand.
     my $tempfile = new File::Temp ( TEMPLATE => "${exp_name}.XXXX",
-				    DIR => '/tmp/',
-				    UNLINK => !$save_temps,
-				    SUFFIX => '.fits');
+                                    DIR => '/tmp/',
+                                    UNLINK => !$save_temps,
+                                    SUFFIX => '.fits');
     my $tempReal = $tempfile->filename;
 
     my $uncompress_command = "$funpack -S $uriReal > $tempReal";
     my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
-	run(command => $uncompress_command, verbose => $verbose);
+        run(command => $uncompress_command, verbose => $verbose);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die("Unable to uncompress file: $uri -> $compUri: $error_code", 
-		$exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to uncompress file: $uri -> $compUri: $error_code",
+                $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
     }
     my $compress_command = "$fpack -h -s 8 -S $tempReal >  $compReal";
     print STDERR "$compReal $uriReal $compress_command\n";
     ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
-	run(command => $compress_command, verbose => $verbose);
+        run(command => $compress_command, verbose => $verbose);
     unless ($success) {
-	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die("Unable to compress file: $uri -> $compUri: $error_code", 
-		$exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to compress file: $uri -> $compUri: $error_code",
+                $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
     }
     my $database_command = "$regtool -updateprocessedimfile -exp_id $exp_id -class_id $class_id -set_state compressed";
@@ -123,17 +124,17 @@
 
     &my_die("Expected output compressed file not found: $compUri\n", $exp_id,$exp_name,$class_id, $uri,$PS_EXIT_SYS_ERROR)
-	unless ($ipprc->file_exists($compUri));
+        unless ($ipprc->file_exists($compUri));
 
     if ($no_update || $no_op) {
-	print STDERR "NOUPDATE: $database_command\n";
+        print STDERR "NOUPDATE: $database_command\n";
     }
     else {
-	($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
-	    run(command => $database_command, verbose => $verbose);
-	unless ($success) {
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    &my_die("Unable to update database file: $uri -> $compUri: $error_code", 
-		    $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
-	}
+        ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
+            run(command => $database_command, verbose => $verbose);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die("Unable to update database file: $uri -> $compUri: $error_code",
+                    $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
+        }
     }
     exit(0);
@@ -149,28 +150,28 @@
     # Confirm we have both files
     &my_die("Couldn't find original file: $uri\n", $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR)
-	unless($ipprc->file_exists($uri));
+        unless($ipprc->file_exists($uri));
     my $uriReal = $ipprc->file_resolve( $uri );
-    
+
     my $compUri = $uri . ".fz";
     unless($ipprc->file_exists($compUri)) {
-	&my_die("Couldn't find compressed version of the file: $compUri\n", 
-		$exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR);
-
-	# If that die is removed, this will compress things as well.
-	# 
-# 	&my_die("Output compressed file already exists: $compUri\n", 
-# 		$exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR) 
-# 	    if ($ipprc->file_exists($compUri));
-# 	my $compReal= $ipprc->file_resolve( $compUri, 'create');
-	
-# 	my $compress_command = "$fpack -h -s 8 -S $uriReal >  $compReal";
-# 	print STDERR "$compReal $uriReal $compress_command\n";
-# 	my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
-# 	    run(command => $compress_command, verbose => $verbose);
-# 	unless ($success) {
-# 	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-# 	    &my_die("Unable to compress file: $uri -> $compUri: $error_code", 
-# 		    $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
-# 	}
+        &my_die("Couldn't find compressed version of the file: $compUri\n",
+                $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR);
+
+        # If that die is removed, this will compress things as well.
+        #
+#       &my_die("Output compressed file already exists: $compUri\n",
+#               $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR)
+#           if ($ipprc->file_exists($compUri));
+#       my $compReal= $ipprc->file_resolve( $compUri, 'create');
+
+#       my $compress_command = "$fpack -h -s 8 -S $uriReal >  $compReal";
+#       print STDERR "$compReal $uriReal $compress_command\n";
+#       my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
+#           run(command => $compress_command, verbose => $verbose);
+#       unless ($success) {
+#           $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+#           &my_die("Unable to compress file: $uri -> $compUri: $error_code",
+#                   $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
+#       }
     }
 
@@ -181,10 +182,10 @@
 
     unless ($no_op) {
-	$neb->replicate($compUri);
-	$neb->swap($uri,$compUri) or
-	    &my_die("Nebulous swap failed between $uri and $compUri", 
-		    $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR);
-    }
-    # Update database 
+        $neb->replicate($compUri);
+        $neb->swap($uri,$compUri) or
+            &my_die("Nebulous swap failed between $uri and $compUri",
+                    $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR);
+    }
+    # Update database
 
     my $database_command = "$regtool -updateprocessedimfile -exp_id $exp_id -class_id $class_id -set_state lossy ";
@@ -192,20 +193,20 @@
 
     $database_command .= " -dbname $dbname" if defined $dbname;
-    
+
     if ($no_update || $no_op) {
-	print STDERR "NOUPDATE: $database_command\n";
+        print STDERR "NOUPDATE: $database_command\n";
     }
     else {
-	my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
-	    run(command => $database_command, verbose => $verbose);
-	unless($success) {
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    $neb->swap($uri,$compUri) or
-		&my_die("DB update failed and Nebulous swap-back failed between $uri and $compUri", 
-			$exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR);
-	    &my_die("Unable to update database file: $uri -> $compUri: $error_code", 
-		    $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
-	}
-	# remove original version
+        my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
+            run(command => $database_command, verbose => $verbose);
+        unless($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            $neb->swap($uri,$compUri) or
+                &my_die("DB update failed and Nebulous swap-back failed between $uri and $compUri",
+                        $exp_id,$exp_name,$class_id,$uri,$PS_EXIT_SYS_ERROR);
+            &my_die("Unable to update database file: $uri -> $compUri: $error_code",
+                    $exp_id,$exp_name,$class_id,$uri, $PS_EXIT_SYS_ERROR);
+        }
+        # remove original version
     $neb->delete($compUri);
     }
Index: /branches/pap/ippScripts/scripts/magic_destreak.pl
===================================================================
--- /branches/pap/ippScripts/scripts/magic_destreak.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/magic_destreak.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -41,5 +42,5 @@
 # Parse the command-line arguments
 my ($magic_ds_id, $camera, $streaks, $inv_streaks, $exp_id, $stage, $stage_id, $component, $uri, $path_base, $cam_path_base, $cam_reduction);
-my ($outroot, $recoveryroot);
+my ($outroot, $recoveryroot, $magicked);
 my ($replace, $release);
 my ($dbname, $save_temps, $verbose, $no_update, $no_op, $logfile);
@@ -61,4 +62,5 @@
            'recoveryroot=s' => \$recoveryroot,# "directory" for saving the images of excised pixels
            'replace=s'      => \$replace,    # replace the input images with the results.
+           'magicked=s'     => \$magicked,   # magicked state of the run
            'release'        => \$release,    # NAN masked pixels for release
            'save-temps'     => \$save_temps, # Save temporary files?
@@ -71,5 +73,5 @@
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
-pod2usage( -msg => "Required options: --magic_ds_id --camera --streaks --stage --stage_id --component --uri --path_base --outroot",
+pod2usage( -msg => "Required options: --magic_ds_id --camera --streaks --stage --stage_id --component --uri --path_base --outroot --magicked",
            -exitval => 3) unless
     defined $magic_ds_id and
@@ -82,5 +84,6 @@
     defined $uri and
     defined $path_base and
-    defined $outroot;
+    defined $outroot and
+    defined $magicked;
 
 my $ipprc = PS::IPP::Config->new( $camera ) or my_die( "Unable to set up", $magic_ds_id, $component, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
@@ -209,5 +212,4 @@
                     &my_die("Unable to parse metadata list", $magic_ds_id, $component, $PS_EXIT_PROG_ERROR);
 
-            $temp_dir = tempdir( CLEANUP => !$save_temps);
             ($sfh, $skycell_list) = tempfile( "/tmp/skycell_list.XXXX", UNLINK => !$save_temps);
 
@@ -218,4 +220,7 @@
                 } else {
                     # diff run must have been cleaned up, need to create this skycell file on the fly
+                    if (!defined $temp_dir ) {
+                        $temp_dir = tempdir( CLEANUP => !$save_temps);
+                    }
                     my $skycell_id = $skycell->{skycell_id};
                     $skycell_uri = "$temp_dir/$skycell_id";
@@ -247,5 +252,6 @@
             my $command = "$ppConfigDump -camera $camera -recipe PSASTRO $recipe_psastro -dump-recipe PSASTRO -";
             my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
+                    # note verbose == 0 to avoid polluting log files with almost always useless information
+                run(command => $command, verbose => 0);
             unless ($success) {
                 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
@@ -266,5 +272,7 @@
         $astrom = $ipprc->filename("PSASTRO.OUTPUT", $cam_path_base);
 
-        if ($dynamicMasks) {
+        # if magicked is non-zero we are updating a previously magicked component. In this case we don't
+        # touch the camera mask
+        if (!$magicked and $dynamicMasks) {
             $mask = $ipprc->filename("PSASTRO.OUTPUT.MASK", $cam_path_base, $class_id);
             $ch_mask = $ipprc->filename("PPIMAGE.CHIP.MASK", $path_base, $class_id);
Index: /branches/pap/ippScripts/scripts/magic_destreak_cleanup.pl
===================================================================
--- /branches/pap/ippScripts/scripts/magic_destreak_cleanup.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/magic_destreak_cleanup.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -62,13 +63,4 @@
 $ipprc->redirect_output($logfile) or my_die( "Unable to redirect output", $magic_ds_id, $PS_EXIT_SYS_ERROR ) if $logfile;
 
-if (0) {
-my $nebulousServer = metadataLookupStr( $ipprc->{_siteConfig}, 'NEB_SERVER' );
-&my_die("cannot find NEB_SERVER in site configuration", $magic_ds_id, $PS_EXIT_CONFIG_ERROR) if !$nebulousServer;
-
-my $nebulous = eval { Nebulous::Client->new( proxy => $nebulousServer ); };
-if ($@ or not defined $nebulous) {
-    &my_die ("Unable to create a Nebulous::Client object with proxy $nebulousServer", $magic_ds_id, $PS_EXIT_CONFIG_ERROR);
-}
-}
 
 $dbname = metadataLookupStr( $ipprc->{_siteConfig}, 'DBNAME' ) if !$dbname;
@@ -107,4 +99,7 @@
 
 
+&my_die("cleanup not supported for camera stage", $magic_ds_id, $PS_EXIT_PROG_ERROR) if $stage eq "camera";
+
+
 &my_die("unexpected run state found: $state", $magic_ds_id, $PS_EXIT_CONFIG_ERROR) if $state ne "goto_cleaned";
 &my_die("clean not allowed for raw stage, use goto_restore", $magic_ds_id, $PS_EXIT_CONFIG_ERROR) if $stage eq "raw";
@@ -129,4 +124,8 @@
 $dbh->disconnect() or warn $dbh->errstr;
 
+# We no longer clean up the camera stage mask files, but the code was left in place in case
+# we change our minds.
+my $cleanup_cam_mask = 0;
+
 my $dynamicMasks;               # Use dynamic masks?
 foreach my $comp (@components) {
@@ -139,5 +138,5 @@
         if ($stage eq "chip") {
             # Check to see if we're using dynamic masks
-            if (!defined $dynamicMasks) {
+            if ($cleanup_cam_mask && !defined $dynamicMasks) {
                 # Get the PSASTRO recipe
                 my $command = "$ppConfigDump -camera $camera -recipe PSASTRO $recipe_psastro -dump-recipe PSASTRO -";
Index: /branches/pap/ippScripts/scripts/magic_destreak_defineruns.pl
===================================================================
--- /branches/pap/ippScripts/scripts/magic_destreak_defineruns.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/magic_destreak_defineruns.pl	(revision 28003)
@@ -11,6 +11,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/magic_destreak_revert.pl
===================================================================
--- /branches/pap/ippScripts/scripts/magic_destreak_revert.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/magic_destreak_revert.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -37,5 +38,5 @@
 
 # Parse the command-line arguments
-my ($magic_ds_id, $camera, $streaks, $stage, $stage_id, $component, $uri, $path_base, $bothways, $cam_path_base, $cam_reduction);
+my ($magic_ds_id, $camera, $streaks, $stage, $stage_id, $component, $uri, $path_base, $bothways, $cam_path_base, $cam_reduction, $magicked);
 my ($outroot, $recoveryroot, $replace, $release, $bytes, $md5sum);
 my ($dbname, $save_temps, $verbose, $no_update, $no_op, $logfile);
@@ -54,4 +55,5 @@
            'replace=s'      => \$replace,    # replace the input images with the results.
            'bothways=s'     => \$bothways,   # run has inverse files (bothways diff)
+           'magicked=s'     => \$magicked,   # magicked state of the run
            'save-temps'     => \$save_temps, # Save temporary files?
            'dbname=s'       => \$dbname,     # Database name
@@ -63,5 +65,5 @@
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
-pod2usage( -msg => "Required options: --magic_ds_id --camera --stage --stage_id --component --path_base --outroot",
+pod2usage( -msg => "Required options: --magic_ds_id --camera --stage --stage_id --component --path_base --outroot --magicked",
            -exitval => 3) unless
     defined $magic_ds_id and
@@ -71,4 +73,5 @@
     defined $component and
     defined $path_base and
+    defined $magicked and
     defined $outroot;
 
@@ -76,4 +79,6 @@
 
 &my_die("cam_path_base is required for chip stage", $magic_ds_id, $component, $PS_EXIT_CONFIG_ERROR) if ($stage eq 'chip' and !$cam_path_base);
+
+
 
 my $ipprc = PS::IPP::Config->new( $camera ) or my_die( "Unable to set up", $magic_ds_id, $component, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
@@ -168,5 +173,6 @@
         my $command = "$ppConfigDump -camera $camera -recipe PSASTRO $recipe_psastro -dump-recipe PSASTRO -";
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-            run(command => $command, verbose => $verbose);
+            # note verbose == 0 to keep from polluting log file with lots of usually useless information
+            run(command => $command, verbose => 0);
         unless ($success) {
             $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
@@ -181,10 +187,12 @@
     }
 
+    $image  = $ipprc->filename("PPIMAGE.CHIP", $path_base, $class_id);
+    $weight = $ipprc->filename("PPIMAGE.CHIP.VARIANCE", $path_base, $class_id);
+
     # we use the mask output from the camera stage for input and replace
     # the output of the chip stage with that mask as well.
-    $image  = $ipprc->filename("PPIMAGE.CHIP", $path_base, $class_id);
-    $weight = $ipprc->filename("PPIMAGE.CHIP.VARIANCE", $path_base, $class_id);
-
-    if ($dynamicMasks) {
+    # Note that when destreaking as part of an update $magicked is non-zero.
+    # In this case we do not touch the camera stage mask so there is no need to revert it
+    if (!$magicked and $dynamicMasks) {
         $mask = $ipprc->filename("PSASTRO.OUTPUT.MASK", $cam_path_base, $class_id);
         $ch_mask = $ipprc->filename("PPIMAGE.CHIP.MASK", $path_base, $class_id);
@@ -194,5 +202,5 @@
 
     $bimage  = $ipprc->filename("PPIMAGE.CHIP", $backup_path_base, $class_id);
-    # This is kludgey but correct
+    # This is somewhat kludgey but it works whether the mask is camera mask or chip mask
     $bmask   = dirname($backup_path_base) . "/SR_" . basename($mask);
     $bch_mask= $ipprc->filename("PPIMAGE.CHIP.MASK", $backup_path_base, $class_id);
Index: /branches/pap/ippScripts/scripts/magic_process.pl
===================================================================
--- /branches/pap/ippScripts/scripts/magic_process.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/magic_process.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -98,13 +99,11 @@
     }
 
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    $inputs = $mdcParser->parse_list(join "", @$stdout_buf) or
         &my_die("Unable to parse metadata config doc", $magic_id, $node, $PS_EXIT_PROG_ERROR);
-
-    $inputs = parse_md_list($metadata) or
-        &my_die("Unable to parse metadata list", $magic_id, $node, $PS_EXIT_PROG_ERROR);
 }
 
 
 my @outputs;
+my $inverse;                    # Using inverse diff?
 ### Do the heavy lifting
 {
@@ -262,4 +261,8 @@
                 cat_list_to_list($mfh, $in_path_base, "mask.list");
                 cat_list_to_list($wfh, $in_path_base, "weight.list");
+
+                if ($innode->{inverse}) {
+                    $inverse = 1;
+                }
             }
             close $in_fh;
@@ -329,4 +332,5 @@
     }
 }
+
 if ($node eq "root") {
     my $streaks_file = "$outroot.streaks";
@@ -347,21 +351,56 @@
     &run_verifystreaks($baseroot);
 
-    my $command = "$magictool -addmask";
-    $command   .= " -magic_id $magic_id";
-    $command   .= " -uri $streaks_file";
-    $command   .= " -streaks $num_streaks";
-    $command   .= " -dbname $dbname" if defined $dbname;
-
-    # Add the processed file to the database
-    unless ($no_update) {
+    my $exp_id;                 # Exposure identifier
+    my $cam_path;               # Camera stage path_base
+    {
+        my $command = "magictool -exposure -magic_id $magic_id";
+        $command .= " -inverse" if defined $inverse;
+        $command .= " -dbname $dbname" if defined $dbname;
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
             run(command => $command, verbose => $verbose);
-        unless ($success) {
-            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-            # This isn't going to work because our result was already entered.
-            &my_die("Unable to perform magictool -addmask: $error_code", $magic_id, $node, $error_code);
-        }
-    } else {
-        print "Skipping command: $command\n";
+        my $exposures = $mdcParser->parse_list(join "", @$stdout_buf);
+        my $exp = $$exposures[0]; # Exposure of interest (should only be one)
+
+        $exp_id = $exp->{exp_id};
+        $cam_path = $exp->{path_base};
+    }
+
+    {
+        my $astrom = $ipprc->filename("PSASTRO.OUTPUT", $cam_path); # Astrometry file
+        my $streaks = "$outroot.streaks";                           # Streaks file
+        my $clusters = "$baseroot.verify/${exp_id}_clusterPos.txt"; # Clusters file
+
+        my $command = "ppCoord -astrom $astrom -streaks $streaks";
+        if ($ipprc->file_exists($clusters)) {
+            $command .= " -clusters $clusters";
+        }
+
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        open my $coords, "> $outroot.coords";
+        print $coords join("", @$stdout_buf);
+        close $coords;
+    }
+
+
+    {
+        my $command = "$magictool -addmask";
+        $command   .= " -magic_id $magic_id";
+        $command   .= " -uri $streaks_file";
+        $command   .= " -streaks $num_streaks";
+        $command   .= " -dbname $dbname" if defined $dbname;
+
+        # Add the processed file to the database
+        unless ($no_update) {
+            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                run(command => $command, verbose => $verbose);
+            unless ($success) {
+                $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+                # This isn't going to work because our result was already entered.
+                &my_die("Unable to perform magictool -addmask: $error_code", $magic_id, $node, $error_code);
+            }
+        } else {
+            print "Skipping command: $command\n";
+        }
     }
 }
Index: /branches/pap/ippScripts/scripts/magic_tree.pl
===================================================================
--- /branches/pap/ippScripts/scripts/magic_tree.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/magic_tree.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/make_burntool_pcontrol.pl
===================================================================
--- /branches/pap/ippScripts/scripts/make_burntool_pcontrol.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/make_burntool_pcontrol.pl	(revision 28003)
@@ -1,8 +1,12 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl 
 # script to generate a pcontrol.pro file to run burntool on a set of data.
 
 use DBI;
+use warnings;
 use DateTime;
 use Getopt::Std;
+use PS::IPP::Metadata::List qw( parse_md_list );
+use PS::IPP::Config 1.01 qw( :standard );
+use IPC::Cmd 0.36 qw( can_run run);
 
 use constant DB_SOCKET => '/var/run/mysqld/mysqld.sock';
@@ -35,7 +39,11 @@
 		   ) or die "Unable to connect to database $DBI::errstr\n";
 
+my $ppConfigDump = can_run('ppConfigDump') or (warn "Can't find ppConfigDump" and $missing_tools = 1);
+if ($missing_tools) {
+    die "Cannot find required tools.";
+}
 # Determine what the value of "BURNTOOL.STATE.GOOD" currently is:
 $burntoolStateGood = 999;
-open(LAZY,"ppConfigDump -camera GPC1 -dump-camera - |") || die "Can't run ppConfigDump\n";
+open(LAZY,"$ppConfigDump -camera GPC1 -dump-camera - |") || die "Can't run ppConfigDump\n";
 while(<LAZY>) {
     chomp;
@@ -46,14 +54,54 @@
 }
 close(LAZY);
-#unless( $burntoolStateGood == 999) {
-#    print STDERR "GOOD == $burntoolStateGood\n";
-#}
-
-
-# List of which obs_modes are "science" and which are something else.
-%science = ('MD' => 1, '3PI' => 1, 'STS' => 1, 'CAL' => 1, 'M31' => 1, 'SS' => 1,
-	    'ENGINEERING' => 0, 'NULL' => 0, 'Unknown' => 1, ' ' => 0);
+
+# Read the nightly science config file and use that to determine which data is science
+my $verbose = 0;
+my $conf_cmd = "$ppConfigDump -dump-recipe NIGHTLY_SCIENCE -";
+my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+    run(command => $conf_cmd, verbose => $verbose);
+unless ($success) {
+    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+    &my_die("Unable to perform ppConfigDUmp: $error_code", $date, $PS_EXIT_SYS_ERROR);
+}
+
+my @target_list;
+my %object_list;
+my $comment_list;
+
+my $mdcParser = PS::IPP::Metadata::Config->new;
+my $metadata = $mdcParser->parse(join "", @$stdout_buf);
+foreach my $entry (@{ $metadata }) {
+    if (${ $entry }{name} eq 'TARGETS') {
+        my @target_data = @{ ${ $entry }{value} };
+        my $this_target = '';
+	
+        foreach my $tentry (@target_data) {
+            if (${ $tentry }{name} eq 'NAME') {
+                $this_target = ${ $tentry }{value};
+                push @target_list, $this_target;
+		$obsmode_list{$this_target} = '.*';
+		$object_list{$this_target} = '.*';
+		$comment_list{$this_target} = '.*';
+            }
+            elsif (${ $tentry }{name} eq 'OBSMODE') {
+                $obsmode_list{$this_target} = ${ $tentry }{value};
+		$obsmode_list{$this_target} =~ s/%//;
+            }
+            elsif (${ $tentry }{name} eq 'OBJECT') {
+                $object_list{$this_target} = ${ $tentry }{value};
+		$object_list{$this_target} =~ s/%//;
+            }
+            elsif (${ $tentry }{name} eq 'COMMENT') {
+                $comment_list{$this_target} = ${ $tentry }{value};
+		$comment_list{$this_target} =~ s/%//;
+            }
+	}
+    }
+}
 if (exists($opt{P})) {
-    $science{Unknown} = 1;
+    push @target_list, 'PR';
+    $obsmode_list{'PR'} = 'Unknown';
+    $object_list{'PR'} = '.*';
+    $comment_list{'PR'} = '.*';
 }
 
@@ -119,5 +167,5 @@
     
     # Find _ALL_ observations within the date range we care about
-    $sth = "SELECT exp_id,dateobs,pon_time,exp_type,obs_mode,comment FROM rawExp WHERE " .
+    $sth = "SELECT exp_id,dateobs,pon_time,exp_type,obs_mode,comment,object FROM rawExp WHERE " .
 	"dateobs >= '${date_min}' AND dateobs <= '${date_max}' order by dateobs";
 
@@ -133,9 +181,12 @@
     foreach $row_ref (@{ $data_ref }) {
 
-	($exp_id,$dateobs,$pontime,$exp_type,$obs_mode,$comment) = @{ $row_ref };
+	($exp_id,$dateobs,$pontime,$exp_type,$obs_mode,$comment,$object) = @{ $row_ref };
 	# Fix nulls in the database
 	if (!defined($obs_mode)) {
 	    $obs_mode = ' ';
 	}
+	if (!defined($object)) {
+	    $object = ' ';
+	}
 	if (!defined($comment)) {
 	    $comment = ' ';
@@ -144,5 +195,5 @@
 	($date,$time) = split / /, $dateobs;
 	($year,$month,$day) = split /-/, $date;
-	($hour,$minute,$second) = split /:/, $time;
+	($hour,$minute,$second) = split /:/, $time; # / # This stops emacs run-on syntax highlights.
 	
 	$dt = DateTime->new( year   => $year, month  => $month, day    => $day,
@@ -155,16 +206,5 @@
 	$et = $dt->epoch();
 
-
-	if (!exists($science{$obs_mode})) {
-	    $science{$obs_mode} = 0;
-	}
-	if ((($science{$obs_mode} == 1)&&($comment !~ /Daytime/))||
-	    (($science{$obs_mode} == 0)&&(
-					  ($comment =~ /MD/)||($comment =~ /ThreePi/)||
-					  ($comment =~ /STS/i)||($comment =~ /M31/)||($comment =~ /Stellar Transit/)||
-					  ($comment =~ /CAL/i)||($comment =~ /SS/)||($comment =~ /SVS/)||
-					  ($comment =~ /Sweetspot/)||($comment =~ /virgo/i)||($comment =~ /kepler/)||
-					  ($comment =~ /sdss/))))					  
-	{
+	if (is_science($exp_type,$obs_mode,$object,$comment)) {
 	    if ($start_s[-1] == 0) {
 		$start_s[-1] = $et - 1800;
@@ -194,5 +234,5 @@
     # Scan again and count how many exposures are between windows
     foreach $row_ref (@{ $data_ref }) {
-	($exp_id,$dateobs,$pontime,$exp_type,$obs_mode,$comment) = @{ $row_ref };
+	($exp_id,$dateobs,$pontime,$exp_type,$obs_mode,$comment,$object) = @{ $row_ref };
 	if (!defined($obs_mode)) {
 	    $obs_mode = ' ';
@@ -204,5 +244,5 @@
 	($date,$time) = split / /, $dateobs;
 	($year,$month,$day) = split /-/, $date;
-	($hour,$minute,$second) = split /:/, $time;
+	($hour,$minute,$second) = split /:/, $time; # / # another emacs syntax highlight bug.
 	
 	$dt = DateTime->new( year   => $year, month  => $month, day    => $day,
@@ -215,10 +255,6 @@
 	$et = $dt->epoch();
 
-	if (!exists($science{$obs_mode})) {
-	    die "No mode >>$obs_mode<<\n";
-	}
-	
 	for ($i = 0; $i <= $#start_s; $i++) {
-	    if (($et < $start_s[$i])&&($science{$obs_mode} == 0)) {
+	    if (($et < $start_s[$i])&&(is_science($exp_type,$obs_mode,$object,$comment) == 0)) {
 		if ($i == 0) {
 		    $skips[$i]++;
@@ -278,4 +314,30 @@
 unless(exists($opt{b}) || ($N_ranges == 0)) {
     print_epilogue();
+}
+
+
+# Subroutine to use the configuration file data and the exposure data to determine whether or not something is "science"
+sub is_science {
+#    if (is_science($exp_type,$obs_mode,$object,$comment)) {
+    my ($exp_type,$obs_mode,$object,$comment) = @_;
+    my $return_value = 0;
+    unless($object) {
+	$object = '';
+    }
+    if ($exp_type eq 'OBJECT') {
+	foreach my $target (@target_list) {
+#	    print STDERR "$target $obsmode_list{$target} $exp_type $obs_mode $object $comment\n";
+	    if (($obs_mode =~ /$obsmode_list{$target}/)&&
+		($object   =~ /$object_list{$target}/)&&
+		($comment  =~ /$comment_list{$target}/)) {
+		$return_value = 1;
+	    }
+#	    print ">$return_value $exp_type $obs_mode $object $comment $target $obsmode_list{$target} $object_list{$target} $comment_list{$target}\n";
+	    if ($return_value) {
+		return($return_value);
+	    }
+	}
+    }
+    return(0);
 }
 
Index: /branches/pap/ippScripts/scripts/publish_file.pl
===================================================================
--- /branches/pap/ippScripts/scripts/publish_file.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/publish_file.pl	(revision 28003)
@@ -7,5 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
-print "Starting script $0 on $host\n\n";
+my $date = `date`;
+print "\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/rcserver_checkstatus.pl
===================================================================
--- /branches/pap/ippScripts/scripts/rcserver_checkstatus.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/rcserver_checkstatus.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/receive_advance.pl
===================================================================
--- /branches/pap/ippScripts/scripts/receive_advance.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/receive_advance.pl	(revision 28003)
@@ -7,5 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
-print "Starting script $0 on $host\n\n";
+my $date = `date`;
+print "\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
@@ -58,7 +60,6 @@
     &my_die( "Unable to set up", $fileset_id, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
 
-# update the fileset entry
-
-if ($dbinfo_uri and ($dbinfo_uri ne "NULL")) {
+my $import_run_to_db = 0;
+if ($import_run_to_db and $dbinfo_uri and ($dbinfo_uri ne "NULL")) {
     my $filename = basename($dbinfo_uri);
     my ($stage) = $filename =~ m|^dbinfo\.(\S+)\.\d+\.mdc$|; # Stage of interest
@@ -100,4 +101,5 @@
 }
 
+# update the fileset entry
 # All done
 {
Index: /branches/pap/ippScripts/scripts/receive_file.pl
===================================================================
--- /branches/pap/ippScripts/scripts/receive_file.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/receive_file.pl	(revision 28003)
@@ -7,5 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
-print "Starting script $0 on $host\n\n";
+my $date = `date`;
+print "\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
@@ -124,5 +126,5 @@
     print "dirinfo resolved is: $resolved\n" if $verbose;
 
-    open OUT, ">$resolved" 
+    open OUT, ">$resolved"
         or &my_die( "failed to open $resolved\n", $file_id, $PS_EXIT_UNKNOWN_ERROR);
     print OUT @$dirinfo_lines
@@ -130,5 +132,5 @@
     close OUT
         or &my_die( "failed to close $resolved\n", $file_id, $PS_EXIT_UNKNOWN_ERROR);
-    
+
     # update the fileset to allow processing of other files
     my $command = "$receivetool -updatefileset -fileset_id $fileset_id";
@@ -160,5 +162,5 @@
     &my_die( "failed to resolve $dbinfo_uri\n", $file_id, $PS_EXIT_UNKNOWN_ERROR) if !$resolved;
 
-    open OUT, ">$resolved" 
+    open OUT, ">$resolved"
         or &my_die( "failed to open $resolved\n", $file_id, $PS_EXIT_UNKNOWN_ERROR);
 
@@ -227,5 +229,5 @@
                 $current_component = $value;
                 $component_dir = $components->{$current_component};
-                &my_die( "$component_dir is null for $value in $filename: $runType\n", 
+                &my_die( "$component_dir is null for $value in $filename: $runType\n",
                         $file_id, $PS_EXIT_UNKNOWN_ERROR) if !$component_dir;
             } elsif ($name eq 'workdir') {
@@ -237,5 +239,5 @@
                 $new_value = basename($value);
             } elsif ((($name eq 'uri') or ($name eq 'path_base')) and ($value ne 'NULL')) {
-                &my_die( "$component_dir is null and we need it for $name", 
+                &my_die( "$component_dir is null and we need it for $name",
                         $file_id, $PS_EXIT_PROG_ERROR) if !$component_dir;
 
Index: /branches/pap/ippScripts/scripts/receive_fileset.pl
===================================================================
--- /branches/pap/ippScripts/scripts/receive_fileset.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/receive_fileset.pl	(revision 28003)
@@ -7,5 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
-print "Starting script $0 on $host\n\n";
+my $date = `date`;
+print "\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/receive_setstatus.pl
===================================================================
--- /branches/pap/ippScripts/scripts/receive_setstatus.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/receive_setstatus.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -74,5 +75,5 @@
         $fileargs = " --list - --copy --abspath";
     }
-        
+
     # XXX need to create a fileset type for this
     my $command = "echo $regline | dsreg --add $status_fs_name --product $status_product --type notset";
Index: /branches/pap/ippScripts/scripts/receive_source.pl
===================================================================
--- /branches/pap/ippScripts/scripts/receive_source.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/receive_source.pl	(revision 28003)
@@ -7,5 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
-print "Starting script $0 on $host\n\n";
+my $date = `date`;
+print "\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/register_exp.pl
===================================================================
--- /branches/pap/ippScripts/scripts/register_exp.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/register_exp.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -126,4 +127,5 @@
 $command .= " -end_stage $end_stage" if defined $end_stage;
 $command .= " -tess_id   $tess_id"   if defined $tess_id;
+$command .= " -state full";
 $command .= " $cmdflags";
 
Index: /branches/pap/ippScripts/scripts/register_imfile.pl
===================================================================
--- /branches/pap/ippScripts/scripts/register_imfile.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/register_imfile.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -115,39 +116,39 @@
     my $burntoolStateGood = 0;
     foreach my $line (split /\n/, $out1) {
-	if ($line =~ /FPA.BURNTOOL.APPLIED/) {
-	    $line =~ s/^\s+//;
-	    $burntoolState = (split /\s+/, $line)[2];
-	}
-	if ($line =~ /FPA.CAMERA/) {
-	    $line =~ s/^\s+//;
-	    if ((split /\s+/, $line)[2] eq 'GPC1') {
-		$isGPC1 = 1;
-	    }
-	}
+        if ($line =~ /FPA.BURNTOOL.APPLIED/) {
+            $line =~ s/^\s+//;
+            $burntoolState = (split /\s+/, $line)[2];
+        }
+        if ($line =~ /FPA.CAMERA/) {
+            $line =~ s/^\s+//;
+            if ((split /\s+/, $line)[2] eq 'GPC1') {
+                $isGPC1 = 1;
+            }
+        }
     }
     if ($isGPC1 != 1) {
-	$burntoolState = 0; # If it's not GPC1, you shouldn't have run burntool.
+        $burntoolState = 0; # If it's not GPC1, you shouldn't have run burntool.
     }
     elsif (($isGPC1 == 1) && ($burntoolState == 1)) {
-#	print STDERR "In the good region: >>$burntoolState<<\n";
-	my $ppConfigDump_cmd = "$ppConfigDump -camera GPC1 -dump-camera -";
-	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	    IPC::Cmd::run(command => $ppConfigDump_cmd, verbose => $verbose);
-	unless ($success) {
-	    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	    warn ("Unable to perform ppConfigDump");
-	    exit($error_code);
-	}
-
-	# This is ugly, but doing a full parse for one entry is a bit wasteful.
-	foreach my $line (split /\n/, (join "", @$stdout_buf)) {
-	    if ($line =~ /BURNTOOL.STATE.GOOD/) {
-		$line =~ s/^\s+//;
-		$burntoolStateGood = (split /\s+/, $line)[2];
-		last;
-	    }
-	}
-	$burntoolState = $burntoolStateGood; # Positive because this has the header table.
-	
+#       print STDERR "In the good region: >>$burntoolState<<\n";
+        my $ppConfigDump_cmd = "$ppConfigDump -camera GPC1 -dump-camera -";
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            IPC::Cmd::run(command => $ppConfigDump_cmd, verbose => $verbose);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            warn ("Unable to perform ppConfigDump");
+            exit($error_code);
+        }
+
+        # This is ugly, but doing a full parse for one entry is a bit wasteful.
+        foreach my $line (split /\n/, (join "", @$stdout_buf)) {
+            if ($line =~ /BURNTOOL.STATE.GOOD/) {
+                $line =~ s/^\s+//;
+                $burntoolStateGood = (split /\s+/, $line)[2];
+                last;
+            }
+        }
+        $burntoolState = $burntoolStateGood; # Positive because this has the header table.
+
     }
     $cmdflags .= " -burntool_state $burntoolState ";
@@ -173,4 +174,5 @@
 $command .= " -hostname $host" if defined $host;
 $command .= " -dbname $dbname" if defined $dbname;
+$command .= " -data_state full";
 $command .= " $cmdflags";
 
Index: /branches/pap/ippScripts/scripts/stack_skycell.pl
===================================================================
--- /branches/pap/ippScripts/scripts/stack_skycell.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/stack_skycell.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
Index: /branches/pap/ippScripts/scripts/staticsky.pl
===================================================================
--- /branches/pap/ippScripts/scripts/staticsky.pl	(revision 28003)
+++ /branches/pap/ippScripts/scripts/staticsky.pl	(revision 28003)
@@ -0,0 +1,324 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+
+## report the program and machine
+use Sys::Hostname;
+my $host = hostname();
+my $date = `date`;
+print "\n\n";
+print "Starting script $0 on $host at $date\n\n";
+
+use DateTime;
+my $mjd_start = DateTime->now->mjd;   # MJD of starting script
+
+use vars qw( $VERSION );
+$VERSION = '0.01';
+
+use IPC::Cmd 0.36 qw( can_run run );
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::List qw( parse_md_list );
+use Data::Dumper;
+use PS::IPP::Config 1.01 qw( :standard );
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+
+# Look for programs we need
+my $missing_tools;
+my $staticskytool = can_run('staticskytool') or (warn "Can't find staticskytool" and $missing_tools = 1);
+my $ppSub = can_run('ppSub') or (warn "Can't find ppSub" and $missing_tools = 1);
+my $ppStatsFromMetadata = can_run('ppStatsFromMetadata') or (warn "Can't find ppStatsFromMetadata" and $missing_tools = 1);
+if ($missing_tools) {
+    warn("Can't find required tools.");
+    exit($PS_EXIT_CONFIG_ERROR);
+}
+
+my ($sky_id, $dbname, $threads, $outroot, $reduction, $inverse, $run_state, $verbose, $no_update, $no_op, $redirect, $save_temps);
+GetOptions(
+    'sky_id=s'          => \$sky_id, # Diff identifier
+    'dbname|d=s'        => \$dbname, # Database name
+    'threads=s'         => \$threads,   # Number of threads to use
+    'run-state=s'       => \$run_state,   # state for run: 'new' or 'update'
+    'outroot=s'         => \$outroot, # Output root name
+    'reduction=s'       => \$reduction, # Reduction class
+    'verbose'           => \$verbose,   # Print to stdout
+    'no-update'         => \$no_update, # Don't update the database?
+    'no-op'             => \$no_op, # Don't do any operations?
+    'redirect-output'   => \$redirect,
+    'save-temps'        => \$save_temps, # Save temporary files?
+) or pod2usage( 2 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+pod2usage(
+    -msg => "Required options: --sky_id --outroot",
+    -exitval => 3,
+          ) unless 
+    defined $sky_id and
+    defined $outroot;
+
+my $ipprc = PS::IPP::Config->new() or my_die( "Unable to set up", $sky_id, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
+
+# XXX camera is not known here; cannot use filerules...
+# my $logDest = $ipprc->filename("LOG.EXP", $outroot);
+my $logDest = "$outroot.log";
+$logDest .= ".update" if $run_state eq "update";
+$ipprc->redirect_output($logDest) or my_die( "Unable to redirect output", $sky_id, $PS_EXIT_SYS_ERROR ) if $redirect;
+
+my $source_id = $ipprc->source_id($dbname, $PS_TABLE_ID_DIFF);
+
+my $outbase = basename($outroot);
+my ($listFile, $listName) = tempfile("/tmp/$outbase.list.XXXX", UNLINK => !$save_temps );
+
+# Get list of input images to stack photometry
+my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
+my $files;
+{
+    my $command = "$staticskytool -inputs -sky_id $sky_id";
+    $command .= " -dbname $dbname" if defined $dbname;
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
+    unless ($success) {
+        $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+        &my_die("Unable to perform difftool -inputskyfile: $error_code", $sky_id, $error_code);
+    }
+
+    my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+        &my_die("Unable to parse metadata config doc", $sky_id, $PS_EXIT_PROG_ERROR);
+    $files = parse_md_list($metadata) or
+        &my_die("Unable to parse metadata list", $sky_id, $PS_EXIT_PROG_ERROR);
+}
+
+# XXX do we NEED to define the camera?
+# &my_die("Unable to identify camera", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless defined $camera;
+# $ipprc->define_camera($camera);
+
+# generate the input 
+print $listFile "INPUT   MULTI\n";
+
+foreach my $file (@$files) {
+    print $listFile "INPUT   METADATA\n";
+
+    $path_base = $file->{path_base};
+    my $imageCnv  = $ipprc->filename("PPSTACK.OUTPUT", $file->{path_base} ); # Mask name
+    my $maskCnv   = $ipprc->filename("PPSTACK.OUTPUT.MASK", $file->{path_base} ); # Mask name
+    my $weightCnv = $ipprc->filename("PPSTACK.OUTPUT.VARIANCE", $file->{path_base} ); # Weight name
+    my $psfCnv    = $ipprc->filename("PSPHOT.PSF.SKY.SAVE", $file->{path_base} ); # PSF name
+
+    my $imageRaw  = $ipprc->filename("PPSTACK.UNCONV", $file->{path_base} ); # Mask name
+    my $maskRaw   = $ipprc->filename("PPSTACK.UNCONV.MASK", $file->{path_base} ); # Mask name
+    my $weightRaw = $ipprc->filename("PPSTACK.UNCONV.VARIANCE", $file->{path_base} ); # Weight name
+
+    my $sources   = $ipprc->filename("PSPHOT.OUT.CMF.MEF", $file->{path_base}); # Sources name
+
+    &my_die("Image $image does not exist", $stack_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists( $image );
+    &my_die("Mask $mask does not exist", $stack_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists( $mask );
+    &my_die("Weight $weight does not exist", $stack_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists( $weight );
+    &my_die("PSF $psf does not exist", $stack_id, $PS_EXIT_SYS_ERROR) if ($convolve and not $ipprc->file_exists( $psf ));
+    &my_die("Sources $sources does not exist", $stack_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists( $sources );
+
+    print $listFile "  RAW:IMAGE     STR  " . $imageRaw  . "\n";
+    print $listFile "  RAW:MASK      STR  " . $maskRaw   . "\n";
+    print $listFile "  RAW:VARIANCE  STR  " . $weightRaw . "\n";
+
+    print $listFile "  CNV:IMAGE     STR  " . $imageCnv  . "\n";
+    print $listFile "  CNV:MASK      STR  " . $maskCnv   . "\n";
+    print $listFile "  CNV:VARIANCE  STR  " . $weightCnv . "\n";
+    print $listFile "  CNV:PSF       STR  " . $psfCnv    . "\n";
+
+    print $listFile "  SOURCES       STR  " . $sources   . "\n";
+
+    print $listFile "END\n\n";
+
+    &my_die("Couldn't find input: $imageRaw",  $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$imageRaw");
+    &my_die("Couldn't find input: $maskRaw",   $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$maskRaw");
+    &my_die("Couldn't find input: $weightRaw", $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$weightRaw");
+    &my_die("Couldn't find input: $imageCnv",  $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$imageCnv");
+    &my_die("Couldn't find input: $maskCnv",   $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$maskCnv");
+    &my_die("Couldn't find input: $weightCnv", $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$weightCnv");
+    &my_die("Couldn't find input: $psfCnv",    $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$psfCnv");
+    &my_die("Couldn't find input: $sources",   $sky_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists("$sources");
+}
+
+# Recipes to use based on reduction class
+$reduction = 'DEFAULT' unless defined $reduction;
+my $recipe_psphot  = $ipprc->reduction($reduction, 'STACKPHOT'); # Recipe to use for psphot
+unless ($recipe_psphot) {
+    &my_die("Couldn't find selected reduction for STACKPHOT: $reduction\n", $sky_id, $PS_EXIT_CONFIG_ERROR);
+}
+
+print "reduction: $reduction\n";
+print "recipe_psphot: $recipe_psphot\n";
+
+# Get the output filenames
+my $outputName = $ipprc->filename("PPSUB.OUTPUT", $outroot);
+my $outputMask = $ipprc->filename("PPSUB.OUTPUT.MASK", $outroot);
+my $outputVariance = $ipprc->filename("PPSUB.OUTPUT.VARIANCE", $outroot);
+my $outputSources = $ipprc->filename("PPSUB.OUTPUT.SOURCES", $outroot);
+my $jpeg1Name = $ipprc->filename("PPSUB.OUTPUT.JPEG1", $outroot);
+my $jpeg2Name = $ipprc->filename("PPSUB.OUTPUT.JPEG2", $outroot);
+my $configuration = $ipprc->filename("PPSUB.CONFIG", $outroot);
+my $outputStats = $ipprc->filename("SKYCELL.STATS", $outroot);
+my $traceDest = $ipprc->filename("TRACE.EXP", $outroot);
+
+if ($run_state eq 'update') {
+    $traceDest .= '.update';
+    $outputStats .= '.update';
+}
+
+my ($inverseName, $inverseMask, $inverseVariance, $inverseSources);
+if ($inverse) {
+    $inverseName = $ipprc->filename("PPSUB.INVERSE", $outroot);
+    $inverseMask = $ipprc->filename("PPSUB.INVERSE.MASK", $outroot);
+    $inverseVariance = $ipprc->filename("PPSUB.INVERSE.VARIANCE", $outroot);
+    $inverseSources = $ipprc->filename("PPSUB.INVERSE.SOURCES", $outroot);
+}
+
+my $cmdflags;
+
+# Perform subtraction
+{
+    my $command = "$ppSub $outroot";
+    $command .= " -inimage $input";
+    $command .= " -refimage $template";
+    $command .= " -inmask $inputMask";
+    $command .= " -refmask $templateMask";
+    $command .= " -invariance $inputVariance";
+    $command .= " -refvariance $templateVariance";
+    $command .= " -insources $inputSources";
+    $command .= " -refsources $templateSources";
+    $command .= " -stats $outputStats";
+    $command .= " -threads $threads" if defined $threads;
+    if ($run_state eq "new") {
+        $command .= " -dumpconfig $configuration";
+    } else {
+        my $configurationReal = $ipprc->file_resolve($configuration) or &my_die("Couldn't resolve configuration file: $configuration", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR);
+        $command .= " -ipprc $configurationReal";
+    }
+    $command .= " -save-inconv" if defined $saveInConv;
+    $command .= " -save-refconv" if defined $saveRefConv;
+    $command .= " -recipe PPSUB $recipe_ppSub";
+    $command .= " -recipe PSPHOT $recipe_psphot";
+    $command .= " -recipe PPSTATS WARPSTATS";
+    $command .= " -F PSPHOT.PSF.SAVE PSPHOT.PSF.SKY.SAVE";
+    $command .= " -F PSPHOT.OUTPUT PSPHOT.OUT.CMF.MEF";
+    $command .= " -F PSPHOT.BACKMDL PSPHOT.BACKMDL.MEF";
+    if ($run_state eq "new") {
+        $command .= " -photometry";
+    }
+    $command .= " -inverse" if $inverse;
+    $command .= " -tracedest $traceDest -log $logDest";
+    $command .= " -dbname $dbname" if defined $dbname;
+    $command .= " -image_id $diff_skyfile_id" if defined $diff_skyfile_id;
+    $command .= " -source_id $source_id" if defined $source_id;
+
+    unless ($no_op) {
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die("Unable to perform ppSub: $error_code", $sky_id, $skycell_id, $error_code);
+        }
+
+        my $outputStatsReal = $ipprc->file_resolve($outputStats);
+        &my_die("Couldn't find expected output file: $outputStats", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($outputStatsReal);
+
+        # measure chip stats
+        $command = "$ppStatsFromMetadata $outputStatsReal - DIFF_SKYCELL";
+        ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            &my_die("Unable to perform ppStatsFromMetadata: $error_code", $sky_id, $skycell_id, $error_code);
+        }
+        foreach my $line (@$stdout_buf) {
+            $cmdflags .= " $line";
+        }
+        chomp $cmdflags;
+
+        my ($quality) = $cmdflags =~ /-quality (\d+)/; # Quality flag
+
+        if (!$quality) {
+            &my_die("Couldn't find expected output file: $outputName", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($outputName);
+            &my_die("Couldn't find expected output file: $outputMask", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($outputMask);
+            &my_die("Couldn't find expected output file: $outputVariance", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($outputVariance);
+            &my_die("Couldn't find expected output file: $outputSources", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($outputSources);
+            &my_die("Couldn't find expected output file: $jpeg1Name",    $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($jpeg1Name);
+            &my_die("Couldn't find expected output file: $jpeg2Name",    $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($jpeg2Name);
+            if ($inverse) {
+                &my_die("Couldn't find expected output file: $inverseName", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($inverseName);
+                &my_die("Couldn't find expected output file: $inverseMask", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($inverseMask);
+                &my_die("Couldn't find expected output file: $inverseVariance", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($inverseVariance);
+                &my_die("Couldn't find expected output file: $inverseSources", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($inverseSources);
+                if ($run_state eq 'new') {
+                    &my_die("Couldn't find expected output file: $configuration", $sky_id, $skycell_id, $PS_EXIT_SYS_ERROR) unless $ipprc->file_exists($configuration);
+                }
+            }
+        }
+    } else {
+        print "Not executing: $command\n";
+    }
+}
+
+unless ($no_update) {
+
+    # Add the subtraction result
+    {
+        my $command = "$difftool -sky_id $sky_id -skycell_id $skycell_id";
+        $command .= " -magicked $magicked" if $magicked;
+        if ($run_state eq 'new') {
+            $command .= " -adddiffskyfile -path_base $outroot";
+            $command .= " $cmdflags";
+            $command .= (" -dtime_script " . ((DateTime->now->mjd - $mjd_start) * 86400));
+            $command .= " -hostname $host" if defined $host;
+        } else {
+            $command .= " -tofullskyfile";
+        }
+        $command .= " -dbname $dbname" if defined $dbname;
+
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+            my $err_message = $run_state eq "update" ?
+                "Unable to perform difftool -adddiffskyfile" :
+                "Unable to perform difftool -tofullskyfile";
+            &my_die("$err_message: $error_code", $sky_id, $skycell_id, $error_code);
+        }
+    }
+}
+
+
+sub my_die
+{
+    my $msg = shift;            # Warning message on die
+    my $sky_id = shift;        # Diff identifier
+    my $exit_code = shift;      # Exit code to add
+
+    $exit_code = $PS_EXIT_PROG_ERROR unless defined $exit_code;
+
+    warn($msg);
+    if (defined $sky_id and defined $skycell_id and not $no_update) {
+        my $command = "$difftool -sky_id $sky_id -skycell_id $skycell_id -fault $exit_code";
+        if ($run_state eq 'new') {
+            $command .= " -adddiffskyfile";
+            $command .= (" -dtime_script " . ((DateTime->now->mjd - $mjd_start) * 86400));
+            $command .= " -hostname $host" if defined $host;
+            $command .= " -path_base $outroot" if defined $outroot;
+            $command .= " -dbname $dbname" if defined $dbname;
+        } else {
+            $command .= " -updatediffskyfile";
+        }
+        run(command => $command, verbose => $verbose);
+    }
+    exit $exit_code;
+}
+
+END {
+    my $exit = $?;
+    system("sync") == 0 or die "failed to execute sync: $!";
+    $? = $exit;
+}
+
+__END__
Index: /branches/pap/ippScripts/scripts/tdl_generate.pl
===================================================================
--- /branches/pap/ippScripts/scripts/tdl_generate.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/tdl_generate.pl	(revision 28003)
@@ -13,6 +13,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 #print "\n\n";
-#print "Starting script $0 on $host\n\n";
+#print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
@@ -58,5 +59,5 @@
 # resolve any path:// or file:// in outroot
 $outroot = $ipprc->file_resolve($outroot);
-    
+
 # Look for programs we need
 my $missing_tools;
Index: /branches/pap/ippScripts/scripts/warp_overlap.pl
===================================================================
--- /branches/pap/ippScripts/scripts/warp_overlap.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/warp_overlap.pl	(revision 28003)
@@ -8,6 +8,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use vars qw( $VERSION );
Index: /branches/pap/ippScripts/scripts/warp_skycell.pl
===================================================================
--- /branches/pap/ippScripts/scripts/warp_skycell.pl	(revision 28002)
+++ /branches/pap/ippScripts/scripts/warp_skycell.pl	(revision 28003)
@@ -7,6 +7,7 @@
 use Sys::Hostname;
 my $host = hostname();
+my $date = `date`;
 print "\n\n";
-print "Starting script $0 on $host\n\n";
+print "Starting script $0 on $host at $date\n\n";
 
 use DateTime;
@@ -299,5 +300,5 @@
             $command .= " -tess_id $tess_dir";
             $command .= " -path_base $outroot"; # needed for logfile lookups
-            $command .= " -magicked $magicked" if $magicked;
+            $command .= " -set_magicked $magicked" if $magicked;
 
             $command .= " -uri $outputImage" if !$quality;
@@ -321,4 +322,5 @@
             $command .= " -warp_id $warp_id";
             $command .= " -skycell_id $skycell_id";
+            $command .= " -set_magicked $magicked" if $magicked;
             $command .= " -dbname $dbname"   if defined $dbname;
 
Index: /branches/pap/ippTasks/camera.pro
===================================================================
--- /branches/pap/ippTasks/camera.pro	(revision 28002)
+++ /branches/pap/ippTasks/camera.pro	(revision 28003)
@@ -154,4 +154,5 @@
     book getword camPendingExp $pageName cam_id -var CAM_ID
     book getword camPendingExp $pageName workdir -var WORKDIR_TEMPLATE
+    book getword camPendingExp $pageName path_base -var PATH_BASE
     book getword camPendingExp $pageName dvodb  -var DVODB
     book getword camPendingExp $pageName dbname -var DBNAME
@@ -173,6 +174,10 @@
     # neb:///ipp004-vol0/gpc1/20080130
 
-    ## generate outroot specific to this exposure (& chip)
-    sprintf outroot "%s/%s/%s.cm.%s" $WORKDIR $EXP_TAG $EXP_TAG $CAM_ID
+    if ("$PATH_BASE" == "NULL") 
+        ## generate outroot specific to this exposure (& chip)
+        sprintf outroot "%s/%s/%s.cm.%s" $WORKDIR $EXP_TAG $EXP_TAG $CAM_ID
+    else
+        $outroot = $PATH_BASE
+    end
 
     stdout $LOGDIR/camera.exp.log
Index: /branches/pap/ippTasks/chip.pro
===================================================================
--- /branches/pap/ippTasks/chip.pro	(revision 28002)
+++ /branches/pap/ippTasks/chip.pro	(revision 28003)
@@ -153,4 +153,5 @@
     book getword chipPendingImfile $pageName reduction -var REDUCTION
     book getword chipPendingImfile $pageName state -var RUN_STATE
+    book getword chipPendingImfile $pageName path_base -var PATH_BASE
 
     if ($RAW_MAGICKED > 0)
@@ -174,6 +175,10 @@
     # neb:///ipp004-vol0/gpc1/20080130
 
-    ## generate outroot specific to this exposure (& chip)
-    sprintf outroot "%s/%s/%s.ch.%s" $WORKDIR $EXP_TAG $EXP_TAG $CHIP_ID
+    if ("$PATH_BASE" == "NULL") 
+        ## generate outroot specific to this exposure (& chip)
+        sprintf outroot "%s/%s/%s.ch.%s" $WORKDIR $EXP_TAG $EXP_TAG $CHIP_ID
+    else
+        $outroot = $PATH_BASE
+    end
 
     stdout $LOGDIR/chip.imfile.log
Index: /branches/pap/ippTasks/destreak.pro
===================================================================
--- /branches/pap/ippTasks/destreak.pro	(revision 28002)
+++ /branches/pap/ippTasks/destreak.pro	(revision 28003)
@@ -37,4 +37,6 @@
     echo magicDSToRevert
     book listbook magicDSToRevert
+    echo magicDSToCleanup
+    book listbook magicDSToCleanup
 end
 
@@ -212,4 +214,5 @@
     book getword magicToDS $pageName recoveryroot -var RECROOT
     book getword magicToDS $pageName re_place -var REPLACE
+    book getword magicToDS $pageName magicked -var MAGICKED
     book getword magicToDS $pageName dbname -var DBNAME
 
@@ -226,5 +229,5 @@
     # TODO: do not add recoveryroot or replace if they are null or zero
 
-    $run = magic_destreak.pl --magic_ds_id $MAGIC_DS_ID --camera $CAMERA --exp_id $EXP_ID --streaks $STREAKS --inv_streaks $INV_STREAKS --stage $STAGE --stage_id $STAGE_ID --component $COMPONENT --uri $URI --path_base $PATH_BASE --cam_path_base $CAM_PATH_BASE --cam_reduction $CAM_REDUCTION --outroot $OUTROOT --logfile $logfile --recoveryroot $RECROOT --replace $REPLACE
+    $run = magic_destreak.pl --magic_ds_id $MAGIC_DS_ID --camera $CAMERA --exp_id $EXP_ID --streaks $STREAKS --inv_streaks $INV_STREAKS --stage $STAGE --stage_id $STAGE_ID --component $COMPONENT --uri $URI --path_base $PATH_BASE --cam_path_base $CAM_PATH_BASE --cam_reduction $CAM_REDUCTION --outroot $OUTROOT --logfile $logfile --recoveryroot $RECROOT --replace $REPLACE --magicked $MAGICKED
 
     add_standard_args run
@@ -273,5 +276,5 @@
   #periods      -exec $LOADEXEC
   periods      -exec 30
-  periods      -timeout 20
+  periods      -timeout 60
   npending     1
 
@@ -412,4 +415,5 @@
     book getword magicDSToRevert $pageName re_place -var REPLACE
     book getword magicDSToRevert $pageName bothways -var BOTHWAYS
+    book getword magicDSToRevert $pageName magicked -var MAGICKED
     book getword magicDSToRevert $pageName dbname -var DBNAME
 
@@ -424,5 +428,5 @@
     end
 
-    $run = magic_destreak_revert.pl --magic_ds_id $MAGIC_DS_ID --camera $CAMERA --stage $STAGE --stage_id $STAGE_ID --component $COMPONENT --path_base $PATH_BASE --cam_path_base $CAM_PATH_BASE --cam_reduction $CAM_REDUCTION --outroot $OUTROOT --logfile $logfile --replace $REPLACE --bothways $BOTHWAYS
+    $run = magic_destreak_revert.pl --magic_ds_id $MAGIC_DS_ID --camera $CAMERA --stage $STAGE --stage_id $STAGE_ID --component $COMPONENT --path_base $PATH_BASE --cam_path_base $CAM_PATH_BASE --cam_reduction $CAM_REDUCTION --outroot $OUTROOT --logfile $logfile --replace $REPLACE --bothways $BOTHWAYS --magicked $MAGICKED
 
     add_standard_args run
Index: /branches/pap/ippTasks/diff.pro
===================================================================
--- /branches/pap/ippTasks/diff.pro	(revision 28002)
+++ /branches/pap/ippTasks/diff.pro	(revision 28003)
@@ -184,4 +184,5 @@
     book getword diffSkyfile $pageName reduction -var REDUCTION
     book getword diffSkyfile $pageName diff_mode -var DIFF_MODE
+    book getword diffSkyfile $pageName path_base -var PATH_BASE
 
     # set the host and workdir based on the skycell hash
@@ -207,5 +208,10 @@
 
     basename $TESS_DIR -var TESS_ID
-    sprintf outroot "%s/%s/%s/%s.%s.%sdif.%s" $WORKDIR $TESS_ID $SKYCELL_ID $TESS_ID $SKYCELL_ID $DIFF_TAG $DIFF_ID
+
+    if ("$PATH_BASE" == "NULL")
+        sprintf outroot "%s/%s/%s/%s.%s.%sdif.%s" $WORKDIR $TESS_ID $SKYCELL_ID $TESS_ID $SKYCELL_ID $DIFF_TAG $DIFF_ID
+    else
+        $outroot = $PATH_BASE
+    end
 
     stdout $LOGDIR/diff.skycell.log
Index: /branches/pap/ippTasks/nightly_stacks.pro
===================================================================
--- /branches/pap/ippTasks/nightly_stacks.pro	(revision 28002)
+++ /branches/pap/ippTasks/nightly_stacks.pro	(revision 28003)
@@ -164,10 +164,12 @@
 
   task.exec
+    stdout $LOGDIR/ns.initday.log
+    stderr $LOGDIR/ns.initday.log
     $today = `date +%Y-%m-%d`
     book newpage nsData $today
     book setword nsData $today nsState NEW
 
-    command echo $today
-#   command automate_stacks.pl --clean_old --date $today
+#    command echo $today
+   command automate_stacks.pl --clean_old --date $today
   end
 
@@ -370,5 +372,5 @@
   periods         -poll $LOADPOLL
   periods         -exec $LOADEXEC
-  periods         -timeout 30
+  periods         -timeout 120
   npending        1
 
@@ -424,5 +426,5 @@
   periods         -poll $LOADPOLL
   periods         -exec $LOADEXEC
-  periods         -timeout 30
+  periods         -timeout 120
   npending        1
 
Index: /branches/pap/ippTasks/pstamp.pro
===================================================================
--- /branches/pap/ippTasks/pstamp.pro	(revision 28002)
+++ /branches/pap/ippTasks/pstamp.pro	(revision 28003)
@@ -13,4 +13,6 @@
 $pstampFin_DB = 0
 $pstampRev_DB = 0
+$pstampDep_DB = 0
+$pstampCleanup_DB = 0
 
 # set PS_DBSERVER if postage stamp database host is not the same as the value for DBSERVER in site.config
@@ -28,8 +30,9 @@
     book init pstampJob
     book init pstampFinish
+    book init pstampDependent
+    book init pstampCleanup
 end
 
 pstamp.reset
-
 
 macro pstamp.on
@@ -57,5 +60,5 @@
         active true
     end
-    task pstamp.job.revert
+    task pstamp.dependent.load
         active true
     end
@@ -89,4 +92,10 @@
         active false
     end
+    task pstamp.dependent.load
+        active false
+    end
+    task pstamp.dependent.run
+        active false
+    end
 end
 
@@ -98,4 +107,20 @@
 macro pstamp.revert.off
     task pstamp.job.revert
+        active false
+    end
+end
+macro pstamp.cleanup.on
+    task pstamp.cleanup.load
+        active true
+    end
+    task pstamp.cleanup.run
+        active true
+    end
+end
+macro pstamp.cleanup.off
+    task pstamp.cleanup.run
+        active false
+    end
+    task pstamp.cleanup.run
         active false
     end
@@ -150,5 +175,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/pstamp.request.load.log
+        stdout NULL
         stderr $LOGSUBDIR/pstamp.request.load.log
         $run = pstamptool -pendingreq
@@ -195,5 +220,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/pstamp.request.run.log
+        stdout NULL
         stderr $LOGSUBDIR/pstamp.request.run.log
         book npages pstampRequest -var N
@@ -208,8 +233,10 @@
         book getword pstampRequest $pageName uri -var URI
         book getword pstampRequest $pageName ds_outProduct -var PRODUCT
+        book getword pstampRequest $pageName outdir -var OUTDIR
+        book getword pstampRequest $pageName label -var LABEL
 
         host anyhost
 
-        $run = pstamp_parser_run.pl --req_id $REQ_ID --uri $URI --product $PRODUCT --redirect-output
+        $run = pstamp_parser_run.pl --req_id $REQ_ID --uri $URI --product $PRODUCT --outdir $OUTDIR --label $LABEL --redirect-output
 
         add_standard_args run
@@ -252,5 +279,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/pstamp.finish.load.log
+        stdout NULL
         stderr $LOGSUBDIR/pstamp.finish.load.log
         $run = pstamptool  -completedreq
@@ -297,5 +324,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/request.finish.run.log
+        stdout NULL
         stderr $LOGSUBDIR/request.finish.run.log
         book npages pstampFinish -var N
@@ -312,6 +339,7 @@
         book getword pstampFinish $pageName name -var REQ_NAME
         book getword pstampFinish $pageName outProduct -var PRODUCT
-
-        $run = request_finish.pl --req_id $REQ_ID --req_type $REQ_TYPE --req_file $URI --req_name $REQ_NAME --product $PRODUCT --redirect-output
+        book getword pstampFinish $pageName outdir -var OUTDIR
+
+        $run = request_finish.pl --req_id $REQ_ID --req_type $REQ_TYPE --req_file $URI --req_name $REQ_NAME --product $PRODUCT --outdir $OUTDIR --redirect-output
 
         add_standard_args run
@@ -354,5 +382,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/pstamp.job.load.log
+        stdout NULL
         stderr $LOGSUBDIR/pstamp.job.load.log
         $run = pstamptool -pendingjob
@@ -402,5 +430,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/pstamp.job.run.log
+        stdout NULL
         stderr $LOGSUBDIR/pstamp.job.run.log
         book npages pstampJob -var N
@@ -480,5 +508,5 @@
 
     task.exec
-        stdout $LOGSUBDIR/pstamp.job.revert.log
+        stdout NULL
         stderr $LOGSUBDIR/pstamp.job.revert.log
         $run = pstamptool -revertjob -all
@@ -512,2 +540,257 @@
 end
 
+task pstamp.dependent.load
+    host        local
+
+    periods     -poll $LOADPOLL
+    # XXX: create a macro for this time
+    periods     -exec 10
+#    periods     -exec $LOADEXEC
+    periods     -timeout 300
+    npending    1
+
+    task.exec
+        stdout NULL
+        stderr $LOGSUBDIR/pstamp.dependent.load.log
+        $run = pstamptool -pendingdependent
+        if ($DB:n == 0)
+            option DEFAULT
+        else
+            option $DB:$pstampDep_DB
+            $run = $run -dbname $DB:$pstampDep_DB $PS_DBSERVER
+            $pstampDep_DB ++
+            if ($pstampDep_DB >= $DB:n) set pstampDep_DB = 0
+        end
+        add_poll_args run
+        add_poll_labels run 
+        command $run
+    end
+
+    task.exit $EXIT_SUCCESS
+        ipptool2book stdout pstampDependent -key dep_id -uniq -setword dbname $options:0 -setword pantaskState INIT
+
+        book npages pstampDependent -var N
+        if ($VERBOSE > 2)
+            book listbook pstampDependent
+        end
+
+        # delete existing entries in the appropriate pantaskStates
+        process_cleanup pstampDependent
+    end
+
+    task.exit   crash
+        showcommand crash
+    end
+
+    task.exit   timeout
+        showcommand timeout
+    end
+
+    task.exit   default
+        showcommand failure
+    end
+
+end
+
+task pstamp.dependent.run
+    periods     -poll $RUNPOLL
+    periods     -exec $RUNEXEC
+    periods     -timeout 300
+
+    task.exec
+        book npages pstampDependent -var N
+        if ($N == 0) 
+            periods -exec $RUNEXEC
+            break
+        end
+        periods -exec 0.05
+        
+        book getpage pstampDependent 0 -var pageName -key pantaskState INIT
+        if ("$pageName" == "NULL") break
+
+        book setword pstampDependent $pageName pantaskState RUN
+        book getword pstampDependent $pageName dep_id     -var DEP_ID
+        book getword pstampDependent $pageName state      -var STATE
+        book getword pstampDependent $pageName stage      -var STAGE
+        book getword pstampDependent $pageName stage_id   -var STAGE_ID
+        book getword pstampDependent $pageName component  -var COMPONENT
+        book getword pstampDependent $pageName imagedb    -var IMAGEDB
+        book getword pstampDependent $pageName rlabel     -var RLABEL
+        book getword pstampDependent $pageName outdir     -var OUTDIR
+        book getword pstampDependent $pageName need_magic -var NEED_MAGIC
+        book getword pstampDependent $pageName dbname     -var DBNAME
+
+        if ($VERBOSE > 1) 
+            book listpage pstampDependent $pageName
+        end
+
+        host anyhost
+
+        if ("$NEED_MAGIC" == "T")
+            $NEED_MAGIC="--need_magic"
+        else
+            $NEED_MAGIC=""
+        end
+
+        $MYLOGFILE = $OUTDIR/checkdep.$DEP_ID.log
+        stdout $MYLOGFILE
+        stderr $MYLOGFILE
+
+        $run = pstamp_checkdependent.pl --dep_id $DEP_ID --stage_id $STAGE_ID --stage $STAGE --component $COMPONENT --imagedb $IMAGEDB --rlabel $RLABEL $NEED_MAGIC
+
+        add_standard_args run
+
+        options $pageName
+
+        if ($VERBOSE > 1) 
+            echo command $run
+        end
+        command $run
+    end
+
+
+    task.exit $EXIT_SUCCESS
+        if ($VERBOSE > 1)
+            echo pstamp.dependent.run task.exit $DEP_ID status: $JOB_STATUS
+        end
+        process_exit pstampDependent $options:0 $JOB_STATUS
+    end
+    task.exit default
+        if ($VERBOSE > 1)
+            echo pstamp.job.run task.exit $DEP_ID status: $JOB_STATUS
+        end
+        showcommand failure
+        process_exit pstampDependent $options:0 $JOB_STATUS
+    end
+
+    task.exit crash
+        echo pstamp.job.run task.crash $DEP_ID status: $JOB_STATUS
+        process_exit pstampDependent $options:0 $JOB_STATUS
+        showcommand crash
+        book setword pstampDependent $options:0 pantaskState CRASH
+    end
+
+    task.exit timeout
+        echo pstamp.job.run task.timeout $DEP_ID status: $JOB_STATUS
+        process_exit pstampDependent $options:0 $JOB_STATUS
+        showcommand timeout
+        book setword pstampDependent $options:0 pantaskState TIMEOUT
+    end
+end
+
+task pstamp.cleanup.load
+    host        local
+
+    periods     -poll $LOADPOLL
+    periods     -exec $LOADEXEC
+    periods     -timeout 300
+    npending    1
+
+    task.exec
+        stdout NULL
+        stderr $LOGSUBDIR/pstamp.cleanup.load.log
+        $run = pstamptool -pendingcleanup
+        if ($DB:n == 0)
+            option DEFAULT
+        else 
+            option $DB:$pstampCleanup_DB
+            $run = $run $PS_DBSERVER -dbname $DB:$pstampCleanup_DB
+            $pstampCleanup_DB ++
+            if ($pstampCleanup_DB >= $DB:n) set pstampCleanup_DB = 0
+        end
+        add_poll_args run
+        add_poll_labels run
+        command $run
+    end
+
+    task.exit $EXIT_SUCCESS
+        ipptool2book stdout pstampCleanup -key req_id -uniq -setword dbname $options:0 -setword pantaskState INIT
+        if ($VERBOSE > 2)
+            echo starting request
+            book listbook pstampCleanup
+        end
+
+        process_cleanup pstampCleanup
+    end
+
+    task.exit   default
+        showcommand failure
+    end
+
+    task.exit   crash
+        showcommand crash
+    end
+
+    task.exit   timeout
+        showcommand timeout
+    end
+end
+
+task pstamp.cleanup.run
+    periods     -poll $RUNPOLL
+    periods     -exec $RUNEXEC
+    periods     -timeout 300
+    # since everything is on one file system keep npending low to avoid
+    # overloading nfs
+
+    npending    10
+
+    task.exec
+        book npages pstampCleanup -var N
+        if ($N == 0) 
+            periods -exec $RUNEXEC
+            break
+        end
+        periods -exec 0.05
+        
+        book getpage pstampCleanup 0 -var pageName -key pantaskState INIT
+        if ("$pageName" == "NULL") break
+
+        book setword pstampCleanup $pageName pantaskState RUN
+        book getword pstampCleanup $pageName req_id -var REQ_ID
+        book getword pstampCleanup $pageName dbname -var DBNAME
+        book getword pstampCleanup $pageName name -var NAME
+        book getword pstampCleanup $pageName outdir -var OUTDIR
+        book getword pstampCleanup $pageName uri -var URI
+        book getword pstampCleanup $pageName reqType -var REQTYPE
+        book getword pstampCleanup $pageName outProduct -var PRODUCT
+
+        # XXX: have the script set this up this
+        $MYLOGFILE=/data/ippdb02.0/pstamp/work/logs/cleanup.$REQ_ID
+        stdout $MYLOGFILE
+        stderr $MYLOGFILE
+
+        host anyhost
+
+        $run = pstamp_cleanup.pl --req_id $REQ_ID --uri $URI --product $PRODUCT --name $NAME --outdir $OUTDIR --reqType $REQTYPE
+
+        add_standard_args run
+        options $pageName
+
+        if ($VERBOSE > 1) 
+            echo command $run
+        end
+        command $run
+    end
+
+
+    task.exit $EXIT_SUCCESS
+        process_exit pstampCleanup $options:0 $JOB_STATUS
+    end
+
+    task.exit default
+        showcommand failure
+        process_exit pstampCleanup $options:0 $JOB_STATUS
+    end
+
+    task.exit crash
+        showcommand crash
+        book setword pstampCleanup $options:0 pantaskState CRASH
+    end
+
+    task.exit timeout
+        showcommand timeout
+        book setword pstampCleanup $options:0 pantaskState TIMEOUT
+    end
+end
+
Index: /branches/pap/ippTasks/simtest.simmosaic.config
===================================================================
--- /branches/pap/ippTasks/simtest.simmosaic.config	(revision 28003)
+++ /branches/pap/ippTasks/simtest.simmosaic.config	(revision 28003)
@@ -0,0 +1,114 @@
+
+CAMERA     STR SIMMOSAIC
+
+FILERULE MULTI
+FILERULE STR    Chip00.fits
+FILERULE STR    Chip01.fits
+FILERULE STR    Chip10.fits
+FILERULE STR    Chip11.fits
+
+# define the simulated data to be generated
+SEQUENCE MULTI
+
+SEQUENCE METADATA
+  OBSTYPE    STR BIAS
+  NIMAGES    S32  20
+END
+
+SEQUENCE METADATA
+  OBSTYPE    STR DARK
+  @EXPTIMES  F32  30.0, 300.0
+  @NIMAGES   S32  10,   10
+END
+
+SEQUENCE METADATA
+  OBSTYPE    STR FLAT
+
+  FILTERS    STR r,r,i
+  @EXPTIMES  F32 0.1,20.0,20.0
+
+  NSETUP     S32 5
+END
+
+SEQUENCE METADATA
+  OBSTYPE    STR FLAT
+
+  FILTERS    STR r,r,r,r,r
+  @EXPTIMES  F32 0.5,1.0,2.0,5.0,10.0
+
+  NSETUP     S32 1
+END
+
+SEQUENCE METADATA
+  OBSTYPE    STR OBJECT
+
+### Carina
+  CENTER.RA  F32 270.75
+  CENTER.DEC F32 -23.7
+### COSMOS field
+#  CENTER.RA  F32 150.119167 
+#  CENTER.DEC F32   2.205833
+
+  OFFSET.RA  F32 3600.0 # linear offset in arcsec (do not include cos(DEC) correction)
+  OFFSET.DEC F32 3600.0 # linear offset in arcsec (do not include cos(DEC) correction)
+  OFFSET.NR  S32 1
+  OFFSET.ND  S32 1
+
+  DITHER.RA  F32 60.0   # linear offset in arcsec (do not include cos(DEC) correction)
+  DITHER.DEC F32 60.0   # linear offset in arcsec (do not include cos(DEC) correction)
+  DITHER.NR  S32 3
+  DITHER.ND  S32 2
+
+  DVODB      STR /data/alala.0/ipp/ippRefs/catdir.synth.simtest 
+  FILTERS    STR r,i
+  @EXPTIMES  F32 10.00,10.00
+  @SKYMAGS   F32 20.86,20.15
+
+  # XXX use a more realistic IQ distribution...
+  IQ_MIN     F32 0.55
+  IQ_MAX     F32 1.25
+  
+  # rotation sequence
+  POS_MIN    F32 0.0
+  POS_MAX    F32 0.0
+  POS_DELTA  F32 1.0
+
+END
+
+
+SEQUENCE METADATA
+  OBSTYPE    STR OBJECT
+
+### Carina
+  CENTER.RA  F32 270.75
+  CENTER.DEC F32 -23.7
+### COSMOS field
+#  CENTER.RA  F32 150.119167 
+#  CENTER.DEC F32   2.205833
+
+  OFFSET.RA  F32 3600.0 # linear offset in arcsec (do not include cos(DEC) correction)
+  OFFSET.DEC F32 3600.0 # linear offset in arcsec (do not include cos(DEC) correction)
+  OFFSET.NR  S32 1
+  OFFSET.ND  S32 1
+
+  DITHER.RA  F32 30.0   # linear offset in arcsec (do not include cos(DEC) correction)
+  DITHER.DEC F32 30.0   # linear offset in arcsec (do not include cos(DEC) correction)
+  DITHER.NR  S32 1
+  DITHER.ND  S32 1
+
+  DVODB      STR /data/alala.0/ipp/ippRefs/catdir.synth.simtest 
+  FILTERS    STR r,r,i,i
+  @EXPTIMES  F32 5.0, 240.0, 5.0, 240.0
+  @SKYMAGS   F32 20.86,20.86,20.15,20.15
+
+  # XXX use a more realistic IQ distribution...
+  IQ_MIN     F32 0.55
+  IQ_MAX     F32 1.25
+  
+  # rotation sequence
+  POS_MIN    F32 0.0
+  POS_MAX    F32 0.0
+  POS_DELTA  F32 1.0
+
+END
+
Index: /branches/pap/ippTasks/stack.pro
===================================================================
--- /branches/pap/ippTasks/stack.pro	(revision 28002)
+++ /branches/pap/ippTasks/stack.pro	(revision 28003)
@@ -116,5 +116,5 @@
     end
     add_poll_args run
-    # add_poll_labels run
+    add_poll_labels run
     command $run
   end
@@ -172,4 +172,5 @@
     book getword stackSumSkyfile $pageName skycell_id -var SKYCELL_ID
     book getword stackSumSkyfile $pageName workdir -var WORKDIR_TEMPLATE
+    book getword stackSumSkyfile $pageName path_base -var PATH_BASE
     book getword stackSumSkyfile $pageName reduction -var REDUCTION
     book getword stackSumSkyfile $pageName dbname -var DBNAME
@@ -185,5 +186,9 @@
 
     basename $TESS_DIR -var TESS_ID
-    sprintf outroot "%s/%s/%s/%s.%s.stk.%s" $WORKDIR $TESS_ID $SKYCELL_ID $TESS_ID $SKYCELL_ID $STACK_ID
+    if ("$PATH_BASE" == "NULL")
+        sprintf outroot "%s/%s/%s/%s.%s.stk.%s" $WORKDIR $TESS_ID $SKYCELL_ID $TESS_ID $SKYCELL_ID $STACK_ID
+    else
+        $outroot = $PATH_BASE
+    end
 
     stdout $LOGDIR/stack.skycell.log
Index: /branches/pap/ippTasks/summit.copy.pro
===================================================================
--- /branches/pap/ippTasks/summit.copy.pro	(revision 28002)
+++ /branches/pap/ippTasks/summit.copy.pro	(revision 28003)
@@ -107,6 +107,9 @@
     periods      -timeout   20
     npending     1
-    # trange       16:00 23:59
-    # trange       00:00 04:00
+
+    # only active in the day (06:00 to 19:00 HST, times are UT):
+    trange        -reset
+    # trange        16:00 23:59
+    # trange        00:00 05:00
 
     task.exec
@@ -153,11 +156,15 @@
 # and inserting these into a db table on the local cluster (pzDownloadExp)
 task pzgetexp
+  host         local
+
   periods      -exec     30
   periods      -poll     1
   periods      -timeout  700
-  # trage       16:00 23:59
-  # trage       00:00 04:00
   npending      1
-  host         local
+
+  # only active in the day (06:00 to 19:00 HST, times are UT):
+  trange        -reset
+  # trange        16:00 23:59
+  # trange        00:00 05:00
 
   task.exec
@@ -213,7 +220,10 @@
     periods      -poll     1
     periods      -timeout  20
-    # trange       16:00 23:59
-    # trange       00:00 04:00
     npending     1
+
+    # only active in the day (06:00 to 19:00 HST, times are UT):
+    trange        -reset
+    # trange        16:00 23:59
+    # trange        00:00 05:00
 
     task.exec
@@ -224,5 +234,5 @@
         # save the DB name for the exit tasks
         option $DB:$pztoolPendingExp_DB
-        command pztool -pendingexp -limit 5 -dbname $DB:$pztoolPendingExp_DB
+        command pztool -pendingexp -limit 10 -dbname $DB:$pztoolPendingExp_DB
         $pztoolPendingExp_DB ++
         if ($pztoolPendingExp_DB >= $DB:n) set pztoolPendingExp_DB = 0
@@ -261,11 +271,15 @@
 # database table of imfiles
 task pzgetimfile 
+    host 	local
+
     periods      -exec     0.05
     periods      -poll     0.025
     periods      -timeout  700
-    # trage       16:00 23:59
-    # trage       00:00 04:00
-    host 	local
     npending 	10
+
+    # only active in the day (06:00 to 19:00 HST, times are UT):
+    trange        -reset
+    # trange        16:00 23:59
+    # trange        00:00 05:00
 
     task.exec
@@ -336,10 +350,13 @@
     host         local
 
-    periods      -exec     30
+    periods      -exec     10
     periods      -poll      1
     periods      -timeout  120
-    # trage       16:00 23:59
-    # trage       00:00 04:00
     npending     1
+
+    # only active in the day (06:00 to 19:00 HST, times are UT):
+    trange        -reset
+    # trange        16:00 23:59
+    # trange        00:00 05:00
 
     # select entries from the current DB; cycle to the next DB, if it exists
@@ -352,5 +369,5 @@
         # save the DB name for the exit tasks
         option $DB:$pztoolPendingImfile_DB
-        command pztool -pendingimfile -limit 60 -dbname $DB:$pztoolPendingImfile_DB
+        command pztool -pendingimfile -limit 240 -dbname $DB:$pztoolPendingImfile_DB
         $pztoolPendingImfile_DB ++
         if ($pztoolPendingImfile_DB >= $DB:n) set pztoolPendingImfile_DB = 0
@@ -384,10 +401,9 @@
     periods      -poll     0.05
     periods      -timeout  1150
+
+    # only active in the day (06:00 to 19:00 HST, times are UT):
     trange        -reset
-    # only active in the night (18:00 to 06:00 HST, times are UT):
-    # trange      04:00 16:00
-    # only active in the day (06:00 to 18:00 HST, times are UT):
     # trange        16:00 23:59
-    # trange        00:00 04:00
+    # trange        00:00 05:00
 
     task.exec
@@ -548,6 +564,4 @@
     periods      -poll      1
     periods      -timeout  120
-    # trage       16:00 23:59
-    # trage       00:00 04:00
     npending     1
 
@@ -592,6 +606,4 @@
     periods      -poll     0.05
     periods      -timeout  650
-    # trage       16:00 23:59
-    # trage       00:00 04:00
 
     task.exec
Index: /branches/pap/ippTasks/warp.pro
===================================================================
--- /branches/pap/ippTasks/warp.pro	(revision 28002)
+++ /branches/pap/ippTasks/warp.pro	(revision 28003)
@@ -314,4 +314,5 @@
     book getword warpPendingSkyCell $pageName camera -var CAMERA
     book getword warpPendingSkyCell $pageName workdir -var WORKDIR_TEMPLATE
+    book getword warpPendingSkyCell $pageName path-base -var PATH_BASE
     book getword warpPendingSkyCell $pageName dbname -var DBNAME
     # XXX change tess_id to tess_dir when schema is changed
@@ -331,6 +332,10 @@
     set.workdir.by.skycell $SKYCELL_ID $WORKDIR_TEMPLATE $default_host WORKDIR
 
-    ## generate outroot specific to this exposure
-    sprintf outroot "%s/%s/%s.wrp.%s.%s" $WORKDIR $EXP_TAG $EXP_TAG $WARP_ID $SKYCELL_ID
+    if ("$PATH_BASE" == "NULL") 
+        ## generate outroot specific to this exposure
+        sprintf outroot "%s/%s/%s.wrp.%s.%s" $WORKDIR $EXP_TAG $EXP_TAG $WARP_ID $SKYCELL_ID
+    else 
+        $outroot = $PATH_BASE
+    end
 
     stdout $LOGDIR/warp.skycell.log
Index: /branches/pap/ippToPsps/config/currentJobId.txt
===================================================================
--- /branches/pap/ippToPsps/config/currentJobId.txt	(revision 28002)
+++ /branches/pap/ippToPsps/config/currentJobId.txt	(revision 28003)
@@ -1,1 +1,1 @@
-733
+5580
Index: /branches/pap/ippToPsps/config/detection/map.xml
===================================================================
--- /branches/pap/ippToPsps/config/detection/map.xml	(revision 28002)
+++ /branches/pap/ippToPsps/config/detection/map.xml	(revision 28003)
@@ -5,34 +5,36 @@
  <table name="FrameMeta">
   <map ippName="ZPT_ERR" ippType="TFLOAT" pspsName="photoScat" />
-  <map ippName="MJD-OBS" ippType="TFLOAT" pspsName="expStart" />
+  <map ippName="MJD-OBS" ippType="TDOUBLE" pspsName="expStart" />
   <map ippName="EXPREQ" ippType="TFLOAT" pspsName="expTime" />
   <map ippName="AIRMASS" ippType="TFLOAT" pspsName="airmass" />
-  <map ippName="RA" ippType="TFLOAT" pspsName="raBore" />
-  <map ippName="DEC" ippType="TFLOAT" pspsName="decBore" />
+  <map ippName="RA" ippType="TDOUBLE" pspsName="raBore" />
+  <map ippName="DEC" ippType="TDOUBLE" pspsName="decBore" />
   <map ippName="CTYPE1" ippType="TSTRING" pspsName="ctype1" />
   <map ippName="CTYPE2" ippType="TSTRING" pspsName="ctype2" />
-  <map ippName="CRVAL1" ippType="TFLOAT" pspsName="crval1" />
-  <map ippName="CRVAL2" ippType="TFLOAT" pspsName="crval2" />
-  <map ippName="CRPIX1" ippType="TFLOAT" pspsName="crpix1" />
-  <map ippName="CRPIX2" ippType="TFLOAT" pspsName="crpix2" />
-  <map ippName="PC001001" ippType="TFLOAT" pspsName="pc001001" />
-  <map ippName="PC001002" ippType="TFLOAT" pspsName="pc001002" />
-  <map ippName="PC002001" ippType="TFLOAT" pspsName="pc002001" />
-  <map ippName="PC002002" ippType="TFLOAT" pspsName="pc002002" />
+  <map ippName="CRVAL1" ippType="TDOUBLE" pspsName="crval1" />
+  <map ippName="CRVAL2" ippType="TDOUBLE" pspsName="crval2" />
+  <map ippName="CRPIX1" ippType="TDOUBLE" pspsName="crpix1" />
+  <map ippName="CRPIX2" ippType="TDOUBLE" pspsName="crpix2" />
+  <map ippName="CDELT1" ippType="TDOUBLE" pspsName="cdelt1" />
+  <map ippName="CDELT2" ippType="TDOUBLE" pspsName="cdelt2" />
+  <map ippName="PC001001" ippType="TDOUBLE" pspsName="pc001001" />
+  <map ippName="PC001002" ippType="TDOUBLE" pspsName="pc001002" />
+  <map ippName="PC002001" ippType="TDOUBLE" pspsName="pc002001" />
+  <map ippName="PC002002" ippType="TDOUBLE" pspsName="pc002002" />
   <map ippName="NPLYTERM" ippType="TBYTE" pspsName="polyOrder" />
-  <map ippName="PCA1X3Y0" ippType="TFLOAT" pspsName="pca1x3y0" />
-  <map ippName="PCA1X2Y1" ippType="TFLOAT" pspsName="pca1x2y1" />
-  <map ippName="PCA1X1Y2" ippType="TFLOAT" pspsName="pca1x1y2" />
-  <map ippName="PCA1X0Y3" ippType="TFLOAT" pspsName="pca1x0y3" />
-  <map ippName="PCA1X2Y0" ippType="TFLOAT" pspsName="pca1x2y0" />
-  <map ippName="PCA1X1Y1" ippType="TFLOAT" pspsName="pca1x1y1" />
-  <map ippName="PCA1X0Y2" ippType="TFLOAT" pspsName="pca1x0y2" />
-  <map ippName="PCA2X3Y0" ippType="TFLOAT" pspsName="pca2x3y0" />
-  <map ippName="PCA2X2Y1" ippType="TFLOAT" pspsName="pca2x2y1" />
-  <map ippName="PCA2X1Y2" ippType="TFLOAT" pspsName="pca2x1y2" />
-  <map ippName="PCA2X0Y3" ippType="TFLOAT" pspsName="pca2x0y3" />
-  <map ippName="PCA2X2Y0" ippType="TFLOAT" pspsName="pca2x2y0" />
-  <map ippName="PCA2X1Y1" ippType="TFLOAT" pspsName="pca2x1y1" />
-  <map ippName="PCA2X0Y2" ippType="TFLOAT" pspsName="pca2x0y2" />
+  <map ippName="PCA1X3Y0" ippType="TDOUBLE" pspsName="pca1x3y0" />
+  <map ippName="PCA1X2Y1" ippType="TDOUBLE" pspsName="pca1x2y1" />
+  <map ippName="PCA1X1Y2" ippType="TDOUBLE" pspsName="pca1x1y2" />
+  <map ippName="PCA1X0Y3" ippType="TDOUBLE" pspsName="pca1x0y3" />
+  <map ippName="PCA1X2Y0" ippType="TDOUBLE" pspsName="pca1x2y0" />
+  <map ippName="PCA1X1Y1" ippType="TDOUBLE" pspsName="pca1x1y1" />
+  <map ippName="PCA1X0Y2" ippType="TDOUBLE" pspsName="pca1x0y2" />
+  <map ippName="PCA2X3Y0" ippType="TDOUBLE" pspsName="pca2x3y0" />
+  <map ippName="PCA2X2Y1" ippType="TDOUBLE" pspsName="pca2x2y1" />
+  <map ippName="PCA2X1Y2" ippType="TDOUBLE" pspsName="pca2x1y2" />
+  <map ippName="PCA2X0Y3" ippType="TDOUBLE" pspsName="pca2x0y3" />
+  <map ippName="PCA2X2Y0" ippType="TDOUBLE" pspsName="pca2x2y0" />
+  <map ippName="PCA2X1Y1" ippType="TDOUBLE" pspsName="pca2x1y1" />
+  <map ippName="PCA2X0Y2" ippType="TDOUBLE" pspsName="pca2x0y2" />
  </table>
 
@@ -48,7 +50,7 @@
   <map ippName="FWHM_MAJ" ippType="TFLOAT" pspsName="psfWidMajor" />
   <map ippName="FWHM_MIN" ippType="TFLOAT" pspsName="psfWidMinor" />
+  <map ippName="ANGLE" ippType="TFLOAT" pspsName="psfTheta" />
   <map ippName="IQ_FW1" ippType="TFLOAT" pspsName="momentWidMajor" />
   <map ippName="IQ_FW2" ippType="TFLOAT" pspsName="momentWidMinor" />
-  <map ippName="ANGLE" ippType="TFLOAT" pspsName="psfTheta" />
   <map ippName="APMIFIT" ippType="TFLOAT" pspsName="apResid" />
   <map ippName="DAPMIFIT" ippType="TFLOAT" pspsName="dapResid" />
@@ -59,27 +61,29 @@
   <map ippName="CTYPE1" ippType="TSTRING" pspsName="ctype1" />
   <map ippName="CTYPE2" ippType="TSTRING" pspsName="ctype2" />
-  <map ippName="CRVAL1" ippType="TFLOAT" pspsName="crval1" />
-  <map ippName="CRVAL2" ippType="TFLOAT" pspsName="crval2" />
-  <map ippName="CRPIX1" ippType="TFLOAT" pspsName="crpix1" />
-  <map ippName="CRPIX2" ippType="TFLOAT" pspsName="crpix2" />
-  <map ippName="PC001001" ippType="TFLOAT" pspsName="pc001001" />
-  <map ippName="PC001002" ippType="TFLOAT" pspsName="pc001002" />
-  <map ippName="PC002001" ippType="TFLOAT" pspsName="pc002001" />
-  <map ippName="PC002002" ippType="TFLOAT" pspsName="pc002002" />
+  <map ippName="CRVAL1" ippType="TDOUBLE" pspsName="crval1" />
+  <map ippName="CRVAL2" ippType="TDOUBLE" pspsName="crval2" />
+  <map ippName="CRPIX1" ippType="TDOUBLE" pspsName="crpix1" />
+  <map ippName="CRPIX2" ippType="TDOUBLE" pspsName="crpix2" />
+  <map ippName="CDELT1" ippType="TDOUBLE" pspsName="cdelt1" />
+  <map ippName="CDELT2" ippType="TDOUBLE" pspsName="cdelt2" />
+  <map ippName="PC001001" ippType="TDOUBLE" pspsName="pc001001" />
+  <map ippName="PC001002" ippType="TDOUBLE" pspsName="pc001002" />
+  <map ippName="PC002001" ippType="TDOUBLE" pspsName="pc002001" />
+  <map ippName="PC002002" ippType="TDOUBLE" pspsName="pc002002" />
   <map ippName="NPLYTERM" ippType="TBYTE" pspsName="polyOrder" />
-  <map ippName="PCA1X3Y0" ippType="TFLOAT" pspsName="pca1x3y0" />
-  <map ippName="PCA1X2Y1" ippType="TFLOAT" pspsName="pca1x2y1" />
-  <map ippName="PCA1X1Y2" ippType="TFLOAT" pspsName="pca1x1y2" />
-  <map ippName="PCA1X0Y3" ippType="TFLOAT" pspsName="pca1x0y3" />
-  <map ippName="PCA1X2Y0" ippType="TFLOAT" pspsName="pca1x2y0" />
-  <map ippName="PCA1X1Y1" ippType="TFLOAT" pspsName="pca1x1y1" />
-  <map ippName="PCA1X0Y2" ippType="TFLOAT" pspsName="pca1x0y2" />
-  <map ippName="PCA2X3Y0" ippType="TFLOAT" pspsName="pca2x3y0" />
-  <map ippName="PCA2X2Y1" ippType="TFLOAT" pspsName="pca2x2y1" />
-  <map ippName="PCA2X1Y2" ippType="TFLOAT" pspsName="pca2x1y2" />
-  <map ippName="PCA2X0Y3" ippType="TFLOAT" pspsName="pca2x0y3" />
-  <map ippName="PCA2X2Y0" ippType="TFLOAT" pspsName="pca2x2y0" />
-  <map ippName="PCA2X1Y1" ippType="TFLOAT" pspsName="pca2x1y1" />
-  <map ippName="PCA2X0Y2" ippType="TFLOAT" pspsName="pca2x0y2" />
+  <map ippName="PCA1X3Y0" ippType="TDOUBLE" pspsName="pca1x3y0" />
+  <map ippName="PCA1X2Y1" ippType="TDOUBLE" pspsName="pca1x2y1" />
+  <map ippName="PCA1X1Y2" ippType="TDOUBLE" pspsName="pca1x1y2" />
+  <map ippName="PCA1X0Y3" ippType="TDOUBLE" pspsName="pca1x0y3" />
+  <map ippName="PCA1X2Y0" ippType="TDOUBLE" pspsName="pca1x2y0" />
+  <map ippName="PCA1X1Y1" ippType="TDOUBLE" pspsName="pca1x1y1" />
+  <map ippName="PCA1X0Y2" ippType="TDOUBLE" pspsName="pca1x0y2" />
+  <map ippName="PCA2X3Y0" ippType="TDOUBLE" pspsName="pca2x3y0" />
+  <map ippName="PCA2X2Y1" ippType="TDOUBLE" pspsName="pca2x2y1" />
+  <map ippName="PCA2X1Y2" ippType="TDOUBLE" pspsName="pca2x1y2" />
+  <map ippName="PCA2X0Y3" ippType="TDOUBLE" pspsName="pca2x0y3" />
+  <map ippName="PCA2X2Y0" ippType="TDOUBLE" pspsName="pca2x2y0" />
+  <map ippName="PCA2X1Y1" ippType="TDOUBLE" pspsName="pca2x1y1" />
+  <map ippName="PCA2X0Y2" ippType="TDOUBLE" pspsName="pca2x0y2" />
  </table>
 
Index: /branches/pap/ippToPsps/config/detection/tables.xml
===================================================================
--- /branches/pap/ippToPsps/config/detection/tables.xml	(revision 28002)
+++ /branches/pap/ippToPsps/config/detection/tables.xml	(revision 28003)
@@ -17,34 +17,36 @@
     <column name="photoScat" type="TFLOAT" default="-999" comment=" global photometric scatter (unit = mag)"></column>
     <column name="numPhotoRef" type="TLONG" default="-999" comment="number of photometric reference sources"></column>
-    <column name="expStart" type="TFLOAT" default="-999" comment=" exposure start time in MJD (unit = day)"></column>
+    <column name="expStart" type="TDOUBLE" default="-999" comment=" exposure start time in MJD (unit = day)"></column>
     <column name="expTime" type="TFLOAT" default="-999" comment=" exposure time (unit = s)"></column>
     <column name="airmass" type="TFLOAT" default="-999" comment="airmass at mid-exposure"></column>
-    <column name="raBore" type="TFLOAT" default="-999" comment=" RA of telescope boresight (unit = deg)"></column>
-    <column name="decBore" type="TFLOAT" default="-999" comment=" DEC of telescope boresight (unit = deg)"></column>
+    <column name="raBore" type="TDOUBLE" default="-999" comment=" RA of telescope boresight (unit = deg)"></column>
+    <column name="decBore" type="TDOUBLE" default="-999" comment=" DEC of telescope boresight (unit = deg)"></column>
     <column name="ctype1" type="TSTRING" default=" " comment="name of astrometric projection in RA"></column>
     <column name="ctype2" type="TSTRING" default=" " comment="name of astrometric projection in DEC"></column>
-    <column name="crval1" type="TFLOAT" default="-999" comment=" RA corresponding to reference pixel (unit = deg)"></column>
-    <column name="crval2" type="TFLOAT" default="-999" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
-    <column name="crpix1" type="TFLOAT" default="-999" comment="reference pixel value for RA"></column>
-    <column name="crpix2" type="TFLOAT" default="-999" comment="reference pixel value for DEC"></column>
-    <column name="pc001001" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc001002" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc002001" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc002002" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="crval1" type="TDOUBLE" default="-999" comment=" RA corresponding to reference pixel (unit = deg)"></column>
+    <column name="crval2" type="TDOUBLE" default="-999" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
+    <column name="crpix1" type="TDOUBLE" default="-999" comment="reference pixel value for RA"></column>
+    <column name="crpix2" type="TDOUBLE" default="-999" comment="reference pixel value for DEC"></column>
+    <column name="cdelt1" type="TDOUBLE" default="-999" comment="scale factor for RA"></column>
+    <column name="cdelt2" type="TDOUBLE" default="-999" comment="scale factor for DEC"></column>
+    <column name="pc001001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc001002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
     <column name="polyOrder" type="TBYTE" default="255" comment="polynomial order of astrometry fit"></column>
-    <column name="pca1x3y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x2y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x1y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x0y3" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x2y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x1y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x0y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x3y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x2y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x1y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x0y3" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x2y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x1y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x0y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
     <column name="calibModNum" type="TSHORT" default="0" comment="calibration modification number"></column>
     <column name="dataRelease" type="TBYTE" default="0" comment="Data release"></column>
@@ -93,27 +95,29 @@
     <column name="ctype1" type="TSTRING" default=" " comment="name of astrometric projection in RA"></column>
     <column name="ctype2" type="TSTRING" default=" " comment="name of astrometric projection in DEC"></column>
-    <column name="crval1" type="TFLOAT" default="-999" comment=" RA corresponding to reference pixel (unit = deg)"></column>
-    <column name="crval2" type="TFLOAT" default="-999" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
-    <column name="crpix1" type="TFLOAT" default="-999" comment=" reference pixel value for RA (unit = pix)"></column>
-    <column name="crpix2" type="TFLOAT" default="-999" comment=" reference pixel value for DEC (unit = pix)"></column>
-    <column name="pc001001" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc001002" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc002001" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc002002" type="TFLOAT" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="crval1" type="TDOUBLE" default="-999" comment=" RA corresponding to reference pixel (unit = deg)"></column>
+    <column name="crval2" type="TDOUBLE" default="-999" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
+    <column name="crpix1" type="TDOUBLE" default="-999" comment=" reference pixel value for RA (unit = pix)"></column>
+    <column name="crpix2" type="TDOUBLE" default="-999" comment=" reference pixel value for DEC (unit = pix)"></column>
+    <column name="cdelt1" type="TDOUBLE" default="-999" comment="scale factor for RA"></column>
+    <column name="cdelt2" type="TDOUBLE" default="-999" comment="scale factor for DEC"></column>
+    <column name="pc001001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc001002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
     <column name="polyOrder" type="TBYTE" default="255" comment="polynomial order of astrometry fit"></column>
-    <column name="pca1x3y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x2y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x1y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x0y3" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x2y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x1y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca1x0y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x3y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x2y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x1y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x0y3" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x2y0" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x1y1" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
-    <column name="pca2x0y2" type="TFLOAT" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
     <column name="calibModNum" type="TSHORT" default="0" comment="calibration modification number"></column>
     <column name="dataRelease" type="TBYTE" default="0" comment="Data release"></column>
@@ -127,5 +131,5 @@
     <column name="surveyID" type="TBYTE" default="0" comment="survey flag identifier"></column>
     <column name="imageID" type="TLONGLONG" default="0" comment="image id hash of frame identifier &amp; OTA/CCD number"></column>
-    <column name="obsTime" type="TFLOAT" default="-999" comment=" Time of mid observation (unit = day)"></column>
+    <column name="obsTime" type="TDOUBLE" default="-999" comment=" Time of mid observation (unit = day)"></column>
     <column name="xPos" type="TFLOAT" default="-999" comment=" measured x on CCD from PSF fit (unit = pix)"></column>
     <column name="yPos" type="TFLOAT" default="-999" comment=" measured y on CCD from PSF fit (unit = pix)"></column>
Index: /branches/pap/ippToPsps/config/init/data.xml
===================================================================
--- /branches/pap/ippToPsps/config/init/data.xml	(revision 28002)
+++ /branches/pap/ippToPsps/config/init/data.xml	(revision 28003)
@@ -31,5 +31,5 @@
   <table name="Survey">
    <row surveyID="0" description="PS1 3PI Survey" />
-   <row surveyID="1" description="S1 MD01 XMM-LSS-DXS 022224-043000" />
+   <row surveyID="1" description="PS1 MD01 XMM-LSS-DXS 022224-043000" />
    <row surveyID="2" description="PS1 MD02 CDFS/GOODS/GEMS 033224-274800" />
    <row surveyID="3" description="PS1 MD03 IFA/Lynx 084300+444000" />
@@ -64,13 +64,4 @@
    <row cameraID="1" cameraConfigID="1" startDate="54000.0" />
    <row cameraID="1" cameraConfigID="2" startDate="54000.0" configDetails="f0123456789abcde"/>
-  </table>
-
-  <table name="PhotoCal">
-   <row photoCalID="0" filterID="1" photoCodeDesc="g filter calibration" AB="1.1" zeropoint="26.09" extinction="0.090" colorterm="0.021" colorExtn="-0.020" orphanCalColor="0.40" orphanCalColorErr="0.01" startDate="54000."/>
-   <row photoCalID="1" filterID="1" photoCodeDesc="g filter calibration" AB="1.1" zeropoint="26.09" extinction="0.090" colorterm="0.021" colorExtn="-0.020" orphanCalColor="0.40" orphanCalColorErr="0.01" startDate="54000."/>
-   <row photoCalID="2" filterID="2" photoCodeDesc="r filter calibration" AB="1.2" zeropoint="25.06" extinction="0.065" colorterm="0.014" colorExtn="-0.005" orphanCalColor="0.45" orphanCalColorErr="0.02" startDate="54000."/>
-   <row photoCalID="3" filterID="3" photoCodeDesc="i filter calibration" AB="1.3" zeropoint="24.00" extinction="0.046" colorterm="0.003" colorExtn="0.000" orphanCalColor="0.50" orphanCalColorErr="0.03" startDate="54000."/>
-   <row photoCalID="4" filterID="4" photoCodeDesc="z filter calibration" AB="1.4" zeropoint="23.59" extinction="0.040" colorterm="-0.010" colorExtn="0.010" orphanCalColor="0.55" orphanCalColorErr="0.04" startDate="54000."/>
-   <row photoCalID="5" filterID="5" photoCodeDesc="y filter calibration" AB="1.5" zeropoint="22.25" extinction="0.031" colorterm="-0.050" colorExtn="0.009" orphanCalColor="0.60" orphanCalColorErr="0.05" startDate="54000."/>
   </table>
 
@@ -101472,6 +101463,314 @@
   <row stackTypeID="9" description="stack type 9" />
   <row stackTypeID="10" description="stack type 10" />
- </table>
+  </table>
 
-</tabledata>
+  <table name="PhotoCal">
+  <row photoCalID="10001" filterID="1" photoCodeDesc="GPC1.g.XY01" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10002" filterID="1" photoCodeDesc="GPC1.g.XY02" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10003" filterID="1" photoCodeDesc="GPC1.g.XY03" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10004" filterID="1" photoCodeDesc="GPC1.g.XY04" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10005" filterID="1" photoCodeDesc="GPC1.g.XY05" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10006" filterID="1" photoCodeDesc="GPC1.g.XY06" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10010" filterID="1" photoCodeDesc="GPC1.g.XY10" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10011" filterID="1" photoCodeDesc="GPC1.g.XY11" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10012" filterID="1" photoCodeDesc="GPC1.g.XY12" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10013" filterID="1" photoCodeDesc="GPC1.g.XY13" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10014" filterID="1" photoCodeDesc="GPC1.g.XY14" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10015" filterID="1" photoCodeDesc="GPC1.g.XY15" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10016" filterID="1" photoCodeDesc="GPC1.g.XY16" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10017" filterID="1" photoCodeDesc="GPC1.g.XY17" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10020" filterID="1" photoCodeDesc="GPC1.g.XY20" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10021" filterID="1" photoCodeDesc="GPC1.g.XY21" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10022" filterID="1" photoCodeDesc="GPC1.g.XY22" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10023" filterID="1" photoCodeDesc="GPC1.g.XY23" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10024" filterID="1" photoCodeDesc="GPC1.g.XY24" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10025" filterID="1" photoCodeDesc="GPC1.g.XY25" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10026" filterID="1" photoCodeDesc="GPC1.g.XY26" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10027" filterID="1" photoCodeDesc="GPC1.g.XY27" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10030" filterID="1" photoCodeDesc="GPC1.g.XY30" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10031" filterID="1" photoCodeDesc="GPC1.g.XY31" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10032" filterID="1" photoCodeDesc="GPC1.g.XY32" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10033" filterID="1" photoCodeDesc="GPC1.g.XY33" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10034" filterID="1" photoCodeDesc="GPC1.g.XY34" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10035" filterID="1" photoCodeDesc="GPC1.g.XY35" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10036" filterID="1" photoCodeDesc="GPC1.g.XY36" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10037" filterID="1" photoCodeDesc="GPC1.g.XY37" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10040" filterID="1" photoCodeDesc="GPC1.g.XY40" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10041" filterID="1" photoCodeDesc="GPC1.g.XY41" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10042" filterID="1" photoCodeDesc="GPC1.g.XY42" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10043" filterID="1" photoCodeDesc="GPC1.g.XY43" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10044" filterID="1" photoCodeDesc="GPC1.g.XY44" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10045" filterID="1" photoCodeDesc="GPC1.g.XY45" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10046" filterID="1" photoCodeDesc="GPC1.g.XY46" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10047" filterID="1" photoCodeDesc="GPC1.g.XY47" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10050" filterID="1" photoCodeDesc="GPC1.g.XY50" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10051" filterID="1" photoCodeDesc="GPC1.g.XY51" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10052" filterID="1" photoCodeDesc="GPC1.g.XY52" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10053" filterID="1" photoCodeDesc="GPC1.g.XY53" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10054" filterID="1" photoCodeDesc="GPC1.g.XY54" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10055" filterID="1" photoCodeDesc="GPC1.g.XY55" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10056" filterID="1" photoCodeDesc="GPC1.g.XY56" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10057" filterID="1" photoCodeDesc="GPC1.g.XY57" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10060" filterID="1" photoCodeDesc="GPC1.g.XY60" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10061" filterID="1" photoCodeDesc="GPC1.g.XY61" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10062" filterID="1" photoCodeDesc="GPC1.g.XY62" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10063" filterID="1" photoCodeDesc="GPC1.g.XY63" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10064" filterID="1" photoCodeDesc="GPC1.g.XY64" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10065" filterID="1" photoCodeDesc="GPC1.g.XY65" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10066" filterID="1" photoCodeDesc="GPC1.g.XY66" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10067" filterID="1" photoCodeDesc="GPC1.g.XY67" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10071" filterID="1" photoCodeDesc="GPC1.g.XY71" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10072" filterID="1" photoCodeDesc="GPC1.g.XY72" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10073" filterID="1" photoCodeDesc="GPC1.g.XY73" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10074" filterID="1" photoCodeDesc="GPC1.g.XY74" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10075" filterID="1" photoCodeDesc="GPC1.g.XY75" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10076" filterID="1" photoCodeDesc="GPC1.g.XY76" AB="0.0" zeropoint="24.580" extinction="-0.150" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10101" filterID="2" photoCodeDesc="GPC1.r.XY01" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10102" filterID="2" photoCodeDesc="GPC1.r.XY02" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10103" filterID="2" photoCodeDesc="GPC1.r.XY03" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10104" filterID="2" photoCodeDesc="GPC1.r.XY04" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10105" filterID="2" photoCodeDesc="GPC1.r.XY05" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10106" filterID="2" photoCodeDesc="GPC1.r.XY06" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10110" filterID="2" photoCodeDesc="GPC1.r.XY10" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10111" filterID="2" photoCodeDesc="GPC1.r.XY11" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10112" filterID="2" photoCodeDesc="GPC1.r.XY12" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10113" filterID="2" photoCodeDesc="GPC1.r.XY13" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10114" filterID="2" photoCodeDesc="GPC1.r.XY14" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10115" filterID="2" photoCodeDesc="GPC1.r.XY15" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10116" filterID="2" photoCodeDesc="GPC1.r.XY16" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10117" filterID="2" photoCodeDesc="GPC1.r.XY17" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10120" filterID="2" photoCodeDesc="GPC1.r.XY20" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10121" filterID="2" photoCodeDesc="GPC1.r.XY21" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10122" filterID="2" photoCodeDesc="GPC1.r.XY22" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10123" filterID="2" photoCodeDesc="GPC1.r.XY23" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10124" filterID="2" photoCodeDesc="GPC1.r.XY24" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10125" filterID="2" photoCodeDesc="GPC1.r.XY25" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10126" filterID="2" photoCodeDesc="GPC1.r.XY26" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10127" filterID="2" photoCodeDesc="GPC1.r.XY27" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10130" filterID="2" photoCodeDesc="GPC1.r.XY30" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10131" filterID="2" photoCodeDesc="GPC1.r.XY31" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10132" filterID="2" photoCodeDesc="GPC1.r.XY32" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10133" filterID="2" photoCodeDesc="GPC1.r.XY33" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10134" filterID="2" photoCodeDesc="GPC1.r.XY34" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10135" filterID="2" photoCodeDesc="GPC1.r.XY35" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10136" filterID="2" photoCodeDesc="GPC1.r.XY36" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10137" filterID="2" photoCodeDesc="GPC1.r.XY37" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10140" filterID="2" photoCodeDesc="GPC1.r.XY40" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10141" filterID="2" photoCodeDesc="GPC1.r.XY41" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10142" filterID="2" photoCodeDesc="GPC1.r.XY42" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10143" filterID="2" photoCodeDesc="GPC1.r.XY43" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10144" filterID="2" photoCodeDesc="GPC1.r.XY44" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10145" filterID="2" photoCodeDesc="GPC1.r.XY45" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10146" filterID="2" photoCodeDesc="GPC1.r.XY46" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10147" filterID="2" photoCodeDesc="GPC1.r.XY47" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10150" filterID="2" photoCodeDesc="GPC1.r.XY50" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10151" filterID="2" photoCodeDesc="GPC1.r.XY51" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10152" filterID="2" photoCodeDesc="GPC1.r.XY52" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10153" filterID="2" photoCodeDesc="GPC1.r.XY53" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10154" filterID="2" photoCodeDesc="GPC1.r.XY54" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10155" filterID="2" photoCodeDesc="GPC1.r.XY55" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10156" filterID="2" photoCodeDesc="GPC1.r.XY56" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10157" filterID="2" photoCodeDesc="GPC1.r.XY57" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10160" filterID="2" photoCodeDesc="GPC1.r.XY60" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10161" filterID="2" photoCodeDesc="GPC1.r.XY61" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10162" filterID="2" photoCodeDesc="GPC1.r.XY62" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10163" filterID="2" photoCodeDesc="GPC1.r.XY63" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10164" filterID="2" photoCodeDesc="GPC1.r.XY64" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10165" filterID="2" photoCodeDesc="GPC1.r.XY65" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10166" filterID="2" photoCodeDesc="GPC1.r.XY66" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10167" filterID="2" photoCodeDesc="GPC1.r.XY67" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10171" filterID="2" photoCodeDesc="GPC1.r.XY71" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10172" filterID="2" photoCodeDesc="GPC1.r.XY72" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10173" filterID="2" photoCodeDesc="GPC1.r.XY73" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10174" filterID="2" photoCodeDesc="GPC1.r.XY74" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10175" filterID="2" photoCodeDesc="GPC1.r.XY75" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10176" filterID="2" photoCodeDesc="GPC1.r.XY76" AB="0.0" zeropoint="24.800" extinction="-0.100" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10201" filterID="3" photoCodeDesc="GPC1.i.XY01" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10202" filterID="3" photoCodeDesc="GPC1.i.XY02" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10203" filterID="3" photoCodeDesc="GPC1.i.XY03" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10204" filterID="3" photoCodeDesc="GPC1.i.XY04" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10205" filterID="3" photoCodeDesc="GPC1.i.XY05" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10206" filterID="3" photoCodeDesc="GPC1.i.XY06" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10210" filterID="3" photoCodeDesc="GPC1.i.XY10" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10211" filterID="3" photoCodeDesc="GPC1.i.XY11" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10212" filterID="3" photoCodeDesc="GPC1.i.XY12" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10213" filterID="3" photoCodeDesc="GPC1.i.XY13" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10214" filterID="3" photoCodeDesc="GPC1.i.XY14" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10215" filterID="3" photoCodeDesc="GPC1.i.XY15" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10216" filterID="3" photoCodeDesc="GPC1.i.XY16" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10217" filterID="3" photoCodeDesc="GPC1.i.XY17" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10220" filterID="3" photoCodeDesc="GPC1.i.XY20" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10221" filterID="3" photoCodeDesc="GPC1.i.XY21" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10222" filterID="3" photoCodeDesc="GPC1.i.XY22" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10223" filterID="3" photoCodeDesc="GPC1.i.XY23" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10224" filterID="3" photoCodeDesc="GPC1.i.XY24" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10225" filterID="3" photoCodeDesc="GPC1.i.XY25" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10226" filterID="3" photoCodeDesc="GPC1.i.XY26" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10227" filterID="3" photoCodeDesc="GPC1.i.XY27" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10230" filterID="3" photoCodeDesc="GPC1.i.XY30" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10231" filterID="3" photoCodeDesc="GPC1.i.XY31" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10232" filterID="3" photoCodeDesc="GPC1.i.XY32" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10233" filterID="3" photoCodeDesc="GPC1.i.XY33" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10234" filterID="3" photoCodeDesc="GPC1.i.XY34" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10235" filterID="3" photoCodeDesc="GPC1.i.XY35" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10236" filterID="3" photoCodeDesc="GPC1.i.XY36" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10237" filterID="3" photoCodeDesc="GPC1.i.XY37" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10240" filterID="3" photoCodeDesc="GPC1.i.XY40" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10241" filterID="3" photoCodeDesc="GPC1.i.XY41" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10242" filterID="3" photoCodeDesc="GPC1.i.XY42" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10243" filterID="3" photoCodeDesc="GPC1.i.XY43" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10244" filterID="3" photoCodeDesc="GPC1.i.XY44" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10245" filterID="3" photoCodeDesc="GPC1.i.XY45" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10246" filterID="3" photoCodeDesc="GPC1.i.XY46" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10247" filterID="3" photoCodeDesc="GPC1.i.XY47" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10250" filterID="3" photoCodeDesc="GPC1.i.XY50" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10251" filterID="3" photoCodeDesc="GPC1.i.XY51" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10252" filterID="3" photoCodeDesc="GPC1.i.XY52" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10253" filterID="3" photoCodeDesc="GPC1.i.XY53" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10254" filterID="3" photoCodeDesc="GPC1.i.XY54" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10255" filterID="3" photoCodeDesc="GPC1.i.XY55" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10256" filterID="3" photoCodeDesc="GPC1.i.XY56" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10257" filterID="3" photoCodeDesc="GPC1.i.XY57" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10260" filterID="3" photoCodeDesc="GPC1.i.XY60" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10261" filterID="3" photoCodeDesc="GPC1.i.XY61" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10262" filterID="3" photoCodeDesc="GPC1.i.XY62" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10263" filterID="3" photoCodeDesc="GPC1.i.XY63" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10264" filterID="3" photoCodeDesc="GPC1.i.XY64" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10265" filterID="3" photoCodeDesc="GPC1.i.XY65" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10266" filterID="3" photoCodeDesc="GPC1.i.XY66" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10267" filterID="3" photoCodeDesc="GPC1.i.XY67" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10271" filterID="3" photoCodeDesc="GPC1.i.XY71" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10272" filterID="3" photoCodeDesc="GPC1.i.XY72" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10273" filterID="3" photoCodeDesc="GPC1.i.XY73" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10274" filterID="3" photoCodeDesc="GPC1.i.XY74" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10275" filterID="3" photoCodeDesc="GPC1.i.XY75" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10276" filterID="3" photoCodeDesc="GPC1.i.XY76" AB="0.0" zeropoint="24.740" extinction="-0.040" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10301" filterID="4" photoCodeDesc="GPC1.z.XY01" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10302" filterID="4" photoCodeDesc="GPC1.z.XY02" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10303" filterID="4" photoCodeDesc="GPC1.z.XY03" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10304" filterID="4" photoCodeDesc="GPC1.z.XY04" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10305" filterID="4" photoCodeDesc="GPC1.z.XY05" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10306" filterID="4" photoCodeDesc="GPC1.z.XY06" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10310" filterID="4" photoCodeDesc="GPC1.z.XY10" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10311" filterID="4" photoCodeDesc="GPC1.z.XY11" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10312" filterID="4" photoCodeDesc="GPC1.z.XY12" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10313" filterID="4" photoCodeDesc="GPC1.z.XY13" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10314" filterID="4" photoCodeDesc="GPC1.z.XY14" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10315" filterID="4" photoCodeDesc="GPC1.z.XY15" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10316" filterID="4" photoCodeDesc="GPC1.z.XY16" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10317" filterID="4" photoCodeDesc="GPC1.z.XY17" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10320" filterID="4" photoCodeDesc="GPC1.z.XY20" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10321" filterID="4" photoCodeDesc="GPC1.z.XY21" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10322" filterID="4" photoCodeDesc="GPC1.z.XY22" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10323" filterID="4" photoCodeDesc="GPC1.z.XY23" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10324" filterID="4" photoCodeDesc="GPC1.z.XY24" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10325" filterID="4" photoCodeDesc="GPC1.z.XY25" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10326" filterID="4" photoCodeDesc="GPC1.z.XY26" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10327" filterID="4" photoCodeDesc="GPC1.z.XY27" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10330" filterID="4" photoCodeDesc="GPC1.z.XY30" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10331" filterID="4" photoCodeDesc="GPC1.z.XY31" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10332" filterID="4" photoCodeDesc="GPC1.z.XY32" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10333" filterID="4" photoCodeDesc="GPC1.z.XY33" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10334" filterID="4" photoCodeDesc="GPC1.z.XY34" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10335" filterID="4" photoCodeDesc="GPC1.z.XY35" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10336" filterID="4" photoCodeDesc="GPC1.z.XY36" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10337" filterID="4" photoCodeDesc="GPC1.z.XY37" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10340" filterID="4" photoCodeDesc="GPC1.z.XY40" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10341" filterID="4" photoCodeDesc="GPC1.z.XY41" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10342" filterID="4" photoCodeDesc="GPC1.z.XY42" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10343" filterID="4" photoCodeDesc="GPC1.z.XY43" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10344" filterID="4" photoCodeDesc="GPC1.z.XY44" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10345" filterID="4" photoCodeDesc="GPC1.z.XY45" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10346" filterID="4" photoCodeDesc="GPC1.z.XY46" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10347" filterID="4" photoCodeDesc="GPC1.z.XY47" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10350" filterID="4" photoCodeDesc="GPC1.z.XY50" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10351" filterID="4" photoCodeDesc="GPC1.z.XY51" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10352" filterID="4" photoCodeDesc="GPC1.z.XY52" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10353" filterID="4" photoCodeDesc="GPC1.z.XY53" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10354" filterID="4" photoCodeDesc="GPC1.z.XY54" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10355" filterID="4" photoCodeDesc="GPC1.z.XY55" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10356" filterID="4" photoCodeDesc="GPC1.z.XY56" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10357" filterID="4" photoCodeDesc="GPC1.z.XY57" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10360" filterID="4" photoCodeDesc="GPC1.z.XY60" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10361" filterID="4" photoCodeDesc="GPC1.z.XY61" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10362" filterID="4" photoCodeDesc="GPC1.z.XY62" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10363" filterID="4" photoCodeDesc="GPC1.z.XY63" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10364" filterID="4" photoCodeDesc="GPC1.z.XY64" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10365" filterID="4" photoCodeDesc="GPC1.z.XY65" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10366" filterID="4" photoCodeDesc="GPC1.z.XY66" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10367" filterID="4" photoCodeDesc="GPC1.z.XY67" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10371" filterID="4" photoCodeDesc="GPC1.z.XY71" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10372" filterID="4" photoCodeDesc="GPC1.z.XY72" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10373" filterID="4" photoCodeDesc="GPC1.z.XY73" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10374" filterID="4" photoCodeDesc="GPC1.z.XY74" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10375" filterID="4" photoCodeDesc="GPC1.z.XY75" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10376" filterID="4" photoCodeDesc="GPC1.z.XY76" AB="0.0" zeropoint="24.260" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10401" filterID="5" photoCodeDesc="GPC1.y.XY01" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10402" filterID="5" photoCodeDesc="GPC1.y.XY02" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10403" filterID="5" photoCodeDesc="GPC1.y.XY03" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10404" filterID="5" photoCodeDesc="GPC1.y.XY04" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10405" filterID="5" photoCodeDesc="GPC1.y.XY05" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10406" filterID="5" photoCodeDesc="GPC1.y.XY06" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10410" filterID="5" photoCodeDesc="GPC1.y.XY10" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10411" filterID="5" photoCodeDesc="GPC1.y.XY11" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10412" filterID="5" photoCodeDesc="GPC1.y.XY12" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10413" filterID="5" photoCodeDesc="GPC1.y.XY13" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10414" filterID="5" photoCodeDesc="GPC1.y.XY14" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10415" filterID="5" photoCodeDesc="GPC1.y.XY15" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10416" filterID="5" photoCodeDesc="GPC1.y.XY16" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10417" filterID="5" photoCodeDesc="GPC1.y.XY17" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10420" filterID="5" photoCodeDesc="GPC1.y.XY20" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10421" filterID="5" photoCodeDesc="GPC1.y.XY21" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10422" filterID="5" photoCodeDesc="GPC1.y.XY22" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10423" filterID="5" photoCodeDesc="GPC1.y.XY23" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10424" filterID="5" photoCodeDesc="GPC1.y.XY24" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10425" filterID="5" photoCodeDesc="GPC1.y.XY25" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10426" filterID="5" photoCodeDesc="GPC1.y.XY26" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10427" filterID="5" photoCodeDesc="GPC1.y.XY27" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10430" filterID="5" photoCodeDesc="GPC1.y.XY30" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10431" filterID="5" photoCodeDesc="GPC1.y.XY31" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10432" filterID="5" photoCodeDesc="GPC1.y.XY32" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10433" filterID="5" photoCodeDesc="GPC1.y.XY33" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10434" filterID="5" photoCodeDesc="GPC1.y.XY34" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10435" filterID="5" photoCodeDesc="GPC1.y.XY35" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10436" filterID="5" photoCodeDesc="GPC1.y.XY36" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10437" filterID="5" photoCodeDesc="GPC1.y.XY37" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10440" filterID="5" photoCodeDesc="GPC1.y.XY40" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10441" filterID="5" photoCodeDesc="GPC1.y.XY41" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10442" filterID="5" photoCodeDesc="GPC1.y.XY42" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10443" filterID="5" photoCodeDesc="GPC1.y.XY43" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10444" filterID="5" photoCodeDesc="GPC1.y.XY44" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10445" filterID="5" photoCodeDesc="GPC1.y.XY45" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10446" filterID="5" photoCodeDesc="GPC1.y.XY46" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10447" filterID="5" photoCodeDesc="GPC1.y.XY47" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10450" filterID="5" photoCodeDesc="GPC1.y.XY50" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10451" filterID="5" photoCodeDesc="GPC1.y.XY51" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10452" filterID="5" photoCodeDesc="GPC1.y.XY52" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10453" filterID="5" photoCodeDesc="GPC1.y.XY53" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10454" filterID="5" photoCodeDesc="GPC1.y.XY54" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10455" filterID="5" photoCodeDesc="GPC1.y.XY55" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10456" filterID="5" photoCodeDesc="GPC1.y.XY56" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10457" filterID="5" photoCodeDesc="GPC1.y.XY57" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10460" filterID="5" photoCodeDesc="GPC1.y.XY60" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10461" filterID="5" photoCodeDesc="GPC1.y.XY61" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10462" filterID="5" photoCodeDesc="GPC1.y.XY62" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10463" filterID="5" photoCodeDesc="GPC1.y.XY63" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10464" filterID="5" photoCodeDesc="GPC1.y.XY64" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10465" filterID="5" photoCodeDesc="GPC1.y.XY65" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10466" filterID="5" photoCodeDesc="GPC1.y.XY66" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10467" filterID="5" photoCodeDesc="GPC1.y.XY67" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10471" filterID="5" photoCodeDesc="GPC1.y.XY71" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10472" filterID="5" photoCodeDesc="GPC1.y.XY72" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10473" filterID="5" photoCodeDesc="GPC1.y.XY73" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10474" filterID="5" photoCodeDesc="GPC1.y.XY74" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10475" filterID="5" photoCodeDesc="GPC1.y.XY75" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="10476" filterID="5" photoCodeDesc="GPC1.y.XY76" AB="0.0" zeropoint="23.410" extinction="-0.030" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="11000" filterID="1" photoCodeDesc="GPC1.g.SkyChip" AB="0.0" zeropoint="25.000" extinction="0.000" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="11100" filterID="2" photoCodeDesc="GPC1.r.SkyChip" AB="0.0" zeropoint="25.000" extinction="0.000" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="11200" filterID="3" photoCodeDesc="GPC1.i.SkyChip" AB="0.0" zeropoint="25.000" extinction="0.000" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="11300" filterID="4" photoCodeDesc="GPC1.z.SkyChip" AB="0.0" zeropoint="25.000" extinction="0.000" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  <row photoCalID="11400" filterID="5" photoCodeDesc="GPC1.y.SkyChip" AB="0.0" zeropoint="25.000" extinction="0.000" colorterm="0.0" colorExtn="0.0" orphanCalColor="0.0" orphanCalColorErr="0.0" startDate="54000."></row>
+  </table>
 
+  </tabledata>
+
Index: /branches/pap/ippToPsps/config/init/tables.xml
===================================================================
--- /branches/pap/ippToPsps/config/init/tables.xml	(revision 28002)
+++ /branches/pap/ippToPsps/config/init/tables.xml	(revision 28003)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<tableDescriptions type="IN">
+<tableDescriptions type="init">
   <table name="Filter">
     <column name="filterID" type="TBYTE" default="0" comment="filter ID: g=1, r=2, i=3, z=4, y=5, w=6, ..."></column>
     <column name="filterType" type="TSTRING" default=" " comment="filter name: g,r,i,z,y, etc."></column>
-    <column name="filterSpec" type="TSTRING" default=" " comment="No comment"></column>
+    <column name="filterSpec" type="TSTRING" default="0x00" comment="No comment"></column>
   </table>
   <table name="FitModel">
@@ -61,6 +61,6 @@
     <column name="cameraID" type="TSHORT" default="0" comment="camera identification number"></column>
     <column name="cameraConfigID" type="TSHORT" default="0" comment="configuration identification number"></column>
-    <column name="startDate" type="TFLOAT" default="0" comment=" starting date of this configuration in MJD (unit = day)"></column>
-    <column name="configDetails" type="TSTRING" default=" " comment="text/table giving the details of the camera configuration"></column>
+    <column name="endDate" type="TFLOAT" default="0" comment=" ending date of this configuration in MJD (unit = day)"></column>
+    <column name="configDetails" type="TSTRING" default="0x00" comment="text/table giving the details of the camera configuration"></column>
   </table>
   <table name="PhotoCal">
@@ -90,12 +90,12 @@
     <column name="ctype1" type="TSTRING" default=" " comment="name of astrometric projection in RA"></column>
     <column name="ctype2" type="TSTRING" default=" " comment="name of astrometric projection in DEC"></column>
-    <column name="crval1" type="TFLOAT" default="0" comment=" RA corresponding to reference pixel (unit = deg)"></column>
-    <column name="crval2" type="TFLOAT" default="0" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
-    <column name="crpix1" type="TFLOAT" default="0" comment="reference pixel value for RA"></column>
-    <column name="crpix2" type="TFLOAT" default="0" comment="reference pixel value for DEC"></column>
-    <column name="pc001001" type="TFLOAT" default="0" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc001002" type="TFLOAT" default="0" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc002001" type="TFLOAT" default="0" comment="elements of rotation/Dcale matrix"></column>
-    <column name="pc002002" type="TFLOAT" default="0" comment="elements of rotation/Dcale matrix"></column>
+    <column name="crval1" type="TDOUBLE" default="0" comment=" RA corresponding to reference pixel (unit = deg)"></column>
+    <column name="crval2" type="TDOUBLE" default="0" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
+    <column name="crpix1" type="TDOUBLE" default="0" comment="reference pixel value for RA"></column>
+    <column name="crpix2" type="TDOUBLE" default="0" comment="reference pixel value for DEC"></column>
+    <column name="pc001001" type="TDOUBLE" default="0" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc001002" type="TDOUBLE" default="0" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002001" type="TDOUBLE" default="0" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002002" type="TDOUBLE" default="0" comment="elements of rotation/Dcale matrix"></column>
   </table>
   <table name="Region">
@@ -104,5 +104,5 @@
     <column name="type" type="TSTRING" default=" " comment="Region type"></column>
     <column name="comment" type="TSTRING" default=" " comment="Comment"></column>
-    <column name="area" type="TFLOAT" default="0" comment="Area covered by the region"></column>
+    <column name="area" type="TDOUBLE" default="0" comment="Area covered by the region"></column>
     <column name="regionBinary" type="TSTRING" default=" " comment="Binary object managed by the spatial library"></column>
   </table>
Index: /branches/pap/ippToPsps/config/test/map.xml
===================================================================
--- /branches/pap/ippToPsps/config/test/map.xml	(revision 28003)
+++ /branches/pap/ippToPsps/config/test/map.xml	(revision 28003)
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<tabledata>
+
+ <table name="FrameMeta">
+  <map ippName="ZPT_ERR" ippType="TFLOAT" pspsName="photoScat" />
+  <map ippName="MJD-OBS" ippType="TFLOAT" pspsName="expStart" />
+  <map ippName="EXPREQ" ippType="TFLOAT" pspsName="expTime" />
+  <map ippName="AIRMASS" ippType="TFLOAT" pspsName="airmass" />
+  <map ippName="RA" ippType="TDOUBLE" pspsName="raBore" />
+  <map ippName="DEC" ippType="TDOUBLE" pspsName="decBore" />
+  <map ippName="CTYPE1" ippType="TSTRING" pspsName="ctype1" />
+  <map ippName="CTYPE2" ippType="TSTRING" pspsName="ctype2" />
+  <map ippName="CRVAL1" ippType="TDOUBLE" pspsName="crval1" />
+  <map ippName="CRVAL2" ippType="TDOUBLE" pspsName="crval2" />
+  <map ippName="CRPIX1" ippType="TDOUBLE" pspsName="crpix1" />
+  <map ippName="CRPIX2" ippType="TDOUBLE" pspsName="crpix2" />
+  <map ippName="CDELT1" ippType="TDOUBLE" pspsName="cdelt1" />
+  <map ippName="CDELT2" ippType="TDOUBLE" pspsName="cdelt2" />
+  <map ippName="PC001001" ippType="TDOUBLE" pspsName="pc001001" />
+  <map ippName="PC001002" ippType="TDOUBLE" pspsName="pc001002" />
+  <map ippName="PC002001" ippType="TDOUBLE" pspsName="pc002001" />
+  <map ippName="PC002002" ippType="TDOUBLE" pspsName="pc002002" />
+  <map ippName="NPLYTERM" ippType="TBYTE" pspsName="polyOrder" />
+  <map ippName="PCA1X3Y0" ippType="TDOUBLE" pspsName="pca1x3y0" />
+  <map ippName="PCA1X2Y1" ippType="TDOUBLE" pspsName="pca1x2y1" />
+  <map ippName="PCA1X1Y2" ippType="TDOUBLE" pspsName="pca1x1y2" />
+  <map ippName="PCA1X0Y3" ippType="TDOUBLE" pspsName="pca1x0y3" />
+  <map ippName="PCA1X2Y0" ippType="TDOUBLE" pspsName="pca1x2y0" />
+  <map ippName="PCA1X1Y1" ippType="TDOUBLE" pspsName="pca1x1y1" />
+  <map ippName="PCA1X0Y2" ippType="TDOUBLE" pspsName="pca1x0y2" />
+  <map ippName="PCA2X3Y0" ippType="TDOUBLE" pspsName="pca2x3y0" />
+  <map ippName="PCA2X2Y1" ippType="TDOUBLE" pspsName="pca2x2y1" />
+  <map ippName="PCA2X1Y2" ippType="TDOUBLE" pspsName="pca2x1y2" />
+  <map ippName="PCA2X0Y3" ippType="TDOUBLE" pspsName="pca2x0y3" />
+  <map ippName="PCA2X2Y0" ippType="TDOUBLE" pspsName="pca2x2y0" />
+  <map ippName="PCA2X1Y1" ippType="TDOUBLE" pspsName="pca2x1y1" />
+  <map ippName="PCA2X0Y2" ippType="TDOUBLE" pspsName="pca2x0y2" />
+ </table>
+
+ <table name="ImageMeta">
+  <map ippName="MSKY_MN" ippType="TFLOAT" pspsName="sky" />
+  <map ippName="MSKY_SIG" ippType="TFLOAT" pspsName="skyScat" />
+  <map ippName="FSATUR" ippType="TFLOAT" pspsName="magSat" />
+  <map ippName="FLIMIT" ippType="TFLOAT" pspsName="completMag" />
+  <map ippName="CERROR" ippType="TFLOAT" pspsName="astroScat" />
+  <map ippName="NASTRO" ippType="TLONG" pspsName="numAstroRef" />
+  <map ippName="CNAXIS1" ippType="TSHORT" pspsName="nx" />
+  <map ippName="CNAXIS2" ippType="TSHORT" pspsName="ny" />
+  <map ippName="FWHM_MAJ" ippType="TFLOAT" pspsName="psfWidMajor" />
+  <map ippName="FWHM_MIN" ippType="TFLOAT" pspsName="psfWidMinor" />
+  <map ippName="ANGLE" ippType="TFLOAT" pspsName="psfTheta" />
+  <map ippName="APMIFIT" ippType="TFLOAT" pspsName="apResid" />
+  <map ippName="DAPMIFIT" ippType="TFLOAT" pspsName="dapResid" />
+  <map ippName="CTYPE1" ippType="TSTRING" pspsName="ctype1" />
+  <map ippName="CTYPE2" ippType="TSTRING" pspsName="ctype2" />
+  <map ippName="CRVAL1" ippType="TDOUBLE" pspsName="crval1" />
+  <map ippName="CRVAL2" ippType="TDOUBLE" pspsName="crval2" />
+  <map ippName="CRPIX1" ippType="TDOUBLE" pspsName="crpix1" />
+  <map ippName="CRPIX2" ippType="TDOUBLE" pspsName="crpix2" />
+  <map ippName="CDELT1" ippType="TDOUBLE" pspsName="cdelt1" />
+  <map ippName="CDELT2" ippType="TDOUBLE" pspsName="cdelt2" />
+  <map ippName="PC001001" ippType="TDOUBLE" pspsName="pc001001" />
+  <map ippName="PC001002" ippType="TDOUBLE" pspsName="pc001002" />
+  <map ippName="PC002001" ippType="TDOUBLE" pspsName="pc002001" />
+  <map ippName="PC002002" ippType="TDOUBLE" pspsName="pc002002" />
+  <map ippName="NPLYTERM" ippType="TBYTE" pspsName="polyOrder" />
+  <map ippName="PCA1X3Y0" ippType="TDOUBLE" pspsName="pca1x3y0" />
+  <map ippName="PCA1X2Y1" ippType="TDOUBLE" pspsName="pca1x2y1" />
+  <map ippName="PCA1X1Y2" ippType="TDOUBLE" pspsName="pca1x1y2" />
+  <map ippName="PCA1X0Y3" ippType="TDOUBLE" pspsName="pca1x0y3" />
+  <map ippName="PCA1X2Y0" ippType="TDOUBLE" pspsName="pca1x2y0" />
+  <map ippName="PCA1X1Y1" ippType="TDOUBLE" pspsName="pca1x1y1" />
+  <map ippName="PCA1X0Y2" ippType="TDOUBLE" pspsName="pca1x0y2" />
+  <map ippName="PCA2X3Y0" ippType="TDOUBLE" pspsName="pca2x3y0" />
+  <map ippName="PCA2X2Y1" ippType="TDOUBLE" pspsName="pca2x2y1" />
+  <map ippName="PCA2X1Y2" ippType="TDOUBLE" pspsName="pca2x1y2" />
+  <map ippName="PCA2X0Y3" ippType="TDOUBLE" pspsName="pca2x0y3" />
+  <map ippName="PCA2X2Y0" ippType="TDOUBLE" pspsName="pca2x2y0" />
+  <map ippName="PCA2X1Y1" ippType="TDOUBLE" pspsName="pca2x1y1" />
+  <map ippName="PCA2X0Y2" ippType="TDOUBLE" pspsName="pca2x0y2" />
+ </table>
+
+ <table name="Detection">
+  <map ippColumn="2" ippName="X_PSF" ippType="TFLOAT" pspsName="xPos" />
+  <map ippColumn="3" ippName="Y_PSF" ippType="TFLOAT" pspsName="yPos" />
+  <map ippColumn="4" ippName="X_PSF_SIG" ippType="TFLOAT" pspsName="xPosErr" />
+  <map ippColumn="5" ippName="Y_PSF_SIG" ippType="TFLOAT" pspsName="yPosErr" />
+  <map ippColumn="15" ippName="RA_PSF" ippType="TFLOAT" pspsName="ippRa" />
+  <map ippColumn="16" ippName="DEC_PSF" ippType="TFLOAT" pspsName="ippDec" />
+  <map ippColumn="22" ippName="PSF_MAJOR" ippType="TFLOAT" pspsName="psfWidMajor" />
+  <map ippColumn="23" ippName="PSF_MINOR" ippType="TFLOAT" pspsName="psfWidMinor" />
+  <map ippColumn="24" ippName="PSF_THETA" ippType="TFLOAT" pspsName="psfTheta" />
+  <map ippColumn="25" ippName="PSF_QF" ippType="TFLOAT" pspsName="psfCf" />
+  <map ippColumn="17" ippName="SKY" ippType="TFLOAT" pspsName="sky" />
+  <map ippColumn="18" ippName="SKY_SIGMA" ippType="TFLOAT" pspsName="skyErr" />
+ </table>
+
+</tabledata>
Index: /branches/pap/ippToPsps/config/test/tables.xml
===================================================================
--- /branches/pap/ippToPsps/config/test/tables.xml	(revision 28003)
+++ /branches/pap/ippToPsps/config/test/tables.xml	(revision 28003)
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<tableDescriptions type="det">
+  <table name="FrameMeta">
+    <column name="frameID" type="TLONG" default="0" comment="unique exposure/frame identifier."></column>
+    <column name="filterID" type="TBYTE" default="0" comment="filter identifier"></column>
+    <column name="nOTA" type="TSHORT" default="-999" comment="number of valid OTA/CCD images in this exposure"></column>
+    <column name="photoScat" type="TFLOAT" default="-999" comment=" global photometric scatter (unit = mag)"></column>
+    <column name="expStart" type="TDOUBLE" default="-999" comment=" exposure start time in MJD (unit = day)"></column>
+    <column name="expTime" type="TFLOAT" default="-999" comment=" exposure time (unit = s)"></column>
+    <column name="airmass" type="TFLOAT" default="-999" comment="airmass at mid-exposure"></column>
+    <column name="raBore" type="TDOUBLE" default="-999" comment=" RA of telescope boresight (unit = deg)"></column>
+    <column name="decBore" type="TDOUBLE" default="-999" comment=" DEC of telescope boresight (unit = deg)"></column>
+    <column name="ctype1" type="TSTRING" default=" " comment="name of astrometric projection in RA"></column>
+    <column name="ctype2" type="TSTRING" default=" " comment="name of astrometric projection in DEC"></column>
+    <column name="crval1" type="TDOUBLE" default="-999" comment=" RA corresponding to reference pixel (unit = deg)"></column>
+    <column name="crval2" type="TDOUBLE" default="-999" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
+    <column name="crpix1" type="TDOUBLE" default="-999" comment="reference pixel value for RA"></column>
+    <column name="crpix2" type="TDOUBLE" default="-999" comment="reference pixel value for DEC"></column>
+    <column name="cdelt1" type="TDOUBLE" default="-999" comment=""></column>
+    <column name="cdelt2" type="TDOUBLE" default="-999" comment=""></column>
+    <column name="pc001001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc001002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="polyOrder" type="TBYTE" default="255" comment="polynomial order of astrometry fit"></column>
+    <column name="pca1x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+  </table>
+  <table name="ImageMeta">
+    <column name="photoCalID" type="TLONG" default="0" comment="photometry reduction code identifier"></column>
+    <column name="filterID" type="TBYTE" default="0" comment="filter ID"></column>
+    <column name="sky" type="TFLOAT" default="-999" comment=" mean sky level (unit = ADU)"></column>
+    <column name="skyScat" type="TFLOAT" default="-999" comment=" scatter in mean sky level (unit = ADU)"></column>
+    <column name="nDetect" type="TLONG" default="-999" comment="number of detections on CCD"></column>
+    <column name="magSat" type="TFLOAT" default="-999" comment=" saturation magnitude level (unit = mag)"></column>
+    <column name="completMag" type="TFLOAT" default="-999" comment=" 95% completion level in mag (unit = mag)"></column>
+    <column name="astroScat" type="TFLOAT" default="-999" comment=" astrometric scatter for chip (unit = mag)"></column>
+    <column name="photoScat" type="TFLOAT" default="-999" comment="photometric scatter for chip"></column>
+    <column name="numAstroRef" type="TLONG" default="-999" comment="number of astrometric reference sources"></column>
+    <column name="nx" type="TSHORT" default="-999" comment="chip dimension in x"></column>
+    <column name="ny" type="TSHORT" default="-999" comment="chip dimension in y"></column>
+    <column name="psfModelID" type="TLONG" default="-999" comment="PSF model identifier"></column>
+    <column name="psfFwhm" type="TFLOAT" default="-999" comment=" model psf full width at half maximum at chip center (unit = arcsec)"></column>
+    <column name="psfWidMajor" type="TFLOAT" default="-999" comment=" model PSF parameters at chip center (unit = arcsec)"></column>
+    <column name="psfWidMinor" type="TFLOAT" default="-999" comment=" model PSF parameters at chip center (unit = arcsec)"></column>
+    <column name="psfTheta" type="TFLOAT" default="-999" comment=" model PSF parameters at chip center (unit = deg)"></column>
+    <column name="apResid" type="TFLOAT" default="-999" comment="corrected aperture residual"></column>
+    <column name="dapResid" type="TFLOAT" default="-999" comment="scatter of aperture corrections"></column>
+    <column name="photoZero" type="TFLOAT" default="-999" comment=" local derived photometric zero point (unit = mag)"></column>
+    <column name="ctype1" type="TSTRING" default=" " comment="name of astrometric projection in RA"></column>
+    <column name="ctype2" type="TSTRING" default=" " comment="name of astrometric projection in DEC"></column>
+    <column name="crval1" type="TDOUBLE" default="-999" comment=" RA corresponding to reference pixel (unit = deg)"></column>
+    <column name="crval2" type="TDOUBLE" default="-999" comment=" DEC corresponding to reference pixel (unit = deg)"></column>
+    <column name="crpix1" type="TDOUBLE" default="-999" comment=" reference pixel value for RA (unit = pix)"></column>
+    <column name="crpix2" type="TDOUBLE" default="-999" comment=" reference pixel value for DEC (unit = pix)"></column>
+    <column name="cdelt1" type="TDOUBLE" default="-999" comment=""></column>
+    <column name="cdelt2" type="TDOUBLE" default="-999" comment=""></column>
+    <column name="pc001001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc001002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002001" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="pc002002" type="TDOUBLE" default="-999" comment="elements of rotation/Dcale matrix"></column>
+    <column name="polyOrder" type="TBYTE" default="255" comment="polynomial order of astrometry fit"></column>
+    <column name="pca1x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca1x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x3y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y3" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x2y0" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x1y1" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+    <column name="pca2x0y2" type="TDOUBLE" default="-999" comment="polynomial coefficients for the astrometric fit"></column>
+  </table>
+  <table name="Detection">
+    <column name="objID" type="TLONGLONG" default="0" comment="ODM object identifier"></column>
+    <column name="detectID" type="TLONGLONG" default="0" comment="ODM detection identifier"></column>
+    <column name="ippObjID" type="TLONGLONG" default="0" comment="object id generated by IPP"></column>
+    <column name="ippDetectID" type="TLONGLONG" default="0" comment="detection id generated by IPP"></column>
+    <column name="filterID" type="TBYTE" default="0" comment="filter ID: g=1, r=2, i=3, z=4, y=5, w=6, ..."></column>
+    <column name="xPos" type="TFLOAT" default="-999" comment=" measured x on CCD from PSF fit (unit = pix)"></column>
+    <column name="yPos" type="TFLOAT" default="-999" comment=" measured y on CCD from PSF fit (unit = pix)"></column>
+    <column name="xPosErr" type="TFLOAT" default="-999" comment=" estimated error in x (unit = pix)"></column>
+    <column name="yPosErr" type="TFLOAT" default="-999" comment=" estimated error in y (unit = pix)"></column>
+    <column name="ippRa" type="TFLOAT" default="-999" comment="RA"></column>
+    <column name="ippDec" type="TFLOAT" default="-999" comment="dec"></column>
+    <column name="instFlux" type="TFLOAT" default="-999" comment=" PSF instrumental flux (unit = adu/s)"></column>
+    <column name="instFluxErr" type="TFLOAT" default="-999" comment=" estimated error in flux (unit = adu/s)"></column>
+    <column name="peakADU" type="TFLOAT" default="-999" comment=" peak count in source pixel (unit = adu)"></column>
+    <column name="psfWidMajor" type="TFLOAT" default="-999" comment=" model PSF width in major axis (unit = arcsec)"></column>
+    <column name="psfWidMinor" type="TFLOAT" default="-999" comment=" model PSF width in minor axis (unit = arcsec)"></column>
+    <column name="psfTheta" type="TFLOAT" default="-999" comment=" model PSF orientation angle (unit = deg)"></column>
+    <column name="psfCf" type="TFLOAT" default="-999" comment="PSF coverage factor"></column>
+    <column name="sky" type="TFLOAT" default="-999" comment=" PSF sky level at source (unit = adu)"></column>
+    <column name="skyErr" type="TFLOAT" default="-999" comment=" estimated error in sky (unit = adu)"></column>
+  </table>
+</tableDescriptions>
Index: /branches/pap/ippToPsps/scripts/convertPhotCodesToXml.pl
===================================================================
--- /branches/pap/ippToPsps/scripts/convertPhotCodesToXml.pl	(revision 28003)
+++ /branches/pap/ippToPsps/scripts/convertPhotCodesToXml.pl	(revision 28003)
@@ -0,0 +1,84 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+use IPC::Cmd 0.36 qw( can_run run );
+use XML::Writer;
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+
+my $inputPath = undef;
+my $outputPath = "photcodes.xml";
+
+# get user args
+GetOptions(
+        'input|i=s' => \$inputPath,
+        ) or pod2usage( 2 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+
+# tell off user for not providing proper args
+pod2usage(
+        -msg => "\n   Required options:\n\n".
+        "--input <path to dvo.photcodes files>\n".
+        -exitval => 3
+        ) unless
+defined $inputPath;
+
+
+
+my $output = new IO::File(">$outputPath");
+my $writer = new XML::Writer(OUTPUT => $output, DATA_MODE => 1, DATA_INDENT=>2);
+$writer->xmlDecl('UTF-8');
+
+$writer->startTag('table', "name" => "PhotoCal");
+
+open (PHOTCODES, $inputPath);
+my $photCode;
+my $zeroPoint;
+my $filter;
+my $description;
+
+while (<PHOTCODES>) {
+
+    chomp;
+
+    if ($_ =~ m/\s+([0-9]+)\s+GPC1.*/) {
+
+        my @columns = split(/\s+/, $_);
+
+        my $filter = $columns[11];
+        my $description = $columns[2];
+        my $photCode = $columns[1];
+        my $zeroPoint = $columns[4];
+
+        $writer->startTag('row',
+                "photoCalID" => $photCode,
+                "filterID" => $filter,
+                "photoCodeDesc" => $description,
+                "AB" => "0.0", # TODO
+                "zeropoint" => $zeroPoint,
+                "extinction" => "0.0", # TODO
+                "colorterm" => "0.0", # TODO
+                "colorExtn" => "0.0", # TODO
+                "orphanCalColor" => "0.0", # TODO
+                "orphanCalColorErr" => "0.0", # TODO
+                "startDate" => "54000.");
+
+        $writer->endTag();
+
+
+
+    }
+}
+
+$writer->endTag();
+
+
+close PHOTCODES;
+
+# finish up XML
+#$writer->endTag();
+$writer->end();
+
+
Index: /branches/pap/ippToPsps/scripts/getExpIdFromJob.pl
===================================================================
--- /branches/pap/ippToPsps/scripts/getExpIdFromJob.pl	(revision 28003)
+++ /branches/pap/ippToPsps/scripts/getExpIdFromJob.pl	(revision 28003)
@@ -0,0 +1,65 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+use IPC::Cmd 0.36 qw( can_run run );
+
+my $path = undef;
+my $list = undef;
+my $job = undef;
+
+GetOptions(
+        'path|p=s' => \$path,
+        'list|l=s' => \$list,
+        'job|j=s' => \$job,
+        ) or pod2usage( 2 );
+
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+pod2usage(
+        -msg => "\n   Required options:\n\n".
+        "--path <pathToJobsDir>\n".
+        "--list <listOfJobNames> | --job <job>\n\n",
+        -exitval => 3
+        ) unless
+defined $path and
+(defined $list || defined $job);
+
+if (defined $job) {getExpId($job);}
+else {
+
+    open (LIST, "$list") || die "couldn't open the file at '$list'";
+
+    while ($job = <LIST>) {
+
+        getExpId($job);
+
+    }
+
+close(LIST);
+}
+#################################################################
+#
+#
+#################################################################
+sub getExpId {
+    my ($job) = @_;
+
+    chomp($job);
+
+    my @cmdOut = `tar -ztf $path/$job/B000.tar.gz`;
+
+    my $line;
+    foreach $line (@cmdOut) {
+
+        if ($line =~ m/.*B000\/(\d+)\.FITS/) {
+
+            print "$1\n";
+
+        }
+
+    }
+}
+
Index: /branches/pap/ippToPsps/scripts/ippToPsps_run.pl
===================================================================
--- /branches/pap/ippToPsps/scripts/ippToPsps_run.pl	(revision 28002)
+++ /branches/pap/ippToPsps/scripts/ippToPsps_run.pl	(revision 28003)
@@ -12,5 +12,5 @@
 
 # globals
-my ($verbose, $save_temps, $no_op, $no_update, $camera, $product, $output, $dvodb, $label, $singleExpId, $no_publish);
+my ($verbose, $save_temps, $no_op, $no_update, $camera, $batchType, $output, $dvodb, $datastoreProduct, $label, $singleExpId, $no_publish);
 
 # TODO temporary until we use database to store current jobid
@@ -26,12 +26,14 @@
 $output = undef;
 $singleExpId = undef;
+$datastoreProduct = "PSPS_test";
 
 # get user args
 GetOptions(
         'output|o=s' => \$output,
-        'product|p=s' => \$product,
+        'batch|b=s' => \$batchType,
         'dvodb|d=s' => \$dvodb,
         'label|l=s' => \$label,
         'expid|e=s' => \$singleExpId,
+        'product|p=s' => \$datastoreProduct,
         'no_publish' => \$no_publish,
         'verbose|v' => \$verbose,
@@ -46,11 +48,17 @@
 pod2usage(
         -msg => "\n   Required options:\n\n".
-        "--product <init|det|diff|stack>\n".
+        "--batch <init|det|diff|stack>\n".
         "--output <path>\n".
-        "--label <label> | --expid <expid>\n" .
-        "--dvodb <path>\n\n",
+        "--label <label> or --expid <expid>\n" .
+        "--dvodb <path>\n".
+        "\n   Optional:\n\n".
+        "--product <datastoreProduct>\n".
+        "--no_publish - won't publish to datastore\n".
+        "--save_temps - will save temporary files\n".
+        "--no-op - ?\n".
+        "--no-update - will not update database\n",
         -exitval => 3
         ) unless 
-defined $product and
+defined $batchType and
 defined $output and
 defined $dvodb and
@@ -68,4 +76,33 @@
 
 close $resultsFile;
+
+#######################################################################################
+# 
+# Generates a PSPS-suitable survey 'type' from the IPP distribution group
+#
+#######################################################################################
+sub getSurveyTypeFromDistGroup {
+    my ($distGroup) = @_;
+
+    if ($distGroup eq "MD01") {return $distGroup;}
+    if ($distGroup eq "MD02") {return $distGroup;}
+    if ($distGroup eq "MD03") {return $distGroup;}
+    if ($distGroup eq "MD04") {return $distGroup;}
+    if ($distGroup eq "MD05") {return $distGroup;}
+    if ($distGroup eq "MD06") {return $distGroup;}
+    if ($distGroup eq "MD07") {return $distGroup;}
+    if ($distGroup eq "MD08") {return $distGroup;}
+    if ($distGroup eq "MD09") {return $distGroup;}
+    if ($distGroup eq "MD10") {return $distGroup;}
+    if ($distGroup eq "M31") {return $distGroup;}
+    if ($distGroup eq "sts") {return "STS";}
+    if ($distGroup eq "SweetSpot") {return "SS";}
+    if ($distGroup eq "3PI") {return $distGroup;}
+    if ($distGroup eq "ThreePi") {return "3PI";}
+    if ($distGroup eq "SAS") {return "3PI";}
+
+    print "* Do not understand distribution group: '$distGroup'\n";
+    return undef;
+}
 
 #######################################################################################
@@ -91,20 +128,24 @@
 
         # query to retrieve all exposures with the provided label
-        $query =
-            "SELECT DISTINCT rawExp.exp_id ".
-            "FROM camRun, chipRun, rawExp ".
-            "WHERE camRun.chip_id = chipRun.chip_id ".
-            "AND chipRun.exp_id = rawExp.exp_id ".
-            "AND camRun.label like '%$label%' ".
-            #    "AND rawExp.decl >= '-0.157079633' AND rawExp.decl <= '0.157079633' ". # TODO Jim's decl range
-            "ORDER BY rawExp.exp_id ASC";
+        $query = $db->prepare(<<SQL);
+
+        SELECT DISTINCT rawExp.exp_id, camRun.dist_group
+            FROM camRun, chipRun, rawExp
+            WHERE camRun.chip_id = chipRun.chip_id
+            AND chipRun.exp_id = rawExp.exp_id
+            AND camRun.label LIKE '%$label%'
+            ORDER BY rawExp.exp_id ASC
+SQL
+            #AND rawExp.exp_id > 136561
+            #AND camRun.dist_group LIKE 'sas'
+            #AND rawExp.decl >= '-0.157079633' AND rawExp.decl <= '0.157079633' Jims Dec range
     }
     else {
 
-        $query = "SELECT DISTINCT exp_id FROM rawExp WHERE rawExp.exp_id = $singleExpId"
-
-    }
-
-    if ($verbose) { print"$query\n";}
+        $query = $db->prepare(<<SQL);
+
+        SELECT DISTINCT rawExp.exp_id, dist_group FROM rawExp, chipRun WHERE chipRun.exp_id = rawExp.exp_id AND rawExp.exp_id = $singleExpId
+SQL
+    }
 
     my $batchId = 0;
@@ -114,20 +155,25 @@
     my $jobId = getJobId();
     $jobId++;
-    if ($jobId < 0) { print "Cannot find sensible jobId ($jobId)\n";
+    if ($jobId < 0) { print "* Cannot find sensible jobId ($jobId)\n";
         return 0;
     }
 
-    print "------------------------------------------------------------------------------------------\n\n";
+    print "*******************************************************************************\n*\n";
 
     my $anyBatches = 0;
 
+
+    $query->execute;
+
     # loop round exposures
-    my $expResults = $db->selectall_arrayref( $query );
-
-    for my $expRow (@$expResults) {
-
-        my ($expId) = @$expRow;
-
-        print "      *** Exposure ID = $expId ***\n";
+    while (my @row = $query->fetchrow_array()) {
+        my ($expId, $distGroup) = @row;
+
+        print "* Exposure ID = $expId with dist group = '$distGroup'\n";
+
+        my $surveyType = getSurveyTypeFromDistGroup($distGroup);
+
+        if (!$surveyType) {next;}
+        print "* Using survey type of $surveyType\n";
 
         # generate batch and job paths from job and batch IDs
@@ -137,15 +183,16 @@
         my $batchOutputPath = sprintf("$jobOutputPath/%s", $batchDir);
 
-        print "Preparing job '$job'...\n";
+        print "* Preparing exposure $expId as job '$job'...\n";
 
         # make directories
         mkdir($jobOutputPath, 0777);
         mkdir($batchOutputPath, 0777);
+        setJobId($jobId);
 
         # run IppToPsps program
-        if (runIppToPsps($db, $expId, $batchOutputPath, $product)) {
+        if (runIppToPsps($db, $expId, $batchOutputPath, $batchType)) {
 
             # write batch manifest and tar and zip up
-            if (writeBatchManifest($batchOutputPath, $batchDir, $product)) {
+            if (writeBatchManifest($batchOutputPath, $batchDir, $batchType)) {
 
                 if (tarAndZipDirectory($jobOutputPath, $batchDir)) {
@@ -161,5 +208,5 @@
             elsif ($anyBatches) {
 
-                if (writeJobManifest($output, $job)) {
+                if (writeJobManifest($output, $job, $surveyType)) {
 
                     if (!$no_publish && !publishToDatastore($output, $job)) { 
@@ -168,5 +215,4 @@
                 }
 
-                setJobId($jobId);
                 $jobId++;
                 $batchId = 0;
@@ -175,13 +221,15 @@
             else {
 
-                print "No batches to publish\n"
+                print "* No batches to publish\n"
             }
         }
 
-        if ($product eq "init" ) {print "Wrote initialisation batch\n"; last;}
-
-
-        print "------------------------------------------------------------------------------------------\n\n";
-    }
+        if ($batchType eq "init" ) {print "* Wrote initialisation batch\n"; last;}
+
+
+        print "*\n*******************************************************************************\n\n";
+    }
+
+    $db->disconnect();
 
     return 1;
@@ -204,5 +252,5 @@
     close (MYFILE);
 
-    if ($verbose) { print "Current jobId = $jobId\n"; }
+    if ($verbose) { print "* Current jobId = $jobId\n"; }
 
     return $jobId;
@@ -221,5 +269,5 @@
     close (MYFILE);
 
-    if ($verbose) { print "New jobId = $jobId\n"; }
+    if ($verbose) { print "* New jobId = $jobId\n"; }
 }
 
@@ -230,16 +278,16 @@
 #######################################################################################
 sub runIppToPsps {
-    my ($db, $expId, $batchOutputPath, $product) = @_;
+    my ($db, $expId, $batchOutputPath, $batchType) = @_;
 
     my $success = 0;
 
     # before anything else, we can publish the init batch
-    if ($product =~ /init/) {
+    if ($batchType =~ /init/) {
         $success = produceInit($batchOutputPath);
     }
-    elsif ($product =~ /det/) {
+    elsif ($batchType =~ /det/) {
         $success = produceDetections($db, $expId, $batchOutputPath);
     }
-    elsif ($product =~ /diff/) {
+    elsif ($batchType =~ /diff/) {
         $success = produceDiffs($db, $expId, $batchOutputPath);
     }
@@ -265,5 +313,5 @@
         run(command => $command, verbose => $verbose);
 
-    if (!$success) { print "Unable to tar up dir: $batch\n" and return 0 };
+    if (!$success) { print "* Unable to tar up dir: $batch\n" and return 0 };
 
     # zip
@@ -272,5 +320,5 @@
         run(command => $command, verbose => $verbose);
 
-    if (!$success) { print "Unable to gzip: $batchTar\n" and return 0 };
+    if (!$success) { print "* Unable to gzip: $batchTar\n" and return 0 };
 
     $command = "rm $batchTar";
@@ -278,5 +326,5 @@
         run(command => $command, verbose => $verbose);
 
-    if (!$success) { print "Unable to remove: $batchTar\n" };
+    if (!$success) { print "* Unable to remove: $batchTar\n" };
 
     $command = "rm -r $batchDir";
@@ -284,5 +332,5 @@
         run(command => $command, verbose => $verbose);
 
-    if (!$success) { print "Unable to remove: $batch\n"};
+    if (!$success) { print "* Unable to remove: $batch\n"};
 
     return 1;
@@ -296,5 +344,5 @@
 sub writeBatchManifest {
 
-    my ($path,$batch,$product) = @_;
+    my ($path,$batch,$batchType) = @_;
 
     use XML::Writer;
@@ -311,8 +359,8 @@
     # determine batch 'type'
     my $type;
-    if($product eq 'init') {$type = "IN";}
-    elsif($product eq 'det') {$type = "P2";}
-    elsif ($product eq 'stack') {$type = "ST";}
-    elsif ($product eq 'diff') {$type = "OB";}
+    if($batchType eq 'init') {$type = "IN";}
+    elsif($batchType eq 'det') {$type = "P2";}
+    elsif ($batchType eq 'stack') {$type = "ST";}
+    elsif ($batchType eq 'diff') {$type = "OB";}
     else {$type = "UNKNOWN";}
 
@@ -325,5 +373,5 @@
     my $maxObjId;
     my $filename;
-    if($product eq 'det') {
+    if($batchType eq 'det') {
 
         while (<MYFILE>) {
@@ -343,5 +391,5 @@
 
     # open directory to hunt for FITS files
-    opendir(DIR, $path) or print "Cannot open '$path' to write batch manifest\n" and return 0;
+    opendir(DIR, $path) or print "* Cannot open '$path' to write batch manifest\n" and return 0;
     my @thefiles= readdir(DIR);
     closedir(DIR);
@@ -353,5 +401,5 @@
         if ($f =~ /\.FITS/) {
 
-            if ($foundFits) { print "More than one FITS file found for this batch\n"; return 0;}
+            if ($foundFits) { print "* More than one FITS file found for this batch\n"; return 0;}
 
             # get md5sum of file
@@ -362,5 +410,5 @@
 
             # write manifest element TODO untidy
-            if($product eq 'det' && $filename eq $f) {
+            if($batchType eq 'det' && $filename eq $f) {
 
                 $writer->startTag('manifest',
@@ -389,5 +437,5 @@
             #$writer->startTag('md5'); $writer->characters("$md5sum"); $writer->endTag();
 
-            #if($product eq 'det' && $filename eq $f) {
+            #if($batchType eq 'det' && $filename eq $f) {
 
                 #    $writer->startTag('minObjId'); $writer->characters("$minObjId"); $writer->endTag();
@@ -404,5 +452,5 @@
 
 
-    if (!$foundFits) { print "Could not find any FITS files for this batch\n"; return 0;}
+    if (!$foundFits) { print "* Could not find any FITS files for this batch\n"; return 0;}
     return 1;
 }
@@ -414,5 +462,5 @@
 #######################################################################################
 sub writeJobManifest {
-    my ($path, $job) = @_;
+    my ($path, $job, $surveyType) = @_;
 
     use XML::Writer;
@@ -433,5 +481,5 @@
     $writer->startTag('manifest',
             "name" => "$job",
-            "type" => "3PI", # TODO survey ID
+            "type" => $surveyType,
             "timestamp" => "$timeStamp");
 
@@ -439,5 +487,5 @@
 
     # open directory to hunt for FITS files
-    opendir(DIR, $jobPath) or print "Cannot open '$path' to write job manifest\n" and return 0;
+    opendir(DIR, $jobPath) or print "* Cannot open '$path' to write job manifest\n" and return 0;
     my @thefiles= readdir(DIR);
     closedir(DIR);
@@ -472,5 +520,5 @@
     $writer->end();
 
-    if (!$foundBatch) { print "Could not find any batches for this job\n"; return 0;}
+    if (!$foundBatch) { print "* Could not find any batches for this job\n"; return 0;}
     return 1;
 }
@@ -489,5 +537,5 @@
 
     # loop through all batch files in this job directory
-    opendir(DIR, $fullJobPath) or print "Cannot open '$fullJobPath' in order to publish to datastore\n" and return 0;
+    opendir(DIR, $fullJobPath) or print "* Cannot open '$fullJobPath' in order to publish to datastore\n" and return 0;
     my @thefiles= readdir(DIR);
     closedir(DIR);
@@ -512,5 +560,5 @@
     $command .= " --datapath $fullJobPath";
     $command .= " --type IPP_PSPS";
-    $command .= " --product PSPS_test";
+    $command .= " --product $datastoreProduct";
     $command .= " --list $tempName";
 
@@ -519,7 +567,7 @@
         run(command => $command, verbose => $verbose);
 
-    if (!$success) { print "Unable to publish $job to datastore\n" and return 0 };
-
-    print "Successfully published $job to datastore\n";
+    if (!$success) { print "* Unable to publish $job to datastore\n" and return 0 };
+
+    print "* Successfully published $job to datastore\n";
 
     close($tempFile);
@@ -536,5 +584,5 @@
     my ($outputPath) = @_;
 
-    my $success = runProgram( "NULL", $outputPath, 0, $product);
+    my $success = runProgram( "NULL", $outputPath, 0, $batchType);
     return $success;
 }
@@ -558,5 +606,5 @@
         "WHERE rawExp.exp_id = $expId AND camRun.magicked";
 
-    if ($verbose) { print"$query\n";}
+    if ($verbose) { print"* $query\n";}
 
 
@@ -564,5 +612,5 @@
     my $results = $db->selectall_arrayref( $query );
     my $size = @$results;
-    if ($size < 1) {print "No smf files found for this exposure\n"; return 0;}
+    if ($size < 1) {print "* No smf files found for this exposure\n"; return 0;}
 
     # loop round db results TODO should only be one result
@@ -580,5 +628,5 @@
         close $tempFile;
 
-        $success = runProgram($tempName, $outputPath, $expId, $product);
+        $success = runProgram($tempName, $outputPath, $expId, $batchType);
         return $success;
     }
@@ -604,10 +652,10 @@
         "WHERE rawExp.exp_id = $expId AND camRun.magicked";
 
-    if ($verbose) { print"$query\n";}
+    if ($verbose) { print"* $query\n";}
 
     # execute query and check results
     my $results = $db->selectall_arrayref( $query );
     my $size = @$results;
-    if ($size < 1) {print "No cmf files found for this exposure\n"; return 0;}
+    if ($size < 1) {print "* No cmf files found for this exposure\n"; return 0;}
 
     my ($tempFile, $tempName) = tempfile( "inputFileList.XXXX", UNLINK => !$save_temps);
@@ -629,5 +677,5 @@
     }
 
-    my $ret = runProgram($tempName, $outputPath, $expId, $product);
+    my $ret = runProgram($tempName, $outputPath, $expId, $batchType);
 
     close $tempFile;
@@ -642,5 +690,5 @@
 #######################################################################################
 sub runProgram {
-    my ($input, $output, $expid, $product) = @_;
+    my ($input, $output, $expid, $batchType) = @_;
 
     # build command
@@ -651,5 +699,5 @@
     $command .= " -config config"; # TODO
     $command .= " -expid $expid";
-    $command .= " -product $product";
+    $command .= " -batch $batchType";
     $command .= " -results $resultsFileName";
 
Index: /branches/pap/ippToPsps/scripts/pspsSchema2xml.pl
===================================================================
--- /branches/pap/ippToPsps/scripts/pspsSchema2xml.pl	(revision 28002)
+++ /branches/pap/ippToPsps/scripts/pspsSchema2xml.pl	(revision 28003)
@@ -16,11 +16,11 @@
 use Pod::Usage qw( pod2usage );
 
-
-my ($schemaPath, $type);
+my $schemaPath = undef;
+my $type = undef;
 
 # get user args
 GetOptions(
-        'schema=s' => \$schemaPath,
-        'type=s' => \$type,
+        'schema|s=s' => \$schemaPath,
+        'type|t=s' => \$type,
         ) or pod2usage( 2 );
 
@@ -286,5 +286,5 @@
         $type =~ s/TINYINT/TBYTE/;
         $type =~ s/INT/TLONG/;
-        $type =~ s/FLOAT/TFLOAT/;
+        $type =~ s/FLOAT/TDOUBLE/;
         $type =~ s/REAL/TFLOAT/;
         $type =~ s/DATE/TSTRING/;
Index: /branches/pap/ippToPsps/scripts/removeFromDatastore.pl
===================================================================
--- /branches/pap/ippToPsps/scripts/removeFromDatastore.pl	(revision 28002)
+++ /branches/pap/ippToPsps/scripts/removeFromDatastore.pl	(revision 28003)
@@ -5,15 +5,34 @@
 use IPC::Cmd 0.36 qw( can_run run );
 use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
 
-my $start;
+my $start = undef;
+my $end = undef;
+my $product = undef;
 
-GetOptions(  'start=s' => \$start)  or pod2usage( 2 );
+GetOptions( 
+        'start|s=s' => \$start,
+        'end|e=s' => \$end,
+        'product|p=s' => \$product,
+        )  or pod2usage( 2 );
+
+pod2usage(
+        -msg => "\n   Required options:\n\n".
+        "--start <jobStartNumber> [--end <jobEndNumber>]\n".
+        "--product <datastoreProduct>\n",
+        -exitval => 3
+        ) unless
+defined $product and
+defined $start;
+
+
+if (!defined $end) {$end = 1000000;}
 
 my $i;
 
-for ($i = $start; $i < 1000; $i++) {
+for ($i=$start; $i<$end+1; $i++) {
 
     my $job = sprintf("J%06d", $i);
-    my $command  = "dsreg --del $job --product PSPS_test";
+    my $command  = "dsreg --del $job --product $product";
 
     run(command => $command, verbose => 1);
Index: /branches/pap/ippToPsps/src/Makefile.am
===================================================================
--- /branches/pap/ippToPsps/src/Makefile.am	(revision 28002)
+++ /branches/pap/ippToPsps/src/Makefile.am	(revision 28003)
@@ -30,4 +30,5 @@
 	ippToPspsVersion.c \
 	ippToPspsConfig.c \
+	ippToPspsBatchTest.c \
 	ippToPspsBatchInit.c \
 	ippToPspsBatchDetection.c \
Index: /branches/pap/ippToPsps/src/ippToPsps.c
===================================================================
--- /branches/pap/ippToPsps/src/ippToPsps.c	(revision 28002)
+++ /branches/pap/ippToPsps/src/ippToPsps.c	(revision 28003)
@@ -18,4 +18,5 @@
 #include "ippToPsps.h"
 
+extern int ippToPsps_batchTest(IppToPsps *data);
 extern int ippToPsps_batchInit(IppToPsps *data);
 extern int ippToPsps_batchDetection(IppToPsps *data);
@@ -123,12 +124,13 @@
 }
 
-// the available IPP data products
+// the available IPP batch types for PSPS
 typedef enum {
 
-    PRODUCT_INIT,
-    PRODUCT_DETECTION,
-    PRODUCT_STACK,
-    PRODUCT_DIFFERENCE,
-    PRODUCT_UNDEFINED
+    BATCH_TEST,
+    BATCH_INIT,
+    BATCH_DETECTION,
+    BATCH_STACK,
+    BATCH_DIFFERENCE,
+    BATCH_UNDEFINED
 
 } ippProducts;
@@ -146,5 +148,5 @@
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-results", 0, "Path to results output", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-config", 0, "Path to config dir", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-product", 0, "Product type: [det|stack|diff]", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-batch", 0, "Product type: [det|stack|diff]", NULL);
 
     bool ret = true;
@@ -163,20 +165,21 @@
         this->fitsOutPath = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-output"));
         this->configsDir = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-config"));
-        tmp = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-product"));
-
-        if (!tmp) this->product = PRODUCT_UNDEFINED;
-        else if (strcmp(tmp, "init") == 0) this->product = PRODUCT_INIT;
-        else if (strcmp(tmp, "det") == 0) this->product = PRODUCT_DETECTION;
-        else if (strcmp(tmp, "stack") == 0) this->product = PRODUCT_STACK;
-        else if (strcmp(tmp, "diff") == 0) this->product = PRODUCT_DIFFERENCE;
-        else this->product = PRODUCT_UNDEFINED;
+        tmp = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-batch"));
+
+        if (!tmp) this->batchType = BATCH_UNDEFINED;
+        else if (strcmp(tmp, "test") == 0) this->batchType = BATCH_TEST;
+        else if (strcmp(tmp, "init") == 0) this->batchType = BATCH_INIT;
+        else if (strcmp(tmp, "det") == 0) this->batchType = BATCH_DETECTION;
+        else if (strcmp(tmp, "stack") == 0) this->batchType = BATCH_STACK;
+        else if (strcmp(tmp, "diff") == 0) this->batchType = BATCH_DIFFERENCE;
+        else this->batchType = BATCH_UNDEFINED;
 
         if (
-                (this->product != PRODUCT_INIT && !this->fitsInPath) || 
-                (this->product != PRODUCT_INIT && !this->resultsPath) || 
-                (this->product != PRODUCT_INIT && this->expId == -1) ||
+                (this->batchType != BATCH_INIT && !this->fitsInPath) || 
+                (this->batchType != BATCH_INIT && !this->resultsPath) || 
+                (this->batchType != BATCH_INIT && this->expId == -1) ||
                 !this->fitsOutPath || 
                 !this->configsDir || 
-                this->product == PRODUCT_UNDEFINED ) {
+                this->batchType == BATCH_UNDEFINED ) {
 
             usage(this,argv[0], arguments);
@@ -196,21 +199,24 @@
     if(this->exitCode == PS_EXIT_SUCCESS) {
 
-        // which product?
-        switch(this->product) {
-
-            case PRODUCT_INIT:
+        // which batchType?
+        switch(this->batchType) {
+
+            case BATCH_TEST:
+                this->exitCode = ippToPsps_batchTest(this);
+                break;
+            case BATCH_INIT:
                 this->exitCode = ippToPsps_batchInit(this);
                 break;
-            case PRODUCT_DETECTION:
+            case BATCH_DETECTION:
                 this->exitCode = ippToPsps_batchDetection(this);
                 break;
-            case PRODUCT_STACK:
+            case BATCH_STACK:
                 this->exitCode = ippToPsps_batchStack(this);
                 break;
-            case PRODUCT_DIFFERENCE:
+            case BATCH_DIFFERENCE:
                 this->exitCode = ippToPsps_batchDifference(this);
                 break;
             default:
-                psError(PS_ERR_UNKNOWN, false, "Unable to run for this product type (%d)", this->product);
+                psError(PS_ERR_UNKNOWN, false, "Unable to run for this batch type (%d)", this->batchType);
                 this->exitCode = false;
                 break;
@@ -260,5 +266,5 @@
     }
 
-    if (this->product != PRODUCT_INIT && !ippToPsps_readInputFilePaths(this)) {
+    if (this->batchType != BATCH_INIT && !ippToPsps_readInputFilePaths(this)) {
 
         this->exitCode = PS_EXIT_DATA_ERROR;
@@ -266,11 +272,13 @@
     }
 
-    if (this->product == PRODUCT_INIT)
+    if (this->batchType == BATCH_TEST)
+        psStringAppend(&this->configsDir, "/test");
+    if (this->batchType == BATCH_INIT)
         psStringAppend(&this->configsDir, "/init");
-    if (this->product == PRODUCT_DETECTION)
+    if (this->batchType == BATCH_DETECTION)
         psStringAppend(&this->configsDir, "/detection");
-    if (this->product == PRODUCT_DIFFERENCE)
+    if (this->batchType == BATCH_DIFFERENCE)
         psStringAppend(&this->configsDir, "/diff");
-    if (this->product == PRODUCT_STACK)
+    if (this->batchType == BATCH_STACK)
         psStringAppend(&this->configsDir, "/stack");
 
Index: /branches/pap/ippToPsps/src/ippToPsps.h
===================================================================
--- /branches/pap/ippToPsps/src/ippToPsps.h	(revision 28002)
+++ /branches/pap/ippToPsps/src/ippToPsps.h	(revision 28003)
@@ -18,9 +18,8 @@
 #define MAXDETECT 30000 //TODO limit ok?
 
-// ippToPsps struct
 typedef struct {
 
     uint32_t expId;            // the exposure ID to be used
-    uint8_t product;           // IPP data product
+    uint8_t batchType;         // PSPS batch type
     psString fitsInPath;       // path to FITS input
     psString resultsPath;      // path to results file
Index: /branches/pap/ippToPsps/src/ippToPspsBatchDetection.c
===================================================================
--- /branches/pap/ippToPsps/src/ippToPspsBatchDetection.c	(revision 28002)
+++ /branches/pap/ippToPsps/src/ippToPspsBatchDetection.c	(revision 28003)
@@ -14,8 +14,8 @@
 
 // Gets flux from magnitude
-static __inline float ippToPsps_getFlux(const float zeroPoint, const float exposureTime, const float magnitude) {
+static __inline bool ippToPsps_getFlux(const float zeroPoint, const float exposureTime, const float magnitude, float* flux) {
 
     // use uncalibrated instrumental flux
-    float flux = powf(10.0, -0.4*magnitude) / exposureTime;
+    *flux = powf(10.0, -0.4*magnitude) / exposureTime;
 
     // use calibrated flux in Janskys, where 3631 Jy is the zero point flux for the filter: constant over all filters because we're using AB magnitudes
@@ -23,5 +23,5 @@
 
     //    printf("mag=%f\texpTime=%f\tzeroPoint=%f\tflux=%f\n", magnitude, exposureTime, zeroPoint, flux);
-    return isnormal(flux) ? flux : -999.0;
+    return (!isfinite(*flux) || *flux < 0.000001) ? false : true;
 }
 
@@ -151,8 +151,9 @@
     short nOta = 0;
     long i;
-    bool duplicate;
+    bool isDuplicate;
     uint32_t numOfDuplicates;
+    uint32_t numInvalidFlux;
     long numDetectionsOut;
-    long duplicateList[MAXDETECT];
+    long removeList[MAXDETECT];
     long thisObjId;
 
@@ -217,5 +218,5 @@
             fits_write_col(this->fitsOut, TLONG, IMAGEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
             fits_write_col(this->fitsOut, TSHORT, IMAGEMETA_CCDID, 1, 1, 1, &pImage->ccdnum, &status);
-            // fits_write_col(this->fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &pImage->photcode, &status); TODO
+            fits_write_col(this->fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &pImage->photcode, &status);
             fits_write_col(this->fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID, &status);
             fits_write_col(this->fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs, &status);
@@ -252,5 +253,8 @@
             // both DVO detections and smf detections should increment. however, there may be gaps in smf and 'invalid' rows in dvo
             numOfDuplicates = 0;
+            numInvalidFlux = 0;
             for (long s = 0; s<nDet; s++) {
+
+                isDuplicate = false;
 
                 // count jumps in smf file
@@ -266,11 +270,10 @@
 
                     // TODO HACK duplicates bug - don't include any duplicates
-                    duplicate = false;
                     thisObjId = dvoDetections[d].ave.extID;
                     for (i=0; i<totalDetections; i++) {
                         if (thisObjId == objID[i]) {
-                            duplicate = true;
-                            duplicateList[numOfDuplicates] = s+1;
+                            removeList[numOfDuplicates+numInvalidFlux] = s+1;
                             numOfDuplicates++;
+                            isDuplicate=true;
                             break;
                         }
@@ -283,7 +286,13 @@
                     imageID[s] = pspsImageId;
                     obsTimes[s] = obsTime;
-                    instFlux[s] = ippToPsps_getFlux(zeroPoint, exposureTime, instMag[s]);
-                    instFluxErr[s] = ippToPsps_getFlux(zeroPoint, exposureTime, instMagErr[s]);
-                    peakFlux[s] = ippToPsps_getFlux(zeroPoint, exposureTime, peakMag[s]);
+
+                    ippToPsps_getFlux(zeroPoint, exposureTime, instMagErr[s], &instFluxErr[s]);
+
+                    // check for invalid flux values (if not already labelled as a duplicate)
+                    if ((!ippToPsps_getFlux(zeroPoint, exposureTime, peakMag[s], &peakFlux[s]) ||
+                                !ippToPsps_getFlux(zeroPoint, exposureTime, instMag[s], &instFlux[s])) && !isDuplicate) {
+                        removeList[numOfDuplicates+numInvalidFlux] = s+1;
+                        numInvalidFlux++;
+                    }
 
                     // store max/min objID
@@ -304,6 +313,6 @@
 
             // write number of rows (detections) to ImageMeta
-            numDetectionsOut = totalDetections - numOfDuplicates;
-            fits_write_col(this->fitsOut, TLONG, 10, 1, 1, 1, &numDetectionsOut, &status);
+            numDetectionsOut = totalDetections - numOfDuplicates - numInvalidFlux;
+            fits_write_col(this->fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &numDetectionsOut, &status);
 
             // detections
@@ -321,5 +330,5 @@
             fits_write_col(this->fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nDet, peakFlux, &status);
             fits_write_col(this->fitsOut, TSTRING, DETECTION_ASSOCDATE, 1, 1, nDet, assocDate, &status); 
-            if (numOfDuplicates) fits_delete_rowlist(this->fitsOut, duplicateList, numOfDuplicates, &status);
+            if (numOfDuplicates||numInvalidFlux) fits_delete_rowlist(this->fitsOut, removeList, numOfDuplicates+numInvalidFlux, &status);
 
             // skinny object
@@ -327,5 +336,5 @@
             fits_write_col(this->fitsOut, TLONGLONG, SKINNYOBJECT_OBJID, 1, 1, nDet, objID, &status);
             fits_write_col(this->fitsOut, TLONGLONG, SKINNYOBJECT_IPPOBJID, 1, 1, nDet, ippObjID, &status);
-            if (numOfDuplicates) fits_delete_rowlist(this->fitsOut, duplicateList, numOfDuplicates, &status);
+            if (numOfDuplicates||numInvalidFlux) fits_delete_rowlist(this->fitsOut, removeList, numOfDuplicates+numInvalidFlux, &status);
 
             // object calibration color
@@ -334,11 +343,11 @@
             fits_write_col(this->fitsOut, TLONGLONG, OBJECTCALCOLOR_IPPOBJID, 1, 1, nDet, ippObjID, &status);
             fits_write_col(this->fitsOut, TBYTE, OBJECTCALCOLOR_FILTERID, 1, 1, nDet, filterIDs, &status);
-            if (numOfDuplicates) fits_delete_rowlist(this->fitsOut, duplicateList, numOfDuplicates, &status);
+            if (numOfDuplicates||numInvalidFlux) fits_delete_rowlist(this->fitsOut, removeList, numOfDuplicates+numInvalidFlux, &status);
 
             psLogMsg("ippToPsps", PS_LOG_INFO,
-                    " ___________________________________________________________________\n"
-                    "| Extension | Rows in | Rows out | Missing from DVO | Duplicate IDs |\n"
-                    "|  %s |  %5ld  |   %5ld  |      %5d       |    %5d      |\n",
-                    extensionName, nDet, numDetectionsOut, unmatched, numOfDuplicates);
+                    "+-----------+---------+----------+------------------+---------------+--------------+\n"
+                    "| Extension | Rows in | Rows out | Missing from DVO | Duplicate IDs | Invalid Flux |\n"
+                    "|  %s |  %5ld  |   %5ld  |      %5d       |    %5d      |    %5d     |\n",
+                    extensionName, nDet, numDetectionsOut, unmatched, numOfDuplicates, numInvalidFlux);
 
             if (dvoDetections!= NULL) dvoFree(dvoDetections);
@@ -353,5 +362,5 @@
     status=0; 
     if (fits_movnam_hdu(this->fitsOut, BINARY_TBL, "FrameMeta", 0, &status))
-            psError(PS_ERR_IO, false, "Can't move back to FrameMeta extension to write number of OTAs\n");
+        psError(PS_ERR_IO, false, "Can't move back to FrameMeta extension to write number of OTAs\n");
     else 
         fits_write_col(this->fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta, &status);
Index: /branches/pap/ippToPsps/src/ippToPspsBatchTest.c
===================================================================
--- /branches/pap/ippToPsps/src/ippToPspsBatchTest.c	(revision 28003)
+++ /branches/pap/ippToPsps/src/ippToPspsBatchTest.c	(revision 28003)
@@ -0,0 +1,347 @@
+/** @file ippToPspsBatchDetection.c
+ *
+ *  @ingroup ippToPsps
+ *
+ *  @author IfA
+ *  Copyright 2009 Institute for Astronomy, University of Hawaii
+ */
+
+#include <limits.h>
+#include "ippToPsps.h"
+#include "ippToPspsConfig.h"
+#include "ippToPspsTestEnums.h"
+#include "fitsio.h"
+
+// Gets flux from magnitude
+static __inline bool ippToPsps_getFlux(const float zeroPoint, const float exposureTime, const float magnitude, float* flux) {
+
+    // use uncalibrated instrumental flux
+    *flux = powf(10.0, -0.4*magnitude) / exposureTime;
+
+    // use calibrated flux in Janskys, where 3631 Jy is the zero point flux for the filter: constant over all filters because we're using AB magnitudes
+    //float flux = 3631 * powf(10.0, -0.4*(magnitude + zeroPoint)) / exposureTime;
+
+    //    printf("mag=%f\texpTime=%f\tzeroPoint=%f\tflux=%f\n", magnitude, exposureTime, zeroPoint, flux);
+    return (!isfinite(*flux) || *flux < 0.000001) ? false : true;
+}
+
+/**
+  \brief test data for checking PSPS values correspond with IPP 
+
+  */
+int ippToPsps_batchTest(IppToPsps *this) {
+
+    if (this->numOfInputFiles < 1) return PS_EXIT_DATA_ERROR;
+
+    int status = 0;
+    fitsfile *fitsIn;         
+    int nKeys;
+
+    if (fits_open_file(&fitsIn, this->inputFiles[0], READONLY, &status)) {
+
+        fits_report_error(stderr, status);
+        return PS_EXIT_SYS_ERROR;
+    }
+
+    // get primary header and pull stuff out for later
+    fits_get_hdrspace(fitsIn, &nKeys, NULL, &status);
+
+    float zptObs, zeroPoint, exposureTime;
+    char filterType[20];
+    status=0; fits_read_key(fitsIn, TFLOAT, "ZPT_OBS", &zptObs, NULL, &status);
+    status=0; fits_read_key(fitsIn, TFLOAT, "ZPT_REF", &zeroPoint, NULL, &status);
+    status=0; fits_read_key(fitsIn, TFLOAT, "EXPREQ", &exposureTime, NULL, &status);
+    status=0; fits_read_key(fitsIn, TSTRING, "FILTERID", filterType, NULL, &status);
+    
+    ippToPspsConfig_writeTable(this->config, fitsIn, this->fitsOut, 1, "FrameMeta", true);
+
+    // FrameMeta values
+    fits_write_col(this->fitsOut, TLONG, FRAMEMETA_FRAMEID, 1, 1, 1, &this->expId, &status);
+
+    int8_t filterID = -1;
+    ippToPspsConfig_getFilterId(this->config, filterType, &filterID);
+    fits_write_col(this->fitsOut, TBYTE, FRAMEMETA_FILTERID, 1, 1, 1, &filterID, &status);
+
+    // stuff to keep from psf.hdr header
+    double obsTime = 0.0;
+    int sourceId = -1;
+    int imageId = -1;
+    float fwhmMaj;
+    float fwhmMin;
+    float momentMaj;
+    float momentMin;
+    float psfFwhm;
+    float momentFwhm;
+    long pspsImageId = -1;
+
+    // DVO variables
+    SkyList *skylist = NULL;
+    dvoDetection *dvoDetections = NULL;
+    int maxDvoDetId = -1;
+    int numDvoDetections = -1;
+    Image *pImage = NULL;
+
+    // stuff for detections table
+    time_t now;
+    struct tm *ts;
+    char timeStr[12];
+    now = time(NULL);
+    ts = gmtime(&now); // TODO should be UTC
+    strftime(timeStr, sizeof(timeStr), "%Y-%m-%d", ts);
+
+    uint32_t totalDetections = 0;
+    uint32_t s,d;
+    uint32_t invalidDvoRows;
+    uint32_t smfJumps;
+    uint32_t unmatched;
+
+    long longnull = -999;
+    float floatnull = -999.0;
+    int anynull = 0;
+
+    char ccdNumber[3];
+    char extensionName[15];
+
+    long ippIDet[MAXDETECT];
+    float instMag[MAXDETECT];
+    float instMagErr[MAXDETECT];
+    float peakMag[MAXDETECT];
+    long objID[MAXDETECT];
+    long detectID[MAXDETECT];
+    long ippObjID[MAXDETECT];
+    long ippDetectID[MAXDETECT];
+    long imageID[MAXDETECT];
+    float obsTimes[MAXDETECT];
+    float instFlux[MAXDETECT];
+    float instFluxErr[MAXDETECT];
+    float peakFlux[MAXDETECT];
+    int8_t filterIDs[MAXDETECT];
+
+    char** assocDate = (char**)calloc(MAXDETECT, sizeof(char**));
+    for (uint32_t i=0; i<MAXDETECT;i++) assocDate[i] = (char*)calloc(20,sizeof(char));
+
+    // some stuff is the same for all detections so we can populate here
+    for (long s = 0; s<MAXDETECT; s++) {
+
+        filterIDs[s] = filterID;
+        strcpy(assocDate[s], timeStr);
+    }
+
+    long maxObjID = LONG_MIN; 
+    long minObjID = LONG_MAX;
+    short nOta = 0;
+    long i;
+    bool isDuplicate;
+    uint32_t numOfDuplicates;
+    uint32_t numInvalidFlux;
+    long numDetectionsOut;
+    long removeList[MAXDETECT];
+    long thisObjId;
+
+    // loop round all 60 chips
+    for (int x=3; x<4; x++) {
+        for (int y=3; y<4; y++) {
+
+            // dodge the corners
+            if (x==0 && y==0) continue;
+            if (x==0 && y==7) continue;
+            if (x==7 && y==0) continue;
+            if (x==7 && y==7) continue;
+
+            sprintf(ccdNumber, "%d%d", x, y);
+
+            // check we can move to detections table in smf
+            sprintf(extensionName, "XY%s.psf", ccdNumber);
+            status=0;
+            if (fits_movnam_hdu(fitsIn, BINARY_TBL, extensionName, 0, &status)) {
+                psError(PS_ERR_IO, false, "Can't move to extension: %s skipping this chip\n", extensionName);
+                continue;
+            }
+
+            // move to header extension
+            sprintf(extensionName, "XY%s.hdr", ccdNumber);
+            status=0;
+            if (fits_movnam_hdu(fitsIn, IMAGE_HDU, extensionName, 0, &status)) {
+                psError(PS_ERR_IO, false, "Can't move to extension: %s skipping this chip\n", extensionName);
+                continue;
+            }
+
+            // stuff to save from psf.hdr
+            status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MAJ", &fwhmMaj, NULL, &status);
+            status=0; fits_read_key(fitsIn, TFLOAT, "FWHM_MIN", &fwhmMin, NULL, &status);
+            status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW1", &momentMaj, NULL, &status);
+            status=0; fits_read_key(fitsIn, TFLOAT, "IQ_FW2", &momentMin, NULL, &status);
+            status=0; fits_read_key(fitsIn, TDOUBLE, "MJD-OBS", &obsTime, NULL, &status);
+
+            status=0; fits_read_key(fitsIn, TLONG, "IMAGEID", &imageId, NULL, &status);
+            status=0; fits_read_key(fitsIn, TLONG, "SOURCEID", &sourceId, NULL, &status);
+
+            // access DVO database
+            skylist = dvoSkyListByExternID(this->dvoConfig, sourceId, imageId, &pImage);
+            if (skylist == NULL) {
+                psError(PS_ERR_IO, false, "DVO: can't find SkyList for sourceId='%d' imageId='%d' (CCD = XY%s): skipping\n", sourceId, imageId, ccdNumber);
+                continue;
+            }
+
+            // create unique int from 'frameID' (aka exposure ID) and ccd number
+            pspsImageId = (this->expId*100) + pImage->ccdnum;
+
+            // now get DVO detections
+            dvoDetections = NULL;
+            numDvoDetections = dvoGetDetections(skylist, pImage->imageID, &dvoDetections, &maxDvoDetId);
+
+            // TODO check nDet < MAXDETECT
+
+            // create ImageMeta
+            ippToPspsConfig_writeTable(this->config, fitsIn, this->fitsOut, 1, "ImageMeta", true);
+            psfFwhm = (fwhmMaj+fwhmMin)/2;
+            momentFwhm = (momentMaj+momentMin)/2;
+            fits_write_col(this->fitsOut, TLONG, IMAGEMETA_PHOTOCALID, 1, 1, 1, &pImage->photcode, &status); 
+            fits_write_col(this->fitsOut, TBYTE, IMAGEMETA_FILTERID, 1, 1, 1, &filterID, &status);
+            fits_write_col(this->fitsOut, TFLOAT, IMAGEMETA_PHOTOSCAT, 1, 1, 1, &zptObs, &status);
+            fits_write_col(this->fitsOut, TFLOAT, IMAGEMETA_PSFFWHM, 1, 1, 1, &psfFwhm, &status);
+            fits_write_col(this->fitsOut, TFLOAT, IMAGEMETA_PHOTOZERO, 1, 1, 1, &zptObs, &status);
+
+            // now move BACK to detections table in smf
+            sprintf(extensionName, "XY%s.psf", ccdNumber);
+            status=0;
+            if (fits_movnam_hdu(fitsIn, BINARY_TBL, extensionName, 0, &status)) {
+                psError(PS_ERR_IO, false, "Can't move to extension: %s skipping\n", extensionName);
+                continue;
+            }
+
+            // keep a running count of 'images' we find in order to write total to FrameMeta at the end
+            nOta++;
+
+            long nDet = 0;
+            if (fits_get_num_rows(fitsIn, &nDet, &status)) {
+                fits_report_error(stderr, status);
+            }
+
+            // loop round detections to populate some extra stuff
+            s = d = totalDetections = invalidDvoRows = smfJumps = unmatched = 0;
+
+            anynull = 0;
+            fits_read_col(fitsIn, TLONG, 1, 1, 1, nDet, &longnull, ippIDet, &anynull, &status);
+            fits_read_col(fitsIn, TFLOAT, 8, 1, 1, nDet, &floatnull, instMag, &anynull, &status);
+            fits_read_col(fitsIn, TFLOAT, 9, 1, 1, nDet, &floatnull, instMagErr, &anynull, &status);
+            fits_read_col(fitsIn, TFLOAT, 12, 1, 1, nDet, &floatnull, peakMag, &anynull, &status);
+
+            // DVO detections are ordered by IPP_IDET, which increments from 0 in SMF table
+            // both DVO detections and smf detections should increment. however, there may be gaps in smf and 'invalid' rows in dvo
+            numOfDuplicates = 0;
+            numInvalidFlux = 0;
+            for (long s = 0; s<nDet; s++) {
+
+                isDuplicate = false;
+
+                // count jumps in smf file
+                if (s>0 && (ippIDet[s] != (ippIDet[s-1] + 1))) smfJumps++;
+
+                while (ippIDet[s] > dvoDetections[d].meas.detID && dvoDetections[d].meas.detID <= maxDvoDetId) {
+
+                    d++;
+                    if (!dvoDetections[d].valid) invalidDvoRows++;
+                }
+
+                if (ippIDet[s] == dvoDetections[d].meas.detID ) {
+
+                    // TODO HACK duplicates bug - don't include any duplicates
+                    thisObjId = dvoDetections[d].ave.extID;
+                    for (i=0; i<totalDetections; i++) {
+                        if (thisObjId == objID[i]) {
+                            removeList[numOfDuplicates+numInvalidFlux] = s+1;
+                            numOfDuplicates++;
+                            isDuplicate=true;
+                            break;
+                        }
+                    }
+                    // populate some arrays to be shoved in table in bulk later
+                    objID[s] = thisObjId;
+                    detectID[s] = dvoDetections[d].meas.extID;
+                    ippObjID[s] = (uint64_t)dvoDetections[d].ave.catID*1000000000 + (uint64_t)dvoDetections[d].ave.objID;
+                    ippDetectID[s] = dvoDetections[d].meas.detID;
+                    imageID[s] = pspsImageId;
+                    obsTimes[s] = obsTime;
+
+                    ippToPsps_getFlux(zeroPoint, exposureTime, instMagErr[s], &instFluxErr[s]);
+
+                    // check for invalid flux values (if not already labelled as a duplicate)
+                    if ((!ippToPsps_getFlux(zeroPoint, exposureTime, peakMag[s], &peakFlux[s]) ||
+                                !ippToPsps_getFlux(zeroPoint, exposureTime, instMag[s], &instFlux[s])) && !isDuplicate) {
+                        removeList[numOfDuplicates+numInvalidFlux] = s+1;
+                        numInvalidFlux++;
+                    }
+
+                    // store max/min objID
+                    if (objID[s] > maxObjID) maxObjID = objID[s];
+                    if (objID[s] < minObjID) minObjID = objID[s];
+
+                    totalDetections++;
+                }
+                // if we get here then we cannot find this smf detection in DVO 
+                else {
+
+                    unmatched++;
+                    continue;
+                }
+
+                if (dvoDetections[d].meas.detID == maxDvoDetId) break;
+            }
+
+            // write number of rows (detections) to ImageMeta
+            numDetectionsOut = totalDetections - numOfDuplicates - numInvalidFlux;
+            fits_write_col(this->fitsOut, TLONG, IMAGEMETA_NDETECT, 1, 1, 1, &numDetectionsOut, &status);
+
+            // detections
+            ippToPspsConfig_writeTable(this->config, fitsIn, this->fitsOut, nDet, "Detection", false);
+            fits_write_col(this->fitsOut, TLONGLONG, DETECTION_OBJID, 1, 1, nDet, objID, &status);
+            fits_write_col(this->fitsOut, TLONGLONG, DETECTION_DETECTID, 1, 1, nDet, detectID, &status);
+            fits_write_col(this->fitsOut, TLONGLONG, DETECTION_IPPOBJID, 1, 1, nDet, ippObjID, &status);
+            fits_write_col(this->fitsOut, TLONGLONG, DETECTION_IPPDETECTID, 1, 1, nDet, ippDetectID, &status);
+            fits_write_col(this->fitsOut, TBYTE, DETECTION_FILTERID, 1, 1, nDet, filterIDs, &status);
+            fits_write_col(this->fitsOut, TFLOAT, DETECTION_INSTFLUX, 1, 1, nDet, instFlux, &status);
+            fits_write_col(this->fitsOut, TFLOAT, DETECTION_INSTFLUXERR, 1, 1, nDet, instFluxErr, &status);
+            fits_write_col(this->fitsOut, TFLOAT, DETECTION_PEAKADU, 1, 1, nDet, peakFlux, &status);
+            if (numOfDuplicates||numInvalidFlux) fits_delete_rowlist(this->fitsOut, removeList, numOfDuplicates+numInvalidFlux, &status);
+
+
+            psLogMsg("ippToPsps", PS_LOG_INFO,
+                    "+-----------+---------+----------+------------------+---------------+--------------+\n"
+                    "| Extension | Rows in | Rows out | Missing from DVO | Duplicate IDs | Invalid Flux |\n"
+                    "|  %s |  %5ld  |   %5ld  |      %5d       |    %5d      |    %5d     |\n",
+                    extensionName, nDet, numDetectionsOut, unmatched, numOfDuplicates, numInvalidFlux);
+
+            if (dvoDetections!= NULL) dvoFree(dvoDetections);
+            SkyListFree(skylist);
+        }
+    }
+
+    for (uint32_t i=0; i<MAXDETECT;i++) free(assocDate[i]);
+    free(assocDate);
+
+    // write number of images we have found into FrameMeta table
+    status=0; 
+    if (fits_movnam_hdu(this->fitsOut, BINARY_TBL, "FrameMeta", 0, &status))
+        psError(PS_ERR_IO, false, "Can't move back to FrameMeta extension to write number of OTAs\n");
+    else 
+        fits_write_col(this->fitsOut, TSHORT, FRAMEMETA_NOTA, 1, 1, 1, &nOta, &status);
+
+    status=0;
+    if (fits_close_file(fitsIn, &status)) fits_report_error(stderr, status);
+
+    // write results
+    if (this->resultsFile) {
+
+        if (fprintf(this->resultsFile, "%ld\n", minObjID) < 1 ) 
+            psError(PS_ERR_IO, false, "Unable to write min Object ID to'%s'\n", this->resultsPath);
+        if (fprintf(this->resultsFile, "%ld\n", maxObjID) < 1 ) 
+            psError(PS_ERR_IO, false, "Unable to write max Object ID to'%s'\n", this->resultsPath);
+    }
+
+    psLogMsg("ippToPsps", PS_LOG_INFO, "Data written for a total of %d chips/OTAs", nOta);
+
+    return PS_EXIT_SUCCESS;
+}
+
+
Index: /branches/pap/ippToPsps/src/ippToPspsConfig.c
===================================================================
--- /branches/pap/ippToPsps/src/ippToPspsConfig.c	(revision 28002)
+++ /branches/pap/ippToPsps/src/ippToPspsConfig.c	(revision 28003)
@@ -737,5 +737,5 @@
                     if (fromHeader) {
                         fits_read_key(fitsIn, TBYTE, table->columns[i].ippName, &int8col[0], NULL, &readStatus);
-                        if (!isnormal(int8col[0])) int8col[0] = int8null;
+                        if (!isfinite(int8col[0])) int8col[0] = int8null;
                     }
                     else fits_read_col(fitsIn, TBYTE, table->columns[i].ippColNum, 1, 1, nRows, &int8null, int8col, &anynull, &readStatus);
@@ -745,5 +745,5 @@
                     if (fromHeader) {
                         fits_read_key(fitsIn, TSHORT, table->columns[i].ippName, &int16col[0], NULL, &readStatus);
-                        if (!isnormal(int16col[0])) int16col[0] = int16null;
+                        if (!isfinite(int16col[0])) int16col[0] = int16null;
                     }
                     else fits_read_col(fitsIn, TSHORT, table->columns[i].ippColNum, 1, 1, nRows, &int16null, int16col, &anynull, &readStatus);
@@ -753,5 +753,5 @@
                     if (fromHeader) {
                         fits_read_key(fitsIn, TLONG, table->columns[i].ippName, &longcol[0], NULL, &readStatus);
-                        if (!isnormal(longcol[0])) longcol[0] = longnull;
+                        if (!isfinite(longcol[0])) longcol[0] = longnull;
                     }
                     else fits_read_col(fitsIn, TLONG, table->columns[i].ippColNum, 1, 1, nRows, &longnull, longcol, &anynull, &readStatus);
@@ -761,5 +761,5 @@
                     if (fromHeader) {
                         fits_read_key(fitsIn, TLONGLONG, table->columns[i].ippName, &longcol[0], NULL, &readStatus);
-                        if (!isnormal(longcol[0])) longcol[0] = longnull;
+                        if (!isfinite(longcol[0])) longcol[0] = longnull;
                     }
                     else fits_read_col(fitsIn, TLONGLONG, table->columns[i].ippColNum, 1, 1, nRows, &longnull, longcol, &anynull, &readStatus);
@@ -769,5 +769,5 @@
                     if (fromHeader) {
                         fits_read_key(fitsIn, TFLOAT, table->columns[i].ippName,&floatcol[0], NULL, &readStatus); 
-                        if (!isnormal(floatcol[0])) floatcol[0] = floatnull;
+                        if (!isfinite(floatcol[0])) floatcol[0] = floatnull;
                     }
                     else fits_read_col(fitsIn, TFLOAT, table->columns[i].ippColNum, 1, 1, nRows, &floatnull, floatcol, &anynull, &readStatus);
@@ -777,5 +777,5 @@
                     if (fromHeader) {
                         fits_read_key(fitsIn, TDOUBLE, table->columns[i].ippName, &doublecol[0], NULL, &readStatus);
-                        if (!isnormal(doublecol[0])) doublecol[0] = doublenull;
+                        if (!isfinite(doublecol[0])) doublecol[0] = doublenull;
                     }
                     else fits_read_col(fitsIn, TDOUBLE, table->columns[i].ippColNum, 1, 1, nRows, &doublenull, doublecol, &anynull, &readStatus);
@@ -795,6 +795,13 @@
 
             // TODO need these errors, but strange error handling runs out of memory
-            //if (readStatus) psError(PS_ERR_IO, false, "Unable to read col num '%d' col name '%s'", table->columns[i].ippColNum, table->columns[i].ippName );
-            //if (writeStatus) psError(PS_ERR_IO, false, "Unable to write col '%s'", table->columns[i].pspsName );
+            //if (readStatus) {
+            //    psError(PS_ERR_IO, false, "Unable to read col num '%d' col name '%s', type %d", 
+            //        table->columns[i].ippColNum, table->columns[i].ippName, table->columns[i].ippType);
+            //    fits_report_error(stderr, readStatus);
+            //}
+            //if (writeStatus) {
+            //    psError(PS_ERR_IO, false, "Unable to write col '%s'", table->columns[i].pspsName );
+            //    fits_report_error(stderr, writeStatus);
+            //}
         }
     }
Index: /branches/pap/ippToPsps/src/ippToPspsDetEnums.h
===================================================================
--- /branches/pap/ippToPsps/src/ippToPspsDetEnums.h	(revision 28002)
+++ /branches/pap/ippToPsps/src/ippToPspsDetEnums.h	(revision 28003)
@@ -29,25 +29,27 @@
   FRAMEMETA_CRPIX1 = 24,
   FRAMEMETA_CRPIX2 = 25,
-  FRAMEMETA_PC001001 = 26,
-  FRAMEMETA_PC001002 = 27,
-  FRAMEMETA_PC002001 = 28,
-  FRAMEMETA_PC002002 = 29,
-  FRAMEMETA_POLYORDER = 30,
-  FRAMEMETA_PCA1X3Y0 = 31,
-  FRAMEMETA_PCA1X2Y1 = 32,
-  FRAMEMETA_PCA1X1Y2 = 33,
-  FRAMEMETA_PCA1X0Y3 = 34,
-  FRAMEMETA_PCA1X2Y0 = 35,
-  FRAMEMETA_PCA1X1Y1 = 36,
-  FRAMEMETA_PCA1X0Y2 = 37,
-  FRAMEMETA_PCA2X3Y0 = 38,
-  FRAMEMETA_PCA2X2Y1 = 39,
-  FRAMEMETA_PCA2X1Y2 = 40,
-  FRAMEMETA_PCA2X0Y3 = 41,
-  FRAMEMETA_PCA2X2Y0 = 42,
-  FRAMEMETA_PCA2X1Y1 = 43,
-  FRAMEMETA_PCA2X0Y2 = 44,
-  FRAMEMETA_CALIBMODNUM = 45,
-  FRAMEMETA_DATARELEASE = 46,
+  FRAMEMETA_CDELT1 = 26,
+  FRAMEMETA_CDELT2 = 27,
+  FRAMEMETA_PC001001 = 28,
+  FRAMEMETA_PC001002 = 29,
+  FRAMEMETA_PC002001 = 30,
+  FRAMEMETA_PC002002 = 31,
+  FRAMEMETA_POLYORDER = 32,
+  FRAMEMETA_PCA1X3Y0 = 33,
+  FRAMEMETA_PCA1X2Y1 = 34,
+  FRAMEMETA_PCA1X1Y2 = 35,
+  FRAMEMETA_PCA1X0Y3 = 36,
+  FRAMEMETA_PCA1X2Y0 = 37,
+  FRAMEMETA_PCA1X1Y1 = 38,
+  FRAMEMETA_PCA1X0Y2 = 39,
+  FRAMEMETA_PCA2X3Y0 = 40,
+  FRAMEMETA_PCA2X2Y1 = 41,
+  FRAMEMETA_PCA2X1Y2 = 42,
+  FRAMEMETA_PCA2X0Y3 = 43,
+  FRAMEMETA_PCA2X2Y0 = 44,
+  FRAMEMETA_PCA2X1Y1 = 45,
+  FRAMEMETA_PCA2X0Y2 = 46,
+  FRAMEMETA_CALIBMODNUM = 47,
+  FRAMEMETA_DATARELEASE = 48,
 } FrameMeta;
 
@@ -99,25 +101,27 @@
   IMAGEMETA_CRPIX1 = 45,
   IMAGEMETA_CRPIX2 = 46,
-  IMAGEMETA_PC001001 = 47,
-  IMAGEMETA_PC001002 = 48,
-  IMAGEMETA_PC002001 = 49,
-  IMAGEMETA_PC002002 = 50,
-  IMAGEMETA_POLYORDER = 51,
-  IMAGEMETA_PCA1X3Y0 = 52,
-  IMAGEMETA_PCA1X2Y1 = 53,
-  IMAGEMETA_PCA1X1Y2 = 54,
-  IMAGEMETA_PCA1X0Y3 = 55,
-  IMAGEMETA_PCA1X2Y0 = 56,
-  IMAGEMETA_PCA1X1Y1 = 57,
-  IMAGEMETA_PCA1X0Y2 = 58,
-  IMAGEMETA_PCA2X3Y0 = 59,
-  IMAGEMETA_PCA2X2Y1 = 60,
-  IMAGEMETA_PCA2X1Y2 = 61,
-  IMAGEMETA_PCA2X0Y3 = 62,
-  IMAGEMETA_PCA2X2Y0 = 63,
-  IMAGEMETA_PCA2X1Y1 = 64,
-  IMAGEMETA_PCA2X0Y2 = 65,
-  IMAGEMETA_CALIBMODNUM = 66,
-  IMAGEMETA_DATARELEASE = 67,
+  IMAGEMETA_CDELT1 = 47,
+  IMAGEMETA_CDELT2 = 48,
+  IMAGEMETA_PC001001 = 49,
+  IMAGEMETA_PC001002 = 50,
+  IMAGEMETA_PC002001 = 51,
+  IMAGEMETA_PC002002 = 52,
+  IMAGEMETA_POLYORDER = 53,
+  IMAGEMETA_PCA1X3Y0 = 54,
+  IMAGEMETA_PCA1X2Y1 = 55,
+  IMAGEMETA_PCA1X1Y2 = 56,
+  IMAGEMETA_PCA1X0Y3 = 57,
+  IMAGEMETA_PCA1X2Y0 = 58,
+  IMAGEMETA_PCA1X1Y1 = 59,
+  IMAGEMETA_PCA1X0Y2 = 60,
+  IMAGEMETA_PCA2X3Y0 = 61,
+  IMAGEMETA_PCA2X2Y1 = 62,
+  IMAGEMETA_PCA2X1Y2 = 63,
+  IMAGEMETA_PCA2X0Y3 = 64,
+  IMAGEMETA_PCA2X2Y0 = 65,
+  IMAGEMETA_PCA2X1Y1 = 66,
+  IMAGEMETA_PCA2X0Y2 = 67,
+  IMAGEMETA_CALIBMODNUM = 68,
+  IMAGEMETA_DATARELEASE = 69,
 } ImageMeta;
 
Index: /branches/pap/ippToPsps/src/ippToPspsTestEnums.h
===================================================================
--- /branches/pap/ippToPsps/src/ippToPspsTestEnums.h	(revision 28003)
+++ /branches/pap/ippToPsps/src/ippToPspsTestEnums.h	(revision 28003)
@@ -0,0 +1,113 @@
+#ifndef IPPTOPSPSDETENUMS_H
+#define IPPTOPSPSDETENUMS_H
+
+
+typedef enum {
+  FRAMEMETA_FRAMEID = 1,
+  FRAMEMETA_FILTERID,
+  FRAMEMETA_NOTA,
+  FRAMEMETA_PHOTOSCAT,
+  FRAMEMETA_EXPSTART,
+  FRAMEMETA_EXPTIME,
+  FRAMEMETA_AIRMASS,
+  FRAMEMETA_RABORE,
+  FRAMEMETA_DECBORE,
+  FRAMEMETA_CTYPE1,
+  FRAMEMETA_CTYPE2,
+  FRAMEMETA_CRVAL1,
+  FRAMEMETA_CRVAL2,
+  FRAMEMETA_CRPIX1,
+  FRAMEMETA_CRPIX2,
+  FRAMEMETA_PC001001,
+  FRAMEMETA_PC001002,
+  FRAMEMETA_PC002001,
+  FRAMEMETA_PC002002,
+  FRAMEMETA_POLYORDER,
+  FRAMEMETA_PCA1X3Y0,
+  FRAMEMETA_PCA1X2Y1,
+  FRAMEMETA_PCA1X1Y2,
+  FRAMEMETA_PCA1X0Y3,
+  FRAMEMETA_PCA1X2Y0,
+  FRAMEMETA_PCA1X1Y1,
+  FRAMEMETA_PCA1X0Y2,
+  FRAMEMETA_PCA2X3Y0,
+  FRAMEMETA_PCA2X2Y1,
+  FRAMEMETA_PCA2X1Y2,
+  FRAMEMETA_PCA2X0Y3,
+  FRAMEMETA_PCA2X2Y0,
+  FRAMEMETA_PCA2X1Y1,
+  FRAMEMETA_PCA2X0Y2,
+} FrameMeta;
+
+typedef enum {
+  IMAGEMETA_PHOTOCALID = 1,
+  IMAGEMETA_FILTERID,
+  IMAGEMETA_SKY,
+  IMAGEMETA_SKYSCAT,
+  IMAGEMETA_NDETECT,
+  IMAGEMETA_MAGSAT,
+  IMAGEMETA_COMPLETMAG,
+  IMAGEMETA_ASTROSCAT,
+  IMAGEMETA_PHOTOSCAT,
+  IMAGEMETA_NUMASTROREF,
+  IMAGEMETA_NX,
+  IMAGEMETA_NY,
+  IMAGEMETA_PSFMODELID,
+  IMAGEMETA_PSFFWHM,
+  IMAGEMETA_PSFWIDMAJOR,
+  IMAGEMETA_PSFWIDMINOR,
+  IMAGEMETA_PSFTHETA,
+  IMAGEMETA_APRESID,
+  IMAGEMETA_DAPRESID,
+  IMAGEMETA_PHOTOZERO,
+  IMAGEMETA_CTYPE1,
+  IMAGEMETA_CTYPE2,
+  IMAGEMETA_CRVAL1,
+  IMAGEMETA_CRVAL2,
+  IMAGEMETA_CRPIX1,
+  IMAGEMETA_CRPIX2,
+  IMAGEMETA_PC001001,
+  IMAGEMETA_PC001002,
+  IMAGEMETA_PC002001,
+  IMAGEMETA_PC002002,
+  IMAGEMETA_POLYORDER,
+  IMAGEMETA_PCA1X3Y0,
+  IMAGEMETA_PCA1X2Y1,
+  IMAGEMETA_PCA1X1Y2,
+  IMAGEMETA_PCA1X0Y3,
+  IMAGEMETA_PCA1X2Y0,
+  IMAGEMETA_PCA1X1Y1,
+  IMAGEMETA_PCA1X0Y2,
+  IMAGEMETA_PCA2X3Y0,
+  IMAGEMETA_PCA2X2Y1,
+  IMAGEMETA_PCA2X1Y2,
+  IMAGEMETA_PCA2X0Y3,
+  IMAGEMETA_PCA2X2Y0,
+  IMAGEMETA_PCA2X1Y1,
+  IMAGEMETA_PCA2X0Y2,
+} ImageMeta;
+
+typedef enum {
+  DETECTION_OBJID = 1,
+  DETECTION_DETECTID,
+  DETECTION_IPPOBJID,
+  DETECTION_IPPDETECTID,
+  DETECTION_FILTERID,
+  DETECTION_XPOS,
+  DETECTION_YPOS,
+  DETECTION_XPOSERR,
+  DETECTION_YPOSERR,
+  DETECTION_IPPRA ,
+  DETECTION_IPPDEC ,
+  DETECTION_INSTFLUX,
+  DETECTION_INSTFLUXERR,
+  DETECTION_PEAKADU,
+  DETECTION_PSFWIDMAJOR,
+  DETECTION_PSFWIDMINOR,
+  DETECTION_PSFTHETA,
+  DETECTION_PSFCF,
+  DETECTION_SKY,
+  DETECTION_SKYERR,
+} Detection;
+
+#endif
Index: /branches/pap/ippTools/share/Makefile.am
===================================================================
--- /branches/pap/ippTools/share/Makefile.am	(revision 28002)
+++ /branches/pap/ippTools/share/Makefile.am	(revision 28003)
@@ -31,4 +31,5 @@
      chiptool_donecleanup.sql \
      chiptool_find_rawexp.sql \
+     chiptool_listrun.sql \
      chiptool_pendingcleanupimfile.sql \
      chiptool_pendingcleanuprun.sql \
@@ -36,10 +37,11 @@
      chiptool_processedimfile.sql \
      chiptool_revertprocessedimfile.sql \
+     chiptool_revertupdatedimfile.sql \
      chiptool_run.sql \
      chiptool_runstate.sql \
      chiptool_setimfiletoupdate.sql \
+     chiptool_export_run.sql \
      chiptool_export_imfile.sql \
      chiptool_export_processed_imfile.sql \
-     chiptool_export_run.sql \
      chiptool_unmasked.sql \
      detselect_search.sql \
@@ -109,8 +111,10 @@
      difftool_export_skyfile.sql \
      difftool_inputskyfile.sql \
+     difftool_listrun.sql \
      difftool_pendingcleanuprun.sql \
      difftool_pendingcleanupskyfile.sql \
      difftool_revertdiffskyfile_delete.sql \
-     difftool_revertdiffskyfile_update.sql \
+     difftool_revertdiffskyfile_updated.sql \
+     difftool_setskyfiletoupdate.sql \
      difftool_skyfile.sql \
      difftool_todiffskyfile.sql \
@@ -194,4 +198,5 @@
      magictool_rawimfile.sql \
      magictool_revertnode.sql \
+     magictool_exposure.sql \
      magicdstool_clearstatefaults.sql \
      magicdstool_completed_runs.sql \
@@ -221,12 +226,16 @@
      pstamptool_completedreq.sql \
      pstamptool_datastore.sql \
+     pstamptool_getdependent.sql \
      pstamptool_listjob.sql \
+     pstamptool_pendingcleanup.sql \
      pstamptool_pendingdependent.sql \
      pstamptool_pendingjob.sql \
      pstamptool_pendingreq.sql \
      pstamptool_project.sql \
+     pstamptool_revertdependent.sql \
      pstamptool_revertjob.sql \
      pstamptool_revertreq.sql \
      pstamptool_revertreq_deletejobs.sql \
+     pstamptool_updatejob.sql \
      pxadmin_create_tables.sql \
      pxadmin_create_mirror_tables.sql \
@@ -290,10 +299,13 @@
      warptool_finish_run.sql \
      warptool_imfile.sql \
+     warptool_listrun.sql \
      warptool_pendingcleanuprun.sql \
      warptool_pendingcleanupskyfile.sql \
      warptool_revertoverlap.sql \
      warptool_revertwarped_delete.sql \
+     warptool_revertwarped_updated.sql \
      warptool_runstate.sql \
      warptool_scmap.sql \
+     warptool_setskyfiletoupdate.sql \
      warptool_tooverlap.sql \
      warptool_towarped.sql \
Index: /branches/pap/ippTools/share/camtool_find_pendingexp.sql
===================================================================
--- /branches/pap/ippTools/share/camtool_find_pendingexp.sql	(revision 28002)
+++ /branches/pap/ippTools/share/camtool_find_pendingexp.sql	(revision 28003)
@@ -10,5 +10,6 @@
     rawExp.telescope,
     rawExp.filelevel,
-    chipRun.magicked AS chip_magicked
+    chipRun.magicked AS chip_magicked,
+    camProcessedExp.path_base
 FROM camRun
 JOIN chipRun
Index: /branches/pap/ippTools/share/camtool_find_processedexp.sql
===================================================================
--- /branches/pap/ippTools/share/camtool_find_processedexp.sql	(revision 28002)
+++ /branches/pap/ippTools/share/camtool_find_processedexp.sql	(revision 28003)
@@ -3,6 +3,8 @@
     camRun.workdir,
     camRun.label,
+    camRun.state,
     camRun.magicked,
     chipRun.chip_id,
+    chipRun.state as chip_state,
     chipRun.magicked as chip_magicked,
     rawExp.exp_tag,
Index: /branches/pap/ippTools/share/chiptool_change_imfile_data_state.sql
===================================================================
--- /branches/pap/ippTools/share/chiptool_change_imfile_data_state.sql	(revision 28002)
+++ /branches/pap/ippTools/share/chiptool_change_imfile_data_state.sql	(revision 28003)
@@ -3,4 +3,5 @@
 -- chip_id and class_id
 UPDATE chipProcessedImfile
+JOIN chipRun USING(chip_id, exp_id)
 JOIN rawImfile USING(exp_id, class_id)
     SET 
Index: /branches/pap/ippTools/share/chiptool_listrun.sql
===================================================================
--- /branches/pap/ippTools/share/chiptool_listrun.sql	(revision 28003)
+++ /branches/pap/ippTools/share/chiptool_listrun.sql	(revision 28003)
@@ -0,0 +1,30 @@
+SELECT DISTINCT
+    chipRun.chip_id,
+    chipRun.state,
+    chipRun.workdir,
+    chipRun.label,
+    chipRun.data_group,
+    chipRun.dist_group,
+    chipRun.note,
+    chipRun.magicked,
+    chipRun.reduction,
+    camRun.cam_id,
+    camRun.state AS camRun_state,
+    camProcessedExp.path_base AS cam_path_base,
+    rawExp.exp_id,
+    rawExp.exp_name,
+    rawExp.camera,
+    rawExp.filter,
+    rawExp.dateobs,
+    rawExp.ra,
+    rawExp.decl,
+    rawExp.exp_time,
+    rawExp.magicked AS raw_magicked,
+    magicDSRun.state AS dsRun_state
+FROM chipRun
+JOIN rawExp
+    USING(exp_id)
+LEFT JOIN camRun USING(chip_id)
+LEFT JOIN camProcessedExp USING(cam_id)
+LEFT JOIN magicDSRun
+    ON stage_id = chip_id AND stage = 'chip' AND magicDSRun.re_place
Index: /branches/pap/ippTools/share/chiptool_pendingcleanupimfile.sql
===================================================================
--- /branches/pap/ippTools/share/chiptool_pendingcleanupimfile.sql	(revision 28002)
+++ /branches/pap/ippTools/share/chiptool_pendingcleanupimfile.sql	(revision 28003)
@@ -13,7 +13,8 @@
     USING(chip_id)
 WHERE
-    ((chipRun.state = 'goto_cleaned' AND chipProcessedImfile.data_state = 'full')
+    ((chipRun.state = 'goto_cleaned' AND (chipProcessedImfile.data_state = 'full'
+                                       OR chipProcessedImfile.data_state = 'update'))
 OR 
-    (chipRun.state = 'goto_scrubbed' AND chipProcessedImfile.data_state = 'full')
+    (chipRun.state = 'goto_scrubbed' AND chipProcessedImfile.data_state != 'scrubbed')
 OR 
     (chipRun.state = 'goto_purged' AND chipProcessedImfile.data_state != 'purged'))
Index: /branches/pap/ippTools/share/chiptool_pendingimfile.sql
===================================================================
--- /branches/pap/ippTools/share/chiptool_pendingimfile.sql	(revision 28002)
+++ /branches/pap/ippTools/share/chiptool_pendingimfile.sql	(revision 28003)
@@ -10,5 +10,7 @@
     rawExp.camera,
     rawExp.telescope,
-    rawExp.filelevel
+    rawExp.filelevel,
+    IFNULL(Label.priority, 10000) AS priority,
+    chipProcessedImfile.path_base
 FROM chipRun
 JOIN rawExp
@@ -25,4 +27,5 @@
 LEFT JOIN chipMask
     ON chipRun.label = chipMask.label
+LEFT JOIN Label ON chipRun.label = Label.label
 WHERE
     ((chipRun.state = 'new'
@@ -33,9 +36,5 @@
     OR
     (chipRun.state = 'update'
-    AND chipProcessedImfile.data_state = 'update'))
--- // Restriction to prevent the processing of bad chips. Not needed now.
---     AND
---     (rawImfile.class_id != 'XY15' AND
---     rawImfile.class_id != 'XY32' AND
---     rawImfile.class_id != 'XY45')
-
+    AND chipProcessedImfile.data_state = 'update'
+    AND chipProcessedImfile.fault = 0))
+    AND (Label.active OR Label.active IS NULL)
Index: /branches/pap/ippTools/share/chiptool_processedimfile.sql
===================================================================
--- /branches/pap/ippTools/share/chiptool_processedimfile.sql	(revision 28002)
+++ /branches/pap/ippTools/share/chiptool_processedimfile.sql	(revision 28003)
@@ -22,5 +22,12 @@
     rawExp.camera,
     rawExp.telescope,
-    rawExp.filelevel
+    rawExp.filelevel,
+    rawExp.dateobs,
+    rawExp.ra,
+    rawExp.decl,
+    rawExp.exp_time,
+    rawImfile.magicked AS raw_magicked,
+    rawImfile.burntool_state,
+    magicDSRun.state AS dsRun_state
 FROM chipRun
 JOIN chipImfile
@@ -30,2 +37,7 @@
 JOIN rawExp
     ON chipProcessedImfile.exp_id = rawExp.exp_id
+JOIN rawImfile
+    ON rawExp.exp_id = rawImfile.exp_id 
+    AND chipProcessedImfile.class_id = rawImfile.class_id
+LEFT JOIN magicDSRun
+    ON stage_id = chip_id AND stage = 'chip' AND magicDSRun.re_place
Index: /branches/pap/ippTools/share/chiptool_revertupdatedimfile.sql
===================================================================
--- /branches/pap/ippTools/share/chiptool_revertupdatedimfile.sql	(revision 28003)
+++ /branches/pap/ippTools/share/chiptool_revertupdatedimfile.sql	(revision 28003)
@@ -0,0 +1,8 @@
+UPDATE chipProcessedImfile
+    JOIN chipRun using(chip_id,exp_id)
+    JOIN rawExp using(exp_id)
+SET chipProcessedImfile.fault = 0
+WHERE
+    chipRun.state = 'update'
+    AND chipProcessedImfile.data_state = 'update'
+    AND chipProcessedImfile.fault != 0
Index: /branches/pap/ippTools/share/detselect_search.sql
===================================================================
--- /branches/pap/ippTools/share/detselect_search.sql	(revision 28002)
+++ /branches/pap/ippTools/share/detselect_search.sql	(revision 28003)
@@ -27,3 +27,3 @@
     ) as Foo
 WHERE
-    (state = 'stop' OR state = 'register')
+    (state = 'stop')
Index: /branches/pap/ippTools/share/difftool_definewarpstack_part1.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_definewarpstack_part1.sql	(revision 28002)
+++ /branches/pap/ippTools/share/difftool_definewarpstack_part1.sql	(revision 28003)
@@ -5,4 +5,5 @@
     warpRun.label,
     warpRun.tess_id,
+    warpRun.data_group,
     COUNT(skycell_id) as skycell_count
 FROM warpRun
Index: /branches/pap/ippTools/share/difftool_definewarpwarp_select.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_definewarpwarp_select.sql	(revision 28002)
+++ /branches/pap/ippTools/share/difftool_definewarpwarp_select.sql	(revision 28003)
@@ -3,4 +3,5 @@
     inputWarpRun.tess_id AS tess_id,
     inputRawExp.exp_id AS input_exp_id,
+    inputWarpRun.data_group AS input_data_group,
     -- The following trick pulls out the warp_id that has the smallest distance
     SUBSTRING_INDEX(GROUP_CONCAT(templateWarpRun.warp_id ORDER BY ABS(ASIN(SQRT(POW(SIN(0.5*(inputRawExp.decl - templateRawExp.decl)),2) + COS(inputRawExp.decl) * COS(templateRawExp.decl) * POW(SIN(0.5*(inputRawExp.ra - templateRawExp.ra)),2))))), ',', 1) AS template_warp_id
Index: /branches/pap/ippTools/share/difftool_listrun.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_listrun.sql	(revision 28003)
+++ /branches/pap/ippTools/share/difftool_listrun.sql	(revision 28003)
@@ -0,0 +1,66 @@
+SELECT DISTINCT
+    diffRun.diff_id,
+    diffRun.state,
+    diffRun.workdir,
+    diffRun.label,
+    diffRun.data_group,
+    diffRun.dist_group,
+    diffRun.note,
+    diffRun.magicked,
+    diffRun.diff_mode,
+    diffRun.tess_id,
+    diffRun.bothways,
+    warp1,
+    stack1,
+    warp2,
+    stack2,
+    -- The following are only valid for warps
+    -- XXX This needs to be more clever to handle diffs between stacks
+    -- Zero points are appropriate for both forward and backward diffs
+    camProcessedInput.zpt_obs,
+    camProcessedInput.zpt_stdev,
+    camProcessedInput.zpt_lq,
+    camProcessedInput.zpt_uq,
+    rawInput.comment,
+    rawInput.exp_time,
+    rawInput.camera,
+    rawInput.exp_name AS exp_name_1,
+    rawInput.exp_id AS exp_id_1,
+    chipInput.chip_id AS chip_id_1,
+    camInput.cam_id AS cam_id_1,
+    fakeInput.fake_id AS fake_id_1,
+    camProcessedInput.sigma_ra AS sigma_ra_1,
+    camProcessedInput.sigma_dec AS sigma_dec_1,
+    rawTemplate.exp_name AS exp_name_2,
+    rawTemplate.exp_id AS exp_id_2,
+    chipTemplate.chip_id AS chip_id_2,
+    camTemplate.cam_id AS cam_id_2,
+    fakeTemplate.fake_id AS fake_id_2,
+    camProcessedTemplate.sigma_ra AS sigma_ra_2,
+    camProcessedTemplate.sigma_dec AS sigma_dec_2
+FROM diffRun
+JOIN diffInputSkyfile USING(diff_id)
+LEFT JOIN warpRun AS warpInput
+    ON warpInput.warp_id = diffInputSkyfile.warp1
+LEFT JOIN fakeRun AS fakeInput
+    ON fakeInput.fake_id = warpInput.fake_id
+LEFT JOIN camRun AS camInput
+    ON camInput.cam_id = fakeInput.cam_id
+LEFT JOIN camProcessedExp AS camProcessedInput
+    ON camProcessedInput.cam_id = camInput.cam_id
+LEFT JOIN chipRun AS chipInput
+    ON chipInput.chip_id = camInput.chip_id
+LEFT JOIN rawExp AS rawInput
+    ON rawInput.exp_id = chipInput.exp_id
+LEFT JOIN warpRun AS warpTemplate
+    ON warpTemplate.warp_id = diffInputSkyfile.warp2
+LEFT JOIN fakeRun AS fakeTemplate
+    ON fakeTemplate.fake_id = warpTemplate.fake_id
+LEFT JOIN camRun AS camTemplate
+    ON camTemplate.cam_id = fakeTemplate.cam_id
+LEFT JOIN camProcessedExp AS camProcessedTemplate
+    ON camProcessedTemplate.cam_id = camTemplate.cam_id
+LEFT JOIN chipRun AS chipTemplate
+    ON chipTemplate.chip_id = camTemplate.chip_id
+LEFT JOIN rawExp AS rawTemplate
+    ON rawTemplate.exp_id = chipTemplate.exp_id
Index: /branches/pap/ippTools/share/difftool_revertdiffskyfile_updated.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_revertdiffskyfile_updated.sql	(revision 28003)
+++ /branches/pap/ippTools/share/difftool_revertdiffskyfile_updated.sql	(revision 28003)
@@ -0,0 +1,6 @@
+UPDATE diffSkyfile
+    JOIN diffRun USING(diff_id)
+SET diffSkyfile.fault = 0
+WHERE diffRun.state = 'update'
+    AND diffSkyfile.data_state = 'update'
+    AND diffSkyfile.fault != 0
Index: /branches/pap/ippTools/share/difftool_setskyfiletoupdate.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_setskyfiletoupdate.sql	(revision 28003)
+++ /branches/pap/ippTools/share/difftool_setskyfiletoupdate.sql	(revision 28003)
@@ -0,0 +1,8 @@
+UPDATE diffRun
+    JOIN diffSkyfile USING(diff_id)
+SET diffRun.state = 'update', 
+    diffSkyfile.data_state = 'update'
+    -- set hook %s
+WHERE diff_id = %lld
+    AND (diffRun.state = 'cleaned' OR diffRun.state = 'update')
+    AND (diffSkyfile.data_state = 'cleaned')
Index: /branches/pap/ippTools/share/difftool_skyfile.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_skyfile.sql	(revision 28002)
+++ /branches/pap/ippTools/share/difftool_skyfile.sql	(revision 28003)
@@ -7,4 +7,5 @@
     diffRun.label,
     diffRun.bothways,
+    diffRun.diff_mode,
     warp1,
     stack1,
Index: /branches/pap/ippTools/share/difftool_todiffskyfile.sql
===================================================================
--- /branches/pap/ippTools/share/difftool_todiffskyfile.sql	(revision 28002)
+++ /branches/pap/ippTools/share/difftool_todiffskyfile.sql	(revision 28003)
@@ -12,5 +12,6 @@
     diffRun.reduction,
     diffRun.bothways,
-    diffRun.diff_mode
+    diffRun.diff_mode,
+    diffSkyfile.path_base
 FROM diffRun
 JOIN diffInputSkyfile USING(diff_id)
Index: /branches/pap/ippTools/share/magicdstool_todestreak_camera.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_todestreak_camera.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_todestreak_camera.sql	(revision 28003)
@@ -3,4 +3,5 @@
     magicDSRun.magic_id,
     chipRun.exp_id,
+    camRun.magicked,
     magicDSRun.label,
     camera,
Index: /branches/pap/ippTools/share/magicdstool_todestreak_chip.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_todestreak_chip.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_todestreak_chip.sql	(revision 28003)
@@ -3,4 +3,5 @@
     magicDSRun.magic_id,
     chipRun.exp_id,
+    chipRun.magicked,
     magicDSRun.label,
     camera,
@@ -33,5 +34,5 @@
     magicDSRun.state = 'new'
     AND magicDSRun.stage = 'chip'
-    AND chipRun.state = 'full'
+    AND (chipRun.state = 'full' OR (chipRun.state = 'update' and chipProcessedImfile.data_state = 'full'))
     AND chipProcessedImfile.fault = 0
     AND chipProcessedImfile.quality = 0
Index: /branches/pap/ippTools/share/magicdstool_todestreak_diff.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_todestreak_diff.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_todestreak_diff.sql	(revision 28003)
@@ -10,4 +10,5 @@
     stage,
     magicRun.diff_id AS stage_id,
+    diffRun.magicked,
     diffSkyfile.skycell_id AS component,
     CAST(NULL AS CHAR(255)) AS uri,
@@ -47,13 +48,14 @@
     magicDSRun.label,
     rawExp.camera,
-    magicMask.uri as streaks_uri,
+    magicMask.uri AS streaks_uri,
     (SELECT uri from magicMask where magic_id = inv_magic_id) AS inv_streaks_uri,
     stage,
-    magicRun.diff_id as stage_id,
-    diffSkyfile.skycell_id as component,
+    magicRun.diff_id AS stage_id,
+    diffRun.magicked,
+    diffSkyfile.skycell_id AS component,
     CAST(NULL AS CHAR(255)) AS uri,
     diffSkyfile.path_base,
     magicRun.inverse,
-    CAST(NULL AS CHAR(255)) as cam_path_base,
+    CAST(NULL AS CHAR(255)) AS cam_path_base,
     CAST(NULL AS CHAR(255)) AS cam_reduction,
     outroot,
@@ -80,5 +82,5 @@
     AND diffSkyfile.quality = 0
     AND magicDSFile.component IS NULL
-) as magicDSRun
+) AS magicDSRun
 -- we need the following so this query is compatible with the other stages
 WHERE magic_ds_id IS NOT NULL
Index: /branches/pap/ippTools/share/magicdstool_todestreak_raw.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_todestreak_raw.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_todestreak_raw.sql	(revision 28003)
@@ -4,9 +4,10 @@
     magicRun.exp_id,
     magicDSRun.label,
-    camera,
+    rawExp.camera,
     magicMask.uri as streaks_uri,
     CAST(NULL AS CHAR(255)) AS inv_streaks_uri,
     stage,
     stage_id,
+    rawExp.magicked,
     class_id as component,
     rawImfile.uri AS uri,
@@ -25,5 +26,6 @@
 JOIN camRun USING(cam_id)
 JOIN camProcessedExp USING(cam_id)
-JOIN rawImfile ON magicRun.exp_id = rawImfile.exp_id
+JOIN rawExp ON magicRun.exp_id = rawExp.exp_id
+JOIN rawImfile ON rawExp.exp_id = rawImfile.exp_id
 LEFT JOIN magicDSFile
     ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
Index: /branches/pap/ippTools/share/magicdstool_todestreak_warp.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_todestreak_warp.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_todestreak_warp.sql	(revision 28003)
@@ -9,4 +9,5 @@
     stage,
     stage_id,
+    warpRun.magicked,
     warpSkyfile.skycell_id as component,
     warpSkyfile.uri,
Index: /branches/pap/ippTools/share/magicdstool_torevert_camera.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_torevert_camera.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_torevert_camera.sql	(revision 28003)
@@ -13,5 +13,6 @@
     0 AS bothways,
     0 AS bytes,
-    0 AS md5sum
+    0 AS md5sum,
+    camRun.magicked
 FROM magicDSRun
     JOIN magicDSFile using(magic_ds_id)
Index: /branches/pap/ippTools/share/magicdstool_torevert_chip.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_torevert_chip.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_torevert_chip.sql	(revision 28003)
@@ -13,9 +13,12 @@
     0 AS bothways,
     0 AS bytes,
-    0 AS md5sum
+    0 AS md5sum,
+    chipRun.magicked
 FROM magicDSRun
     JOIN magicDSFile using(magic_ds_id)
     JOIN camProcessedExp using(cam_id)
-    JOIN chipProcessedImfile ON (stage_id = chipProcessedImfile.chip_id AND component = class_id)
+    JOIN chipRun ON (stage_id = chipRun.chip_id)
+    -- JOIN chipProcessedImfile ON (stage_id = chipProcessedImfile.chip_id AND component = class_id)
+    JOIN chipProcessedImfile USING(chip_id, exp_id)
     JOIN rawExp using(exp_id)
 WHERE magicDSRun.stage = 'chip'
Index: /branches/pap/ippTools/share/magicdstool_torevert_diff.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_torevert_diff.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_torevert_diff.sql	(revision 28003)
@@ -13,5 +13,6 @@
     CAST(diffRun.bothways AS SIGNED) AS bothways,
     0 AS bytes,
-    0 AS md5sum
+    0 AS md5sum,
+    diffRun.magicked
 FROM magicDSRun
     JOIN magicRun using(magic_id)
Index: /branches/pap/ippTools/share/magicdstool_torevert_raw.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_torevert_raw.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_torevert_raw.sql	(revision 28003)
@@ -10,8 +10,9 @@
     outroot,
     rawImfile.uri AS path_base,
-    NULL AS cam_path_base,
+    CAST(NULL AS CHAR(255)) AS cam_path_base, 
     0 AS bothways,
     bytes,
-    md5sum
+    md5sum,
+    0 AS magicked
 FROM magicDSRun
     JOIN magicDSFile using(magic_ds_id)
Index: /branches/pap/ippTools/share/magicdstool_torevert_warp.sql
===================================================================
--- /branches/pap/ippTools/share/magicdstool_torevert_warp.sql	(revision 28002)
+++ /branches/pap/ippTools/share/magicdstool_torevert_warp.sql	(revision 28003)
@@ -13,5 +13,6 @@
     0 AS bothways,
     0 AS bytes,
-    0 AS md5sum
+    0 AS md5sum,
+    warpRun.magicked
 FROM magicDSRun
     JOIN magicDSFile USING(magic_ds_id)
Index: /branches/pap/ippTools/share/magictool_exposure.sql
===================================================================
--- /branches/pap/ippTools/share/magictool_exposure.sql	(revision 28003)
+++ /branches/pap/ippTools/share/magictool_exposure.sql	(revision 28003)
@@ -0,0 +1,54 @@
+SELECT *
+FROM (
+    -- Forward diff
+    SELECT DISTINCT
+        magicRun.magic_id,
+        rawExp.*,
+        camProcessedExp.path_base,
+        camProcessedExp.zpt_obs,
+        camProcessedExp.zpt_stdev,
+        camProcessedExp.fwhm_major,
+        camProcessedExp.fwhm_minor,
+        camProcessedExp.iq_m2,
+        camProcessedExp.iq_m3,
+        camProcessedExp.iq_m4
+    FROM
+        magicRun
+    JOIN diffRun USING(diff_id)
+    JOIN diffInputSkyfile USING(diff_id)
+    LEFT JOIN warpRun
+        ON warpRun.warp_id = diffInputSkyfile.warp1
+        AND magicRun.inverse = 0
+    JOIN fakeRun USING(fake_id)
+    JOIN camRun USING(cam_id)
+    JOIN camProcessedExp USING(cam_id)
+    JOIN chipRun USING(chip_id,exp_id)
+    JOIN rawExp USING(exp_id)
+    -- WHERE hook %s
+    UNION
+    -- Backward diff
+    SELECT DISTINCT
+        magicRun.magic_id,
+        rawExp.*,
+        camProcessedExp.path_base,
+        camProcessedExp.zpt_obs,
+        camProcessedExp.zpt_stdev,
+        camProcessedExp.fwhm_major,
+        camProcessedExp.fwhm_minor,
+        camProcessedExp.iq_m2,
+        camProcessedExp.iq_m3,
+        camProcessedExp.iq_m4
+    FROM
+        magicRun
+    JOIN diffRun USING(diff_id)
+    JOIN diffInputSkyfile USING(diff_id)
+    LEFT JOIN warpRun
+        ON warpRun.warp_id = diffInputSkyfile.warp2
+        AND magicRun.inverse = 1
+    JOIN fakeRun USING(fake_id)
+    JOIN camRun USING(cam_id)
+    JOIN camProcessedExp USING(cam_id)
+    JOIN chipRun USING(chip_id,exp_id)
+    JOIN rawExp USING(exp_id)
+    -- WHERE hook %s
+) AS magicExposures
Index: /branches/pap/ippTools/share/pstamptool_completedreq.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_completedreq.sql	(revision 28002)
+++ /branches/pap/ippTools/share/pstamptool_completedreq.sql	(revision 28003)
@@ -1,4 +1,6 @@
-SELECT * 
+SELECT pstampRequest.* ,
+    IFNULL(Label.priority, 0) AS priority
 FROM pstampRequest 
+    LEFT JOIN Label USING(label) 
 WHERE state = 'run'
     AND (
Index: /branches/pap/ippTools/share/pstamptool_getdependent.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_getdependent.sql	(revision 28003)
+++ /branches/pap/ippTools/share/pstamptool_getdependent.sql	(revision 28003)
@@ -0,0 +1,5 @@
+SELECT DISTINCT pstampDependent.*
+FROM pstampDependent
+-- JOIN pstampJob USING(dep_id)
+-- JOIN pstampRequest USING(req_id)
+WHERE pstampDependent.state = 'new'
Index: /branches/pap/ippTools/share/pstamptool_pendingcleanup.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_pendingcleanup.sql	(revision 28003)
+++ /branches/pap/ippTools/share/pstamptool_pendingcleanup.sql	(revision 28003)
@@ -0,0 +1,9 @@
+-- postage stamp requests pending cleanup
+SELECT
+    pstampRequest.*,
+    IFNULL(Label.priority, 10000) AS priority
+FROM pstampRequest
+    LEFT JOIN Label ON pstampRequest.label = Label.label
+WHERE pstampRequest.state = 'goto_cleaned'
+    AND pstampRequest.fault = 0
+    AND (Label.active OR Label.active IS NULL)
Index: /branches/pap/ippTools/share/pstamptool_pendingdependent.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_pendingdependent.sql	(revision 28002)
+++ /branches/pap/ippTools/share/pstamptool_pendingdependent.sql	(revision 28003)
@@ -1,3 +1,12 @@
-SELECT *
+SELECT DISTINCT
+    pstampDependent.*,
+    IFNULL(Label.priority, 10000) AS priority
 FROM pstampDependent
-WHERE state = 'new'
+JOIN pstampJob USING(dep_id)
+JOIN pstampRequest USING(req_id)
+LEFT JOIN Label ON pstampRequest.label = Label.label
+WHERE pstampDependent.state = 'new'
+    AND pstampDependent.fault = 0
+    AND pstampJob.state = 'run'
+    AND (pstampRequest.state = 'run' OR pstampRequest.state = 'new')
+    AND (Label.active OR Label.active IS NULL)
Index: /branches/pap/ippTools/share/pstamptool_pendingjob.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_pendingjob.sql	(revision 28002)
+++ /branches/pap/ippTools/share/pstamptool_pendingjob.sql	(revision 28003)
@@ -1,6 +1,8 @@
-SELECT pstampJob.*
+SELECT pstampJob.*,
+    IFNULL(Label.priority, 10000) AS priority
 FROM pstampJob
     JOIN pstampRequest USING(req_id)
     LEFT JOIN pstampDependent USING(dep_id)
+    LEFT JOIN Label ON pstampRequest.label = Label.label
 WHERE pstampRequest.state = 'run'
     AND pstampRequest.fault = 0
@@ -8,2 +10,3 @@
     AND pstampJob.fault = 0
     AND (dep_id = 0 OR pstampDependent.state = 'full')
+    AND (Label.active OR Label.active IS NULL)
Index: /branches/pap/ippTools/share/pstamptool_pendingreq.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_pendingreq.sql	(revision 28002)
+++ /branches/pap/ippTools/share/pstamptool_pendingreq.sql	(revision 28003)
@@ -1,9 +1,11 @@
 -- postage stamp requests ready for download and parsing
 SELECT
- pstampRequest.*,
- pstampDataStore.outProduct as ds_outProduct
- FROM pstampRequest
- LEFT JOIN pstampDataStore
-    USING(ds_id)
- WHERE pstampRequest.state = 'new'
+    pstampRequest.*,
+    pstampDataStore.outProduct AS ds_outProduct,
+    IFNULL(Label.priority, 10000) AS priority
+FROM pstampRequest
+    LEFT JOIN pstampDataStore USING(ds_id)
+    LEFT JOIN Label ON pstampRequest.label = Label.label
+WHERE pstampRequest.state = 'new'
     AND pstampRequest.fault = 0
+    AND (Label.active OR Label.active IS NULL)
Index: /branches/pap/ippTools/share/pstamptool_revertdependent.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_revertdependent.sql	(revision 28003)
+++ /branches/pap/ippTools/share/pstamptool_revertdependent.sql	(revision 28003)
@@ -0,0 +1,5 @@
+UPDATE pstampDependent
+    JOIN pstampJob USING(dep_id)
+    JOIN pstampRequest USING(req_id)
+SET pstampDependent.fault = 0
+WHERE pstampDependent.state = 'new'
Index: /branches/pap/ippTools/share/pstamptool_updatejob.sql
===================================================================
--- /branches/pap/ippTools/share/pstamptool_updatejob.sql	(revision 28003)
+++ /branches/pap/ippTools/share/pstamptool_updatejob.sql	(revision 28003)
@@ -0,0 +1,2 @@
+UPDATE pstampJob LEFT JOIN pstampDependent USING(dep_id)
+SET 
Index: /branches/pap/ippTools/share/pxadmin_create_tables.sql
===================================================================
--- /branches/pap/ippTools/share/pxadmin_create_tables.sql	(revision 28002)
+++ /branches/pap/ippTools/share/pxadmin_create_tables.sql	(revision 28003)
@@ -1175,4 +1175,6 @@
         KEY(label),
         KEY(fault),
+        KEY(stage),
+        KEY(stage_id),
         FOREIGN KEY(magic_id) REFERENCES magicRun(magic_id),
         FOREIGN KEY(inv_magic_id) REFERENCES magicRun(magic_id)
@@ -1301,4 +1303,5 @@
         outProduct VARCHAR(64),
         uri VARCHAR(255),
+        outdir     VARCHAR(255),
         fault SMALLINT,
         PRIMARY KEY(req_id),
@@ -1327,8 +1330,13 @@
         stage      VARCHAR(64),
         stage_id   BIGINT,
+        component  VARCHAR(64),
         imagedb    VARCHAR(64),
         rlabel     VARCHAR(64),
-        no_magic   TINYINT,
-        PRIMARY KEY(dep_id)
+        outdir     VARCHAR(255),
+        need_magic TINYINT,
+        PRIMARY KEY(dep_id),
+        KEY(state),
+        KEY(stage),
+        KEY(stage_id)
 ) ENGINE=innodb DEFAULT CHARSET=latin1;
 
@@ -1342,4 +1350,8 @@
     comment     VARCHAR(255),
     PRIMARY KEY(target_id),
+    KEY(stage),
+    KEY(dist_group),
+    KEY(filter),
+    KEY(state),
     CONSTRAINT UNIQUE (dist_group, filter, stage, clean)
 )  ENGINE=innodb DEFAULT CHARSET=latin1;
@@ -1365,4 +1377,9 @@
     KEY(state),
     KEY(label),
+    KEY(stage),
+    KEY(stage_id),
+    KEY(magic_ds_id),
+    KEY(fault),
+    KEY(data_group),
     FOREIGN KEY(target_id) REFERENCES distTarget(target_id)
 )  ENGINE=innodb DEFAULT CHARSET=latin1;
@@ -1549,5 +1566,5 @@
       note VARCHAR(255),             -- note
       registered TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- time run was registered
-      PRIMARY KEY(dqstats_id),
+      PRIMARY KEY(ss_id),
       KEY(state),
       KEY(label),
@@ -1581,5 +1598,15 @@
       KEY(fault),
       KEY(quality),
-      FOREIGN KEY(ss_id) REFERENCES staticskyRun(ss_id),
+      FOREIGN KEY(ss_id) REFERENCES staticskyRun(ss_id)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+CREATE TABLE Label (
+    label       VARCHAR(64),
+    priority    INT,
+    active      TINYINT,
+    comment     VARCHAR(80),
+    PRIMARY KEY(label),
+    KEY(priority),
+    KEY(active)
 ) ENGINE=innodb DEFAULT CHARSET=latin1;
 
Index: /branches/pap/ippTools/share/pxadmin_drop_tables.sql
===================================================================
--- /branches/pap/ippTools/share/pxadmin_drop_tables.sql	(revision 28002)
+++ /branches/pap/ippTools/share/pxadmin_drop_tables.sql	(revision 28003)
@@ -81,4 +81,8 @@
 DROP TABLE IF EXISTS publishDone;
 DROP TABLE IF EXISTS pstampDependent;
+DROP TABLE IF EXISTS staticskyInput;
+DROP TABLE IF EXISTS staticskyResult;
+DROP TABLE IF EXISTS staticskyRun;
+DROP TABLE IF EXISTS Label;
 
 SET FOREIGN_KEY_CHECKS=1
Index: /branches/pap/ippTools/share/stacktool_tosum.sql
===================================================================
--- /branches/pap/ippTools/share/stacktool_tosum.sql	(revision 28002)
+++ /branches/pap/ippTools/share/stacktool_tosum.sql	(revision 28003)
@@ -6,5 +6,6 @@
     stackRun.reduction,
     stackRun.label,
-    stackRun.state
+    stackRun.state,
+    stackSumSkyfile.path_base
 FROM stackRun
 JOIN stackInputSkyfile USING(stack_id)
@@ -16,3 +17,3 @@
     -- WHERE hook %s
 GROUP BY stack_id
-HAVING COUNT(warpRun.state = 'full') = COUNT(stackInputSkyfile.warp_id)
+HAVING SUM(IF(warpRun.state = 'full', 1, 0)) = COUNT(stackInputSkyfile.warp_id)
Index: /branches/pap/ippTools/share/warptool_listrun.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_listrun.sql	(revision 28003)
+++ /branches/pap/ippTools/share/warptool_listrun.sql	(revision 28003)
@@ -0,0 +1,21 @@
+SELECT
+    warpRun.*,
+    camRun.cam_id,
+    chipRun.chip_id,
+    rawExp.exp_id,
+    rawExp.exp_name,
+    rawExp.camera,
+    rawExp.filter,
+    rawExp.dateobs,
+    rawExp.ra,
+    rawExp.decl,
+    rawExp.exp_time
+FROM warpRun
+JOIN fakeRun
+    ON warpRun.fake_id = fakeRun.fake_id
+JOIN camRun
+    ON camRun.cam_id   = fakeRun.cam_id
+JOIN chipRun
+    ON camRun.chip_id  = chipRun.chip_id
+JOIN rawExp
+    ON chipRun.exp_id  = rawExp.exp_id
Index: /branches/pap/ippTools/share/warptool_pendingcleanupskyfile.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_pendingcleanupskyfile.sql	(revision 28002)
+++ /branches/pap/ippTools/share/warptool_pendingcleanupskyfile.sql	(revision 28003)
@@ -10,5 +10,6 @@
     USING(warp_id)
 WHERE
-   ((warpRun.state = 'goto_cleaned'  AND warpSkyfile.data_state = 'full')
+   ((warpRun.state = 'goto_cleaned'  AND (warpSkyfile.data_state = 'full'
+                                      OR  warpSkyfile.data_state = 'update'))
     OR
     (warpRun.state = 'goto_scrubbed' AND warpSkyfile.data_state != 'scrubbed')
Index: /branches/pap/ippTools/share/warptool_revertwarped_updated.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_revertwarped_updated.sql	(revision 28003)
+++ /branches/pap/ippTools/share/warptool_revertwarped_updated.sql	(revision 28003)
@@ -0,0 +1,10 @@
+UPDATE warpSkyfile
+    JOIN warpRun USING(warp_id)
+    JOIN fakeRun USING(fake_id)
+    JOIN camRun USING(cam_id)
+    JOIN chipRun USING(chip_id)
+    JOIN rawExp USING(exp_id)
+SET warpSkyfile.fault = 0
+WHERE warpRun.state = 'update'
+    AND warpSkyfile.data_state = 'update'
+    AND warpSkyfile.fault != 0
Index: /branches/pap/ippTools/share/warptool_scmap.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_scmap.sql	(revision 28002)
+++ /branches/pap/ippTools/share/warptool_scmap.sql	(revision 28003)
@@ -3,5 +3,10 @@
     chipProcessedImfile.uri,
     chipProcessedImfile.path_base as chip_path_base,
-    camProcessedExp.path_base as cam_path_base
+    camProcessedExp.path_base as cam_path_base,
+    chipProcessedImfile.chip_id,
+    chipRun.state,
+    chipProcessedImfile.data_state,
+    chipProcessedImfile.magicked,
+    rawImfile.magicked AS raw_magicked
 FROM warpRun
 JOIN warpSkyCellMap
@@ -18,7 +23,7 @@
     ON chipRun.chip_id = chipProcessedImfile.chip_id
     AND warpSkyCellMap.class_id = chipProcessedImfile.class_id
+JOIN rawImfile
+    ON chipRun.exp_id = rawImfile.exp_id
+    AND chipProcessedImfile.class_id = rawImfile.class_id
 WHERE
---    warpRun.state = 'new'
-    fakeRun.state = 'full'
-    AND camRun.state = 'full'
-    AND chipRun.state = 'full'
+    1
Index: /branches/pap/ippTools/share/warptool_setskyfiletoupdate.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_setskyfiletoupdate.sql	(revision 28003)
+++ /branches/pap/ippTools/share/warptool_setskyfiletoupdate.sql	(revision 28003)
@@ -0,0 +1,8 @@
+UPDATE warpRun
+    JOIN warpSkyfile USING(warp_id)
+SET warpRun.state = 'update', 
+    warpSkyfile.data_state = 'update'
+    -- set hook %s
+WHERE warp_id = %lld
+    AND (warpRun.state = 'cleaned' OR warpRun.state = 'update')
+    AND (warpSkyfile.data_state = 'cleaned')
Index: /branches/pap/ippTools/share/warptool_towarped.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_towarped.sql	(revision 28002)
+++ /branches/pap/ippTools/share/warptool_towarped.sql	(revision 28003)
@@ -1,2 +1,17 @@
+SELECT 
+    warp_id,
+    warp_skyfile_id,
+    skycell_id,
+    tess_id,
+    fake_id,
+    state,
+    reduction,
+    cam_id,
+    camera,
+    exp_tag,
+    workdir,
+    magicked,
+    path_base
+FROM (
     SELECT DISTINCT
         warpSkyCellMap.warp_id,
@@ -11,5 +26,6 @@
         rawExp.exp_tag,
         warpRun.workdir,
-        chipRun.magicked
+        chipRun.magicked,
+        CAST(NULL AS CHAR(255)) AS path_base
     FROM warpRun
     JOIN warpSkyCellMap
@@ -45,2 +61,41 @@
         AND warpSkyCellMap.fault = 0
         -- where hook 1 %s
+        -- limit hook 1 %s
+UNION
+    SELECT
+        warpSkyCellMap.warp_id,
+        warpImfile.warp_skyfile_id,
+        warpSkyCellMap.skycell_id,
+        warpSkyCellMap.tess_id,
+        warpRun.fake_id,
+        warpRun.state,
+        warpRun.reduction,
+        camRun.cam_id,
+        rawExp.camera,
+        rawExp.exp_tag,
+        warpRun.workdir,
+        MIN(chipProcessedImfile.magicked) AS magicked,
+        warpSkyfile.path_base
+    FROM warpRun
+    JOIN warpImfile USING(warp_id)
+    JOIN warpSkyCellMap USING(warp_id, skycell_id)
+    JOIN warpSkyfile USING(warp_id, skycell_id)
+    JOIN fakeRun USING(fake_id)
+    JOIN camRun USING(cam_id)
+    JOIN chipRun USING(chip_id)
+    JOIN rawExp USING(exp_id)
+    LEFT JOIN chipProcessedImfile USING(chip_id, class_id)
+    WHERE warpRun.state = 'update'
+        AND warpSkyfile.data_state = 'update'
+        AND warpSkyfile.fault = 0
+        AND camRun.state = 'full'
+        AND chipProcessedImfile.data_state = 'full'
+        -- if warpSkyfile was magicked previously require inputs to be magicked
+        -- this blocks processing until all the chip inputs have been destreaked
+        AND (warpSkyfile.magicked = 0 OR chipProcessedImfile.magicked >= 0)
+        -- where hook 2 %s
+    GROUP BY warp_id, skycell_id
+    HAVING COUNT(warpSkyCellMap.class_id) = COUNT(chipProcessedImfile.class_id)
+    -- limit hook 2 %s
+) as towarped
+
Index: /branches/pap/ippTools/share/warptool_warped.sql
===================================================================
--- /branches/pap/ippTools/share/warptool_warped.sql	(revision 28002)
+++ /branches/pap/ippTools/share/warptool_warped.sql	(revision 28003)
@@ -7,5 +7,10 @@
     rawExp.exp_id,
     rawExp.exp_name,
-    rawExp.camera
+    rawExp.camera,
+    rawExp.filter,
+    rawExp.dateobs,
+    rawExp.ra,
+    rawExp.decl,
+    rawExp.exp_time
 FROM warpRun
 JOIN warpSkyfile
@@ -21,6 +26,2 @@
 JOIN rawExp
     ON chipRun.exp_id  = rawExp.exp_id
-WHERE
--- bogus test; just here so there there is a 'WHERE' stmt to append conditionals too
--- XXX EAM : not needed: fix warptool.c
-    warpRun.warp_id is NOT NULL
Index: /branches/pap/ippTools/src/addtool.c
===================================================================
--- /branches/pap/ippTools/src/addtool.c	(revision 28002)
+++ /branches/pap/ippTools/src/addtool.c	(revision 28003)
@@ -280,4 +280,5 @@
     PXOPT_COPY_STR(config->args, where, "-state",     "addRun.state", "==");
     PXOPT_COPY_STR(config->args, where, "-reduction", "addRun.reduction", "==");
+    PXOPT_COPY_STR(config->args, where, "-dvodb", "addRun.dvodb", "==");
 
     if (!psListLength(where->list)) {
Index: /branches/pap/ippTools/src/addtoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/addtoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/addtoolConfig.c	(revision 28003)
@@ -76,7 +76,9 @@
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-state",                  0, "search by addRun state", NULL);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-reduction",              0, "search by addRun reduction class", NULL);
+    psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-dvodb",                  0, "search by dvodb", NULL);
     psMetadataAddBool(updaterunArgs, PS_LIST_TAIL, "-all",                   0, "allow everything to be queued without search terms", false);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_state",              0, "set state", NULL);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_label",              0, "set label", NULL);
+    psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_dvodb",              0, "set dvodb", NULL);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_data_group", 0,   "define new data_group", NULL);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_dist_group", 0,   "define new dist_group", NULL);
Index: /branches/pap/ippTools/src/camtool.c
===================================================================
--- /branches/pap/ippTools/src/camtool.c	(revision 28002)
+++ /branches/pap/ippTools/src/camtool.c	(revision 28003)
@@ -681,4 +681,5 @@
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_BOOL(faulted, config->args, "-faulted", false);
+    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
 
     // generate restrictions
@@ -741,6 +742,10 @@
     }
 
-    // order by cam_id so that the postage stamp parser can easliy find the 'latest' astrometry
-    psStringAppend(&query, " ORDER BY exp_id, cam_id");
+
+    if (pstamp_order) {
+        // put runs in order of exposure id with newest chip Runs first
+        // The postage stamp parser depends on this behavior
+        psStringAppend(&query, " ORDER BY exp_id, cam_id DESC");
+    }
 
     // treat limit == 0 as "no limit"
Index: /branches/pap/ippTools/src/camtoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/camtoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/camtoolConfig.c	(revision 28003)
@@ -184,4 +184,6 @@
     pxmagicAddArguments(processedexpArgs);
 
+    psMetadataAddBool(processedexpArgs, PS_LIST_TAIL, "-pstamp_order",  0,      "order the results for the postage stamp server", false);
+
     psMetadataAddU64(processedexpArgs, PS_LIST_TAIL, "-limit",    0,            "limit result set to N items", 0);
     psMetadataAddBool(processedexpArgs, PS_LIST_TAIL, "-all",     0,            "list everything without restriction", false);
Index: /branches/pap/ippTools/src/chiptool.c
===================================================================
--- /branches/pap/ippTools/src/chiptool.c	(revision 28002)
+++ /branches/pap/ippTools/src/chiptool.c	(revision 28003)
@@ -60,4 +60,5 @@
 static bool runstateMode(pxConfig *config);
 static bool setimfiletoupdateMode(pxConfig *config);
+static bool listrunMode(pxConfig *config);
 
 # define MODECASE(caseName, func) \
@@ -103,4 +104,5 @@
         MODECASE(CHIPTOOL_MODE_RUNSTATE,                runstateMode);
         MODECASE(CHIPTOOL_MODE_SETIMFILETOUPDATE,       setimfiletoupdateMode);
+        MODECASE(CHIPTOOL_MODE_LISTRUN,                 listrunMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -420,8 +422,8 @@
     PXOPT_COPY_S64(config->args,  where, "-chip_id", "chipRun.chip_id", "==");
     // we only allow a single label to match (do not use pxAddLabelSearchArgs here)
-    PXOPT_COPY_STR(config->args,  where, "-label",   "chipRun.label",   "==");
+    PXOPT_COPY_STR(config->args,  where, "-label",   "chipRun.label",   "LIKE");
     PXOPT_COPY_STR(config->args,  where, "-state",   "chipRun.state",   "==");
-    PXOPT_COPY_STR(config->args,  where, "-data_group", "chipRun.data_group",   "==");
-    PXOPT_COPY_STR(config->args,  where, "-dist_group", "chipRun.dist_group",   "==");
+    PXOPT_COPY_STR(config->args,  where, "-data_group", "chipRun.data_group",   "LIKE");
+    PXOPT_COPY_STR(config->args,  where, "-dist_group", "chipRun.dist_group",   "LIKE");
 
     if (!psListLength(where->list)) {
@@ -469,4 +471,6 @@
     }
     psFree(where);
+
+    psStringAppend(&query, "\nORDER BY priority DESC, chip_id");
 
     // treat limit == 0 as "no limit"
@@ -699,4 +703,8 @@
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_BOOL(faulted, config->args, "-faulted", false);
+    PXOPT_LOOKUP_BOOL(allfiles, config->args, "-allfiles", false);
+    if (allfiles) {
+        faulted = false;
+    }
 
     psMetadata *where = psMetadataAlloc();
@@ -740,5 +748,5 @@
         // list only faulted rows
         psStringAppend(&query, " %s", "AND chipProcessedImfile.fault != 0");
-    } else {
+    } else if (!allfiles) {
         // don't list faulted rows
         psStringAppend(&query, " %s", "AND chipProcessedImfile.fault = 0");
@@ -807,8 +815,15 @@
         return false;
     }
+    psString query_update = pxDataGet("chiptool_revertupdatedimfile.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        psFree(where);
+        return false;
+    }
 
     if (where && psListLength(where->list)) {
         psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
         psStringAppend(&query, " AND %s", whereClause);
+        psStringAppend(&query_update, " AND %s", whereClause);
         psFree(whereClause);
     }
@@ -822,4 +837,10 @@
     }
     psFree(query);
+    if (!p_psDBRunQuery(config->dbh, query_update)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query_update);
+        return false;
+    }
+    psFree(query_update);
 
     return true;
@@ -1414,6 +1435,6 @@
     }
 
-    char *set_magicked_imfile = "";
-    char *set_magicked_run = "";
+    psString set_magicked_imfile = psStringCopy("");
+    psString set_magicked_run = psStringCopy("");
     if (!strcmp(data_state, "full")) {
         // if (chipProcessedImfile.magicked < 0 and rawImfile.magicked = 0) leave magicked unchanged. This will
@@ -1421,10 +1442,14 @@
         // otherwise copy magicked from the rawImfile
         // Same thing for chipRun/rawExp
-        set_magicked_imfile = "\n , chipProcessedImfile.magicked = IF((chipProcessedImfile.magicked < 0 AND rawImfile.magicked = 0), chipProcessedImfile.magicked, rawImfile.magicked)";
-        set_magicked_run = "\n , chipRun.magicked = IF((chipRun.magicked < 0 AND rawExp.magicked = 0), chipRun.magicked, rawExp.magicked)";
+        psStringAppend(&set_magicked_imfile, "\n , chipProcessedImfile.magicked = IF((chipProcessedImfile.magicked < 0"
+                                      " AND rawImfile.magicked = 0), chipProcessedImfile.magicked, rawImfile.magicked)");
+        psStringAppend(&set_magicked_run, "\n , chipRun.magicked = IF((chipRun.magicked < 0 AND rawExp.magicked = 0), "
+                                      " chipRun.magicked, rawExp.magicked)");
+
     } else if (!strcmp(data_state, "cleaned") || !strcmp(data_state, "purged")) {
         // if magicked is non-zero set it to -1
-        set_magicked_imfile = "\n, chipProcessedImfile.magicked = IF(chipProcessedImfile.magicked = 0, 0, -1)";
-        set_magicked_run = "\n, chipRun.magicked = IF(chipRun.magicked = 0, 0, -1)";
+        // Once one imfile has been cleaned, the chipRun is no longer 'magicked'
+        psStringAppend(&set_magicked_imfile, "\n, chipProcessedImfile.magicked = IF(chipProcessedImfile.magicked = 0, 0, -1),"
+                                             " chipRun.magicked = IF(chipRun.magicked = 0, 0, -1)");
     }
 
@@ -1440,4 +1465,6 @@
     }
     psFree(query);
+    psFree(set_magicked_imfile);
+    psFree(set_magicked_run);
     if (psDBAffectedRows(config->dbh) < 1) {
         psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");
@@ -1757,2 +1784,90 @@
     return true;
 }
+
+static bool listrunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
+
+    psMetadata *where = psMetadataAlloc();
+    pxchipGetSearchArgs (config, where); // chipRun, chipProcessedImfile, rawExp
+    PXOPT_COPY_S64(config->args, where, "-chip_id", "chipRun.chip_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-reduction", "chipRun.reduction", "==");
+    PXOPT_COPY_STR(config->args, where, "-state", "chipRun.state", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "chipRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group", "chipRun.data_group", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-dist_group", "chipRun.dist_group", "LIKE");
+    PXOPT_COPY_S64(config->args, where, "-magicked", "chipRun.magicked", "==");
+
+    psString where2 = NULL;
+    pxmagicAddWhere(config, &where2, "chipRun");
+    // add cuts on ra and decl if supplied
+    if (!pxspaceAddWhere(config, &where2, "rawExp")) {
+        psError(psErrorCodeLast(), false, "pxSpaceAddWhere failed");
+        return false;
+    }
+
+    psString query = pxDataGet("chiptool_listrun.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s %s", whereClause, where2 ? where2 : "");
+        psFree(whereClause);
+    } else if (psMetadataLookupBool(NULL, config->args, "-all") || where2) {
+        psStringAppend(&query, " WHERE chipRun.chip_id IS NOT NULL %s", where2 ? where2 : "");
+    } else {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters (or -all) are required");
+        return false;
+    }
+    psFree(where);
+
+    if (pstamp_order) {
+        // put runs in order of exposure id with newest chip Runs first
+        // The postage stamp parser depends on this behavior
+        psStringAppend(&query, "\nORDER by exp_id, chip_id DESC");
+    }
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("chiptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // negative simple so the default is true
+    if (!ippdbPrintMetadatas(stdout, output, "chipRun", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+    return true;
+}
Index: /branches/pap/ippTools/src/chiptool.h
===================================================================
--- /branches/pap/ippTools/src/chiptool.h	(revision 28002)
+++ /branches/pap/ippTools/src/chiptool.h	(revision 28003)
@@ -50,5 +50,6 @@
     CHIPTOOL_MODE_EXPORTRUN,
     CHIPTOOL_MODE_IMPORTRUN,
-    CHIPTOOL_MODE_RUNSTATE
+    CHIPTOOL_MODE_RUNSTATE,
+    CHIPTOOL_MODE_LISTRUN
 } chiptoolMode;
 
Index: /branches/pap/ippTools/src/chiptoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/chiptoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/chiptoolConfig.c	(revision 28003)
@@ -196,4 +196,5 @@
     psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-all",  0,            "list everything without search terms", false);
     psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-faulted",  0,        "only return imfiles with a fault status set", false);
+    psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-allfiles",  0,       "only all matching imfiles regardless of fault status", false);
     psMetadataAddBool(processedimfileArgs, PS_LIST_TAIL, "-simple",  0,         "use the simple output format", false);
 
@@ -216,4 +217,22 @@
     psMetadataAddS16(updateprocessedimfileArgs, PS_LIST_TAIL, "-fault",  0,            "set fault code (required)", 0);
     psMetadataAddStr(updateprocessedimfileArgs, PS_LIST_TAIL, "-set_state", 0,         "set state", NULL);
+
+    // -processedExp
+    psMetadata *listrunArgs = psMetadataAlloc();
+    pxchipSetSearchArgs(listrunArgs);
+    psMetadataAddS64(listrunArgs, PS_LIST_TAIL, "-chip_id",  0,         "search by  chip ID", 0);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-reduction",          0, "search by reduction class", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-label",  PS_META_DUPLICATE_OK, "search by chipRun label (LIKE comparison)", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-state",              0, "search by chipRun state", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by chipRun data_group (LIKE comparison)", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-dist_group",  PS_META_DUPLICATE_OK, "search by chipRun dist_group (LIKE comparison)", NULL);
+    pxmagicAddArguments(listrunArgs);
+
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-pstamp_order",  0,    "order results for postage stamp server", false);
+    psMetadataAddU64(listrunArgs,  PS_LIST_TAIL, "-limit",  0,           "limit result set to N items", 0);
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-all",  0,            "list everything without search terms", false);
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-simple",  0,         "use the simple output format", false);
+    pxspaceAddArguments(listrunArgs);
+
     // -block
     psMetadata *blockArgs = psMetadataAlloc();
@@ -328,4 +347,5 @@
     PXOPT_ADD_MODE("-revertprocessedimfile","undo a processed imfile",              CHIPTOOL_MODE_REVERTPROCESSEDIMFILE,revertprocessedimfileArgs);
     PXOPT_ADD_MODE("-runstate",             "list the states of chip run",          CHIPTOOL_MODE_RUNSTATE,             runstateArgs);
+    PXOPT_ADD_MODE("-listrun",              "list chipRuns",                        CHIPTOOL_MODE_LISTRUN,              listrunArgs);
     PXOPT_ADD_MODE("-advanceexp",           "advance completed exposures",          CHIPTOOL_MODE_ADVANCEEXP,           advanceexpArgs);
     PXOPT_ADD_MODE("-block",                "set a label block",                    CHIPTOOL_MODE_BLOCK,                blockArgs);
Index: /branches/pap/ippTools/src/difftool.c
===================================================================
--- /branches/pap/ippTools/src/difftool.c	(revision 28002)
+++ /branches/pap/ippTools/src/difftool.c	(revision 28003)
@@ -57,4 +57,6 @@
 static bool toscrubbedskyfileMode(pxConfig *config);
 static bool tofullskyfileMode(pxConfig *config);
+static bool listrunMode(pxConfig *config);
+static bool setskyfiletoupdateMode(pxConfig *config);
 
 
@@ -101,4 +103,6 @@
         MODECASE(DIFFTOOL_MODE_TOSCRUBBEDSKYFILE,     toscrubbedskyfileMode);
         MODECASE(DIFFTOOL_MODE_TOFULLSKYFILE,         tofullskyfileMode);
+        MODECASE(DIFFTOOL_MODE_LISTRUN,               listrunMode);
+        MODECASE(DIFFTOOL_MODE_SETSKYFILETOUPDATE,    setskyfiletoupdateMode);
 
         default:
@@ -194,4 +198,5 @@
     PXOPT_COPY_S64(config->args, where, "-diff_id",  "diff_id",   "==");
     PXOPT_COPY_STR(config->args, where, "-label",     "label",     "==");
+    PXOPT_COPY_STR(config->args, where, "-data_group","data_group",     "==");
     PXOPT_COPY_STR(config->args, where, "-state",     "state",     "==");
     if (!psListLength(where->list)) {
@@ -702,4 +707,5 @@
     pxAddLabelSearchArgs (config, where, "-data_group", "diffRun.data_group", "LIKE");
 
+    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
     PXOPT_LOOKUP_BOOL(template, config->args, "-template", false);
     if (!template) {
@@ -745,4 +751,12 @@
     psFree(where);
 
+    if (pstamp_order) {
+        if (template) {
+            psStringAppend(&query, " ORDER BY rawTemplate.exp_id, diff_id DESC");
+        } else {
+            psStringAppend(&query, " ORDER BY rawInput.exp_id, diff_id DESC");
+        }
+    }
+            
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -810,48 +824,13 @@
     }
 
-    if (!psDBTransaction(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(where);
-        return false;
-    }
-
-    // Update state to 'new'
-    {
-        psString query = pxDataGet("difftool_revertdiffskyfile_update.sql");
-        if (!query) {
-            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-
-        if (psListLength(where->list)) {
-            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-            psStringAppend(&query, " AND %s", whereClause);
-            psFree(whereClause);
-        }
-
-        if (!p_psDBRunQuery(config->dbh, query)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-            psFree(query);
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-        psFree(query);
-
-        psLogMsg("difftool", PS_LOG_INFO, "Updated %" PRIu64 " rows", psDBAffectedRows(config->dbh));
-    }
-
-    // Delete product
     {
         psString query = pxDataGet("difftool_revertdiffskyfile_delete.sql");
         if (!query) {
             psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
+            return false;
+        }
+        psString query_updated = pxDataGet("difftool_revertdiffskyfile_updated.sql");
+        if (!query_updated) {
+            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
             return false;
         }
@@ -860,4 +839,5 @@
             psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
             psStringAppend(&query, " AND %s", whereClause);
+            psStringAppend(&query_updated, " AND %s", whereClause);
             psFree(whereClause);
         }
@@ -866,20 +846,21 @@
             psError(PS_ERR_UNKNOWN, false, "database error");
             psFree(query);
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
             return false;
         }
         psFree(query);
-
         psLogMsg("difftool", PS_LOG_INFO, "Deleted %" PRIu64 " rows", psDBAffectedRows(config->dbh));
+
+        if (!p_psDBRunQuery(config->dbh, query_updated)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            psFree(query_updated);
+            return false;
+        }
+        psFree(query_updated);
+
+        psLogMsg("difftool", PS_LOG_INFO, "Updated %" PRIu64 " rows", psDBAffectedRows(config->dbh));
     }
 
     psFree(where);
 
-    if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
 
     return true;
@@ -971,16 +952,16 @@
         return false;
     }
-    psS16 diff_mode = 0;
+    psS16 diff_mode = IPP_DIFF_MODE_UNDEFINED;
     if ((input_warp_id != PS_MAX_S64) && (template_warp_id != PS_MAX_S64)) {
-      diff_mode = 1;
+      diff_mode = IPP_DIFF_MODE_WARP_WARP;
     }
     else if ((input_warp_id != PS_MAX_S64) && (template_stack_id != PS_MAX_S64)) {
-      diff_mode = 2;
+      diff_mode = IPP_DIFF_MODE_WARP_STACK;
     }
     else if ((input_stack_id != PS_MAX_S64) && (template_warp_id != PS_MAX_S64)) {
-      diff_mode = 3;
+      diff_mode = IPP_DIFF_MODE_STACK_WARP;
     }
     else if ((input_stack_id != PS_MAX_S64) && (template_stack_id != PS_MAX_S64)) {
-      diff_mode = 4;
+      diff_mode = IPP_DIFF_MODE_STACK_STACK;
     }
 
@@ -1366,5 +1347,4 @@
         }
 
-
         psString filter = psMetadataLookupStr(&mdok, row, "filter");
         if (!mdok) {
@@ -1378,4 +1358,20 @@
             return false;
         }
+
+	psString warp_data_group = psMetadataLookupStr(&mdok, row, "data_group");
+	if (!mdok) {
+	  psError(PXTOOLS_ERR_PROG, false, "warp data_group not found");
+	  psFree(warp2Query);
+	  psFree(stackQuery);
+	  psFree(skycell_query);
+	  if (!psDBRollback(config->dbh)) {
+	    psError(PS_ERR_UNKNOWN, false, "database error");
+	  }
+	  return false;
+	}
+	if (warp_data_group) {
+	  data_group = warp_data_group;
+	}
+	
         if (!p_psDBRunQueryF(config->dbh, skycell_query, stackQuery, warp_id, filter, warp2Query)) {
             psError(PS_ERR_UNKNOWN, false, "database error");
@@ -1416,5 +1412,5 @@
                 true,                   // exposure
                 0,       // magicked
-                2,       // diff_mode for warp-stack difference
+                IPP_DIFF_MODE_WARP_STACK,
                 note
         );
@@ -1739,4 +1735,9 @@
         const char *template = psMetadataLookupStr(NULL, row, "template_warp_id");
         const char *tess_id = psMetadataLookupStr(NULL, row, "tess_id");
+	psString input_data_group = psMetadataLookupStr(NULL, row, "input_data_group");
+	if (input_data_group) {
+	  data_group = input_data_group;
+	}
+
         if (!input_id || !template || !tess_id) {
             psError(PXTOOLS_ERR_PROG, false, "Identifiers not found");
@@ -1749,5 +1750,5 @@
             return false;
         }
-
+	
         diffRunRow *run = diffRunRowAlloc(0,
                                           "reg",
@@ -1763,5 +1764,5 @@
                                           true,  // exposure
                                           false, // magicked
-                                          1,     // diff_mode for warp-warp diff
+                                          IPP_DIFF_MODE_WARP_WARP,
                                           note); // Run to insert
         if (!diffRunInsertObject(config->dbh, run)) {
@@ -2045,5 +2046,5 @@
                                       false,                 // exposure
                                       0,       // magicked
-                                      4,       // diff_mode
+                                      IPP_DIFF_MODE_STACK_STACK, // diff_mode
                                       note
                                       );
@@ -2338,4 +2339,5 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_S64(config->args, where, "-diff_id",   "diff_id",   "==");
+    PXOPT_COPY_STR(config->args, where, "-skycell_id", "skycell_id",   "==");
 
     if (!pxSetFaultCode(config->dbh, "diffSkyfile", where, fault)) {
@@ -2606,2 +2608,148 @@
   return true;
 }
+
+static bool listrunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where,  "-diff_id", "diffRun.diff_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-tess_id", "diffRun.tess_id", "==");
+    PXOPT_COPY_S64(config->args, where,  "-magicked", "diffRun.magicked", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "diffRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group", "diffRun.data_group", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-dist_group", "diffRun.dist_group", "LIKE");
+
+    PXOPT_LOOKUP_BOOL(template, config->args, "-template", false);
+    if (!template) {
+        PXOPT_COPY_S64(config->args, where, "-exp_id", "rawInput.exp_id", "==");
+        PXOPT_COPY_STR(config->args, where, "-exp_name", "rawInput.exp_name", "==");
+        PXOPT_COPY_STR(config->args, where, "-warp_id", "warpInput.warp_id", "==");
+        PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawInput.dateobs",  ">=");
+        PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawInput.dateobs",  "<=");
+        PXOPT_COPY_STR(config->args, where, "-filter",     "rawInput.filter", "LIKE");
+    } else {
+        PXOPT_COPY_S64(config->args, where, "-exp_id", "rawTemplate.exp_id", "==");
+        PXOPT_COPY_STR(config->args, where, "-exp_name", "rawTemplate.exp_name", "==");
+        PXOPT_COPY_STR(config->args, where, "-warp_id", "warpTemplate.warp_id", "==");
+        PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawTemplate.dateobs",  ">=");
+        PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawTemplate.dateobs",  "<=");
+        PXOPT_COPY_STR(config->args, where, "-filter",     "rawTemplate.filter", "LIKE");
+    }
+
+    PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
+
+
+    psString where2 = NULL;
+    pxmagicAddWhere(config, &where2, "diffRun");
+    pxspaceAddWhere(config, &where2, template ? "rawTemplate" : "rawInput");
+    psString query = pxDataGet("difftool_listrun.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s", whereClause);
+        psFree(whereClause);
+    } else if (where2) {
+        psStringAppend(&query, " WHERE diffRun.diff_id is not null %s", where2);
+    } else if (!all) {
+        psError(PXTOOLS_ERR_CONFIG, true, "search parameters or -all are required");
+        return false;
+    }
+    psFree(where);
+
+    if (pstamp_order) {
+        if (template) {
+            psStringAppend(&query, " ORDER BY rawTemplate.exp_id, diff_id DESC");
+        } else {
+            psStringAppend(&query, " ORDER BY rawInput.exp_id, diff_id DESC");
+        }
+    }
+            
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psErrorCode err = psErrorCodeLast();
+        switch (err) {
+            case PS_ERR_DB_CLIENT:
+                psError(PXTOOLS_ERR_SYS, false, "database error");
+            case PS_ERR_DB_SERVER:
+                psError(PXTOOLS_ERR_PROG, false, "database error");
+            default:
+                psError(PXTOOLS_ERR_PROG, false, "unknown error");
+        }
+
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("difftool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (psArrayLength(output)) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "diffRun", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    return true;
+}
+// a very specfic function to queue a cleaned warpSkyfile to be updated
+static bool setskyfiletoupdateMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_S64(diff_id, config->args, "-diff_id", true, false);
+    PXOPT_LOOKUP_STR(skycell_id, config->args, "-skycell_id", false, false);
+    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
+
+    psString query = pxDataGet("difftool_setskyfiletoupdate.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    psString setHook = psStringCopy("");
+    if (label) {
+        psStringAppend(&setHook, "\n , diffRun.label = '%s'", label);
+    }
+
+    if (skycell_id) {
+        psStringAppend(&query, " AND (diffSkyfile.skycell_id = '%s')", skycell_id);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, setHook, diff_id)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    psFree(setHook);
+    psFree(query);
+
+    return true;
+}
Index: /branches/pap/ippTools/src/difftool.h
===================================================================
--- /branches/pap/ippTools/src/difftool.h	(revision 28002)
+++ /branches/pap/ippTools/src/difftool.h	(revision 28003)
@@ -47,6 +47,7 @@
     DIFFTOOL_MODE_TOPURGEDSKYFILE,
     DIFFTOOL_MODE_TOSCRUBBEDSKYFILE,
-    DIFFTOOL_MODE_TOFULLSKYFILE
-    
+    DIFFTOOL_MODE_TOFULLSKYFILE,
+    DIFFTOOL_MODE_LISTRUN,
+    DIFFTOOL_MODE_SETSKYFILETOUPDATE,
 } difftoolMode;
 
Index: /branches/pap/ippTools/src/difftoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/difftoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/difftoolConfig.c	(revision 28003)
@@ -65,4 +65,5 @@
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-state", 0,            "set state", NULL);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-label", 0,            "define by label instead of diff ID", 0);
+    psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-data_group", 0,       "define by data_group instead of diff ID", 0);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_label", 0,        "define new value for label", 0);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_state", 0,        "define new state", NULL);
@@ -147,11 +148,37 @@
     psMetadataAddStr(diffskyfileArgs,  PS_LIST_TAIL, "-label",  PS_META_DUPLICATE_OK, "search by diffRun label (LIKE comparison)", NULL);
     psMetadataAddStr(diffskyfileArgs,  PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by diffRun data_group (LIKE comparison)", NULL);
+    psMetadataAddStr(diffskyfileArgs,  PS_LIST_TAIL, "-dist_group",  PS_META_DUPLICATE_OK, "search by diffRun dist_group (LIKE comparison)", NULL);
     psMetadataAddS16(diffskyfileArgs, PS_LIST_TAIL,  "-fault",  0,           "search by fault code", 0);
     pxmagicAddArguments(diffskyfileArgs);
     pxspaceAddArguments(diffskyfileArgs);
 
+    psMetadataAddBool(diffskyfileArgs, PS_LIST_TAIL, "-pstamp_order",  0,    "order results for postage stamp server", false);
     psMetadataAddBool(diffskyfileArgs, PS_LIST_TAIL, "-all",  0,             "search without arguments", false);
     psMetadataAddU64(diffskyfileArgs, PS_LIST_TAIL,  "-limit",  0,            "limit result set to N items", 0);
     psMetadataAddBool(diffskyfileArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
+
+    // -listrun
+    psMetadata *listrunArgs = psMetadataAlloc();
+    psMetadataAddS64(listrunArgs, PS_LIST_TAIL,  "-diff_id", 0,           "search by diff ID", 0);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-tess_id",  0,          "search by tessellation ID", NULL);
+    psMetadataAddStr(listrunArgs , PS_LIST_TAIL, "-warp_id",  0,         "search by warp_id", NULL);
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-template",  0,        "apply exposure args to template of bothways diff", false);
+    psMetadataAddS64(listrunArgs, PS_LIST_TAIL,  "-exp_id",  0,           "search by exposure ID", 0);
+    psMetadataAddStr(listrunArgs , PS_LIST_TAIL, "-exp_name",  0,        "search by exposure name", NULL);
+    psMetadataAddTime(listrunArgs, PS_LIST_TAIL, "-dateobs_begin", 0,    "search for exposures by time (>=)", NULL);
+    psMetadataAddTime(listrunArgs, PS_LIST_TAIL, "-dateobs_end", 0,      "search for exposures by time (<=)", NULL);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-filter", 0,           "search for filter", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-label",  PS_META_DUPLICATE_OK, "search by diffRun label (LIKE comparison)", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by diffRun data_group (LIKE comparison)", NULL);
+    psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-dist_group",  PS_META_DUPLICATE_OK, "search by diffRun dist_group (LIKE comparison)", NULL);
+    pxmagicAddArguments(listrunArgs);
+    pxspaceAddArguments(listrunArgs);
+
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-pstamp_order",  0,    "order results for postage stamp server", false);
+
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-all",  0,             "search without arguments", false);
+    psMetadataAddU64(listrunArgs, PS_LIST_TAIL,  "-limit",  0,            "limit result set to N items", 0);
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
+
 
     // -revertdiffskyfile
@@ -299,5 +326,6 @@
     psMetadata *updatediffskyfileArgs = psMetadataAlloc();
     psMetadataAddS64(updatediffskyfileArgs, PS_LIST_TAIL, "-diff_id", 0,      "define diff ID (required)", 0);
-    psMetadataAddS16(updatediffskyfileArgs, PS_LIST_TAIL, "-fault", 0,         "set fault code (required)", 0);
+    psMetadataAddS16(updatediffskyfileArgs, PS_LIST_TAIL, "-fault", 0,        "set fault code (required)", 0);
+    psMetadataAddStr(updatediffskyfileArgs, PS_LIST_TAIL, "-skycell_id", 0,   "search by skycell ID", NULL);
 
     // -tocleanedskyfile
@@ -321,4 +349,12 @@
     psMetadataAddStr(tofullskyfileArgs, PS_LIST_TAIL, "-skycell_id", 0, "skycell ID to update", NULL);
     psMetadataAddS64(tofullskyfileArgs, PS_LIST_TAIL, "-magicked",  0, "define magicked state", 0);
+
+    // -setskyfiletoupdate
+    psMetadata *setskyfiletoupdateArgs = psMetadataAlloc();
+    psMetadataAddS64(setskyfiletoupdateArgs, PS_LIST_TAIL, "-diff_id", 0,           "search by difftool ID (required)", 0);
+    psMetadataAddStr(setskyfiletoupdateArgs, PS_LIST_TAIL, "-skycell_id",  0,       "search by tessellation ID", NULL);
+    psMetadataAddStr(setskyfiletoupdateArgs, PS_LIST_TAIL, "-set_label",  0,        "new value for diffRun.label", NULL);
+
+
 
     // -exportrun
@@ -348,4 +384,5 @@
     PXOPT_ADD_MODE("-advance",          "", DIFFTOOL_MODE_ADVANCE,           advanceArgs);
     PXOPT_ADD_MODE("-diffskyfile",      "", DIFFTOOL_MODE_DIFFSKYFILE,       diffskyfileArgs);
+    PXOPT_ADD_MODE("-listrun",          "", DIFFTOOL_MODE_LISTRUN,           listrunArgs);
     PXOPT_ADD_MODE("-revertdiffskyfile","", DIFFTOOL_MODE_REVERTDIFFSKYFILE, revertdiffskyfileArgs);
     PXOPT_ADD_MODE("-definepoprun",     "", DIFFTOOL_MODE_DEFINEPOPRUN,      definepoprunArgs);
@@ -357,4 +394,6 @@
     PXOPT_ADD_MODE("-donecleanup",           "show runs that have been cleaned",     DIFFTOOL_MODE_DONECLEANUP,          donecleanupArgs);
     PXOPT_ADD_MODE("-updatediffskyfile",     "update fault code for a diffskyfile",  DIFFTOOL_MODE_UPDATEDIFFSKYFILE,          updatediffskyfileArgs);
+    PXOPT_ADD_MODE("-setskyfiletoupdate", "set cleaned skyfile to be updated", DIFFTOOL_MODE_SETSKYFILETOUPDATE, setskyfiletoupdateArgs);
+
     PXOPT_ADD_MODE("-exportrun",            "export run for import on other database", DIFFTOOL_MODE_EXPORTRUN, exportrunArgs);
     PXOPT_ADD_MODE("-importrun",            "import run from metadata file",           DIFFTOOL_MODE_IMPORTRUN, importrunArgs);
Index: /branches/pap/ippTools/src/magicdstool.c
===================================================================
--- /branches/pap/ippTools/src/magicdstool.c	(revision 28002)
+++ /branches/pap/ippTools/src/magicdstool.c	(revision 28003)
@@ -572,5 +572,4 @@
     // we can transition by query as well
 
-
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
@@ -1234,6 +1233,14 @@
         psFree(whereClause);
     } else {
-        psError(PS_ERR_UNKNOWN, true, "search arugments are required");
-        return false;
+        psError(PS_ERR_UNKNOWN, true, "search arguments are required");
+        return false;
+    }
+
+    if (!strcmp(state, "goto_cleaned")) {
+        // Don't set state back to goto_cleaned if it is already cleaned
+        psStringAppend(&query, " AND (magicDSRun.state != 'cleaned')");
+
+        // don't clean up magicDSRun's where stage is camera
+        psStringAppend(&query, " AND (magicDSRun.stage != 'camera')");
     }
 
Index: /branches/pap/ippTools/src/magictool.c
===================================================================
--- /branches/pap/ippTools/src/magictool.c	(revision 28002)
+++ /branches/pap/ippTools/src/magictool.c	(revision 28003)
@@ -48,4 +48,5 @@
 static bool maskMode(pxConfig *config);
 static bool censorrunMode(pxConfig *config);
+static bool exposureMode(pxConfig *config);
 
 static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state);
@@ -87,4 +88,5 @@
         MODECASE(MAGICTOOL_MODE_MASK,                maskMode);
         MODECASE(MAGICTOOL_MODE_CENSORRUN,           censorrunMode);
+        MODECASE(MAGICTOOL_MODE_EXPOSURE,            exposureMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -1514,2 +1516,66 @@
     return true;
 }
+
+
+static bool exposureMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-magic_id", "magicRun.magic_id", "==");
+    PXOPT_COPY_BOOL(config->args, where, "-inverse", "magicRun.inverse", "==");
+
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+
+    psString query = pxDataGet("magictool_exposure.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    psString whereClause = psStringCopy(""); // WHERE restrictions
+    if (psListLength(where->list)) {
+        psString clause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&whereClause, "\nWHERE %s", clause);
+        psFree(clause);
+    }
+    psFree(where);
+
+    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psErrorCode err = psErrorCodeLast();
+        switch (err) {
+            case PS_ERR_DB_CLIENT:
+                psError(PXTOOLS_ERR_SYS, false, "database error");
+                break;
+            case PS_ERR_DB_SERVER:
+                psError(PXTOOLS_ERR_PROG, false, "database error");
+                break;
+            default:
+                psError(PXTOOLS_ERR_PROG, false, "unknown error");
+                break;
+        }
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("magictool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (!ippdbPrintMetadatas(stdout, output, "magicMask", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+    psFree(output);
+
+    return true;
+}
Index: /branches/pap/ippTools/src/magictool.h
===================================================================
--- /branches/pap/ippTools/src/magictool.h	(revision 28002)
+++ /branches/pap/ippTools/src/magictool.h	(revision 28003)
@@ -42,4 +42,5 @@
     MAGICTOOL_MODE_MASK,
     MAGICTOOL_MODE_CENSORRUN,
+    MAGICTOOL_MODE_EXPOSURE,
 } MAGICtoolMode;
 
Index: /branches/pap/ippTools/src/magictoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/magictoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/magictoolConfig.c	(revision 28003)
@@ -168,4 +168,10 @@
     psMetadataAddS64(censorrunArgs, PS_LIST_TAIL, "-exp_id", 0, "define exposure ID", 0);
     psMetadataAddStr(censorrunArgs, PS_LIST_TAIL, "-label",       0, "define label", NULL);
+
+    // -exposure
+    psMetadata *exposureArgs = psMetadataAlloc();
+    psMetadataAddS64(exposureArgs, PS_LIST_TAIL, "-magic_id", 0, "define magictool ID", 0);
+    psMetadataAddBool(exposureArgs, PS_LIST_TAIL, "-inverse", 0, "select the inverse subtraction?", false);
+    psMetadataAddBool(exposureArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
 
     psFree(now);
@@ -191,4 +197,5 @@
     PXOPT_ADD_MODE("-mask",                "", MAGICTOOL_MODE_MASK,                maskArgs);
     PXOPT_ADD_MODE("-censorrun",           "", MAGICTOOL_MODE_CENSORRUN,           censorrunArgs);
+    PXOPT_ADD_MODE("-exposure",            "", MAGICTOOL_MODE_EXPOSURE,            exposureArgs);
 
     if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
Index: /branches/pap/ippTools/src/pstamptool.c
===================================================================
--- /branches/pap/ippTools/src/pstamptool.c	(revision 28002)
+++ /branches/pap/ippTools/src/pstamptool.c	(revision 28003)
@@ -40,4 +40,5 @@
 static bool updatereqMode(pxConfig *config);
 static bool revertreqMode(pxConfig *config);
+static bool pendingcleanupMode(pxConfig *config);
 static bool addjobMode(pxConfig *config);
 static bool listjobMode(pxConfig *config);
@@ -51,4 +52,5 @@
 static bool pendingdependentMode(pxConfig *config);
 static bool updatedependentMode(pxConfig *config);
+static bool revertdependentMode(pxConfig *config);
 
 # define MODECASE(caseName, func) \
@@ -80,4 +82,5 @@
         MODECASE(PSTAMPTOOL_MODE_UPDATEREQ, updatereqMode);
         MODECASE(PSTAMPTOOL_MODE_REVERTREQ, revertreqMode);
+        MODECASE(PSTAMPTOOL_MODE_PENDINGCLEANUP, pendingcleanupMode);
         MODECASE(PSTAMPTOOL_MODE_ADDJOB, addjobMode);
         MODECASE(PSTAMPTOOL_MODE_LISTJOB, listjobMode);
@@ -91,4 +94,5 @@
         MODECASE(PSTAMPTOOL_MODE_PENDINGDEPENDENT, pendingdependentMode);
         MODECASE(PSTAMPTOOL_MODE_UPDATEDEPENDENT, updatedependentMode);
+        MODECASE(PSTAMPTOOL_MODE_REVERTDEPENDENT, revertdependentMode);
         default:
             psAbort("invalid option (this should not happen)");
@@ -263,4 +267,5 @@
         NULL,   // outProduct
         uri,
+        NULL,   // outdir
         0       // fault
         )) {
@@ -299,4 +304,6 @@
     }
     psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
 
     // treat limit == 0 as "no limit"
@@ -337,5 +344,5 @@
 }
 
-static bool listreqMode(pxConfig *config)
+static bool pendingcleanupMode(pxConfig *config)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
@@ -343,21 +350,23 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    PXOPT_COPY_S64(config->args, where, "-not_req_id", "req_id", "!=");
-    PXOPT_COPY_STR(config->args, where, "-name", "name", "==");
-
-    PXOPT_LOOKUP_U64(limit,   config->args, "-limit",  false, false);
+    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
-    if (!psListLength(where->list)) {
-        psError(PS_ERR_UNKNOWN, true, "-req_id or -name must be supplied");
-        return false;
-    }
-
-    psString query = psStringCopy("SELECT * from pstampRequest");
-
-    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-    psStringAppend(&query, " WHERE %s", whereClause);
-    psFree(whereClause);
-    psFree(where);
+    psString query = pxDataGet("pstamptool_pendingcleanup.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, "pstampRequest");
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
 
     // treat limit == 0 as "no limit"
@@ -381,10 +390,7 @@
     }
     if (!psArrayLength(output)) {
-        psTrace("pstamptool", PS_LOG_INFO, "request not found");
-        // This causes main to exit with PS_EXIT_DATA_ERROR which the script is looking for
-        psError(PXTOOLS_ERR_CONFIG, true, "request not found");
-        psFree(output);
-        // we return false so that the caller can determine that a request does not exist
-        return false;
+        psTrace("pstamptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
     }
 
@@ -401,21 +407,26 @@
 }
 
-static bool completedreqMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psMetadata *where = psMetadataAlloc();
-    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
-
-    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+static bool listreqMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-not_req_id", "req_id", "!=");
+    PXOPT_COPY_STR(config->args, where, "-name", "name", "==");
+
+    PXOPT_LOOKUP_U64(limit,   config->args, "-limit",  false, false);
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
-    psString query = pxDataGet("pstamptool_completedreq.sql");
-
-    if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
+    if (!psListLength(where->list)) {
+        psError(PS_ERR_UNKNOWN, true, "-req_id or -name must be supplied");
+        return false;
+    }
+
+    psString query = psStringCopy("SELECT * from pstampRequest");
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " WHERE %s", whereClause);
+    psFree(whereClause);
     psFree(where);
 
@@ -432,4 +443,5 @@
         return false;
     }
+    psFree(query);
 
     psArray *output = p_psDBFetchResult(config->dbh);
@@ -438,9 +450,11 @@
         return false;
     }
-
     if (!psArrayLength(output)) {
-        psTrace("pstamptool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
+        psTrace("pstamptool", PS_LOG_INFO, "request not found");
+        // This causes main to exit with PS_EXIT_DATA_ERROR which the script is looking for
+        psError(PXTOOLS_ERR_CONFIG, true, "request not found");
+        psFree(output);
+        // we return false so that the caller can determine that a request does not exist
+        return false;
     }
 
@@ -457,23 +471,103 @@
 }
 
+static bool completedreqMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+
+    psString query = pxDataGet("pstamptool_completedreq.sql");
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    if (!psArrayLength(output)) {
+        psTrace("pstamptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    // negative simple so the default is true
+    if (!ippdbPrintMetadatas(stdout, output, "pstampRequest", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+    return true;
+}
+
 static bool updatereqMode(pxConfig *config)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    PXOPT_LOOKUP_S64(req_id,     config->args, "-req_id",     true, false);
-    PXOPT_LOOKUP_STR(state,      config->args, "-state",      false, false);
-    PXOPT_LOOKUP_STR(outProduct, config->args, "-outProduct", false, false);
-    PXOPT_LOOKUP_STR(fault,      config->args, "-fault",      false, false);
-    PXOPT_LOOKUP_STR(uri,        config->args, "-uri",        false, false);
-    PXOPT_LOOKUP_STR(name,       config->args, "-name",       false, false);
-    PXOPT_LOOKUP_STR(reqType,    config->args, "-reqType",    false, false);
-
-    psString query = NULL;
-    psStringAppend(&query, "UPDATE pstampRequest SET");
-
+    // PXOPT_LOOKUP_S64(req_id,     config->args, "-req_id",   true, false);
+    PXOPT_LOOKUP_STR(state,      config->args, "-set_state",      false, false);
+    PXOPT_LOOKUP_STR(label,      config->args, "-set_label",      false, false);
+    PXOPT_LOOKUP_STR(outProduct, config->args, "-set_outProduct", false, false);
+    PXOPT_LOOKUP_S16(fault,      config->args, "-set_fault",          false, false);
+    PXOPT_LOOKUP_STR(uri,        config->args, "-set_uri",        false, false);
+    PXOPT_LOOKUP_STR(outdir,     config->args, "-set_outdir",        false, false);
+    PXOPT_LOOKUP_STR(name,       config->args, "-set_name",       false, false);
+    PXOPT_LOOKUP_STR(reqType,    config->args, "-set_reqType",    false, false);
+    PXOPT_LOOKUP_BOOL(clearfault,config->args, "-clearfault",    false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-req_id",     "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-req_id_max", "req_id", "<=");
+    PXOPT_COPY_S32(config->args, where, "-fault",      "fault", "==");
+    PXOPT_COPY_STR(config->args, where, "-state",      "state", "==");
+    pxAddLabelSearchArgs(config, where, "-label",      "pstampRequest.label", "LIKE");
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+    psString query = psStringCopy("UPDATE pstampRequest SET");
+
+    psString stateCheck = NULL;
     char c = ' ';
     if (state) {
         psStringAppend(&query, "%c state = '%s'", c, state);
         c = ',';
+        if (!strcmp(state, "goto_cleaned")) {
+            psStringAppend(&stateCheck, " AND state != 'cleaned'");
+        }
+    }
+    if (label) {
+        psStringAppend(&query, "%c label = '%s'", c, label);
+        c = ',';
     }
     if (outProduct) {
@@ -481,6 +575,17 @@
         c = ',';
     }
-    if (fault) {
-        psStringAppend(&query, "%c fault = %s", c, fault);
+    if (outdir) {
+        psStringAppend(&query, "%c outdir = '%s'", c, outdir);
+        c = ',';
+    }
+    if (clearfault) {
+        if (fault) {
+            psError(PXTOOLS_ERR_CONFIG, true, "only one of -fault and -clearfault is allowed");
+            return false;
+        }
+        psStringAppend(&query, "%c fault = 0", c);
+        c = ',';
+    } else if (fault) {
+        psStringAppend(&query, "%c fault = %d", c, fault);
         c = ',';
     }
@@ -497,10 +602,17 @@
         c = ',';
     }
-    if (!state && !outProduct && !fault && !uri && !name && !reqType) {
-        psError(PS_ERR_UNKNOWN, true, "at least one of state, outProduct, fault, uri, name, and reqType must be specified");
-        return false;
-    }
-
-    psStringAppend(&query, " WHERE req_id = %" PRId64, req_id);
+    if (c != ',') {
+        psError(PS_ERR_UNKNOWN, true, "at least one set option is required");
+        return false;
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, "\nWHERE %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (stateCheck) {
+        psStringAppend(&query, "%s", stateCheck);
+    }
 
     if (!p_psDBRunQuery(config->dbh, query)) {
@@ -510,11 +622,6 @@
     }
 
-    psU64 affected = psDBAffectedRows(config->dbh);
-    // note zero is not an error
-    if (affected > 1) {
-        psError(PS_ERR_UNKNOWN, false, "should have affected one row but %"
-                                        PRIu64 " rows were modified", affected);
-        return false;
-    }
+    // psU64 affected = psDBAffectedRows(config->dbh);
+    // psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampRequests", affected);
 
     return true;
@@ -528,5 +635,5 @@
 
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    PXOPT_COPY_S64(config->args, where, "-fault", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-fault", "fault", "==");
     PXOPT_COPY_STR(config->args, where, "-state", "pstampRequest.state", "==");
     pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
@@ -703,5 +810,5 @@
     PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
-    pxAddLabelSearchArgs(config, where, "-label", "label", "LIKE");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -722,4 +829,6 @@
     psFree(where);
 
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
+
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -763,32 +872,51 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    PXOPT_LOOKUP_S64(job_id,    config->args, "-job_id", true, false);
-    PXOPT_LOOKUP_STR(state,     config->args, "-state",  true, false);
-    PXOPT_LOOKUP_STR(fault,     config->args, "-fault",  false, false);
-
-    psString faultStr = NULL;
-    if (!fault) {
-        faultStr = psStringCopy("");
-    } else {
-        psStringAppend(&faultStr, ", fault = '%s'", fault);
-    }
-
-    char *query ="UPDATE pstampJob"
-        " SET state = '%s' %s"
-        " WHERE job_id = %" PRId64;
-
-    if (!p_psDBRunQueryF(config->dbh, query, state, faultStr, job_id)) {
+    PXOPT_LOOKUP_S64(job_id,    config->args, "-job_id", false, false);
+    PXOPT_LOOKUP_S64(dep_id,    config->args, "-dep_id", false, false);
+
+    if (!job_id && !dep_id) {
+        psError(PS_ERR_UNKNOWN, true, "at least -job_id or -dep_id is required");
+        return false;
+    }
+
+    PXOPT_LOOKUP_STR(state,     config->args, "-set_state",  false, false);
+    PXOPT_LOOKUP_S32(fault,     config->args, "-set_fault",  false, false);
+    
+    if (!state && !fault) {
+        psError(PS_ERR_UNKNOWN, true, "at least one of -set_state and -set_fault is required");
+        return false;
+    }
+
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+
+    psString query = pxDataGet("pstamptool_updatejob.sql");
+
+    char c = ' ';
+    if (state) {
+        psStringAppend(&query, "\n %c pstampJob.state = '%s'", c, state);
+        c = ',';
+    }
+    if (fault) {
+        psStringAppend(&query, "\n %c pstampJob.fault = %d", c, fault);
+        c = ',';
+    }
+    
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " WHERE %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
         return false;
     }
-    psFree(faultStr);
+    psFree(query);
 
     psU64 affected = psDBAffectedRows(config->dbh);
-    if (affected != 1) {
-        psError(PS_ERR_UNKNOWN, false, "should have affected one row but %"
-                                        PRIu64 " rows were modified", affected);
-        return false;
-    }
+    psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampJobs", affected);
 
     return true;
@@ -952,7 +1080,9 @@
     PXOPT_LOOKUP_STR(stage,       config->args, "-stage",   true, false);
     PXOPT_LOOKUP_S64(stage_id,    config->args, "-stage_id", true, false);
+    PXOPT_LOOKUP_STR(component,   config->args, "-component",  true, false);
     PXOPT_LOOKUP_STR(imagedb,     config->args, "-imagedb",  true, false);
-    PXOPT_LOOKUP_STR(rlabel,      config->args, "-rlabel",  false, false);
-    PXOPT_LOOKUP_BOOL(no_magic,   config->args, "-no_magic", false);
+    PXOPT_LOOKUP_STR(rlabel,      config->args, "-rlabel",  true, false);
+    PXOPT_LOOKUP_STR(outdir,      config->args, "-outdir",  true, false);
+    PXOPT_LOOKUP_BOOL(need_magic, config->args, "-need_magic", false);
     PXOPT_LOOKUP_BOOL(no_create,  config->args, "-no_create", false);
 
@@ -961,4 +1091,5 @@
     PXOPT_COPY_STR(config->args, where, "-imagedb", "imagedb", "==");
     PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-component", "component", "==");
 
     // start a transaction eraly so it will contain any row level locks
@@ -968,15 +1099,15 @@
     }
 
-    psString query = pxDataGet("pstamptool_pendingdependent.sql");
+    psString query = pxDataGet("pstamptool_getdependent.sql");
     if (!query) {
         psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         return false;
     }
-    psString whereClause = psDBGenerateWhereSQL(where, "WHERE");
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
     if (!no_create) {
         // This will lock the row until the transaction is committed
-        psStringAppend(&query, " %s FOR UPDATE", whereClause);
+        psStringAppend(&query, " AND %s FOR UPDATE", whereClause);
     } else {
-        psStringAppend(&query, " %s", whereClause);
+        psStringAppend(&query, " AND %s", whereClause);
     }
     psFree(whereClause);
@@ -1027,7 +1158,10 @@
         stage,
         stage_id,
+        component,
         imagedb,
         rlabel,
-        no_magic
+        need_magic,
+        outdir,
+        0               // fault
         )) {
         if (!psDBRollback(config->dbh)) {
@@ -1038,4 +1172,14 @@
     }
 
+    // if we try and get this after commit zero is returned
+    psS64 dep_id = psDBLastInsertID(config->dbh);
+    if (!dep_id) {
+        psError(PS_ERR_UNKNOWN, false, "psDBLastInsertID returned NULL");
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        return false;
+    }
+
     if (!psDBCommit(config->dbh)) {
         // rollback
@@ -1047,5 +1191,4 @@
     }
 
-    psS64 dep_id = psDBLastInsertID(config->dbh);
     printf("%" PRId64 "\n", dep_id);
 
@@ -1058,4 +1201,10 @@
 
     psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_STR(config->args, where, "-stage", "stage", "==");
+    PXOPT_COPY_STR(config->args, where, "-imagedb", "imagedb", "==");
+    PXOPT_COPY_S64(config->args, where, "-stage_id", "stage_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-rlabel", "rlabel", "==");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "==");
 
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -1069,9 +1218,11 @@
 
     if (psListLength(where->list)) {
-        psString whereClause = psDBGenerateWhereConditionSQL(where, "pstampDependent");
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
         psStringAppend(&query, " AND %s", whereClause);
         psFree(whereClause);
     }
     psFree(where);
+
+    psStringAppend(&query, " ORDER BY priority DESC, req_id");
 
     // treat limit == 0 as "no limit"
@@ -1116,11 +1267,24 @@
 
     PXOPT_LOOKUP_S64(dep_id,    config->args, "-dep_id", true, false);
-    PXOPT_LOOKUP_STR(state,     config->args, "-set_state",  true, false);
-
-    char *query ="UPDATE pstampDependent"
-        " SET state = '%s'"
-        " WHERE dep_id = %" PRId64;
-
-    if (!p_psDBRunQueryF(config->dbh, query, state, dep_id)) {
+    PXOPT_LOOKUP_STR(state,     config->args, "-set_state",  false, false);
+    PXOPT_LOOKUP_S16(fault,     config->args, "-set_fault",  false, false);
+
+    if (!fault && !state) {
+        psError(PS_ERR_UNKNOWN, true, "at least one of -set_state or fault is required");
+        return false;
+    }
+    psString query = psStringCopy("UPDATE pstampDependent SET");
+    bool needComma = false;
+    if (state) {
+        psStringAppend(&query, " state = '%s'", state);
+        needComma = true;
+    }
+    if (fault) {
+        psStringAppend(&query, "%s fault = %d", needComma ? ", " : "", fault);
+        needComma = true;
+    }
+    psStringAppend(&query, " WHERE dep_id = %" PRId64, dep_id);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
@@ -1137,2 +1301,35 @@
     return true;
 }
+static bool revertdependentMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-fault", "pstampDependent.fault", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "==");
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+    psString query = pxDataGet("pstamptool_revertdependent.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, " AND %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+
+    return true;
+}
Index: /branches/pap/ippTools/src/pstamptool.h
===================================================================
--- /branches/pap/ippTools/src/pstamptool.h	(revision 28002)
+++ /branches/pap/ippTools/src/pstamptool.h	(revision 28003)
@@ -34,4 +34,5 @@
     PSTAMPTOOL_MODE_UPDATEREQ,
     PSTAMPTOOL_MODE_REVERTREQ,
+    PSTAMPTOOL_MODE_PENDINGCLEANUP,
     PSTAMPTOOL_MODE_ADDJOB,
     PSTAMPTOOL_MODE_LISTJOB,
@@ -46,4 +47,5 @@
     PSTAMPTOOL_MODE_PENDINGDEPENDENT,
     PSTAMPTOOL_MODE_UPDATEDEPENDENT,
+    PSTAMPTOOL_MODE_REVERTDEPENDENT,
 } pstamptoolMode;
 
Index: /branches/pap/ippTools/src/pstamptoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/pstamptoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/pstamptoolConfig.c	(revision 28003)
@@ -98,11 +98,18 @@
     // -updatereq
     psMetadata *updatereqArgs = psMetadataAlloc();
-    psMetadataAddS64(updatereqArgs, PS_LIST_TAIL, "-req_id", 0,            "req_id for which to change state", 0);
-    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-state", 0,            "new state", NULL);
-    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-outProduct", 0,            "define request outProduct", NULL);
-    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-fault", 0,            "define request fault code", NULL);
-    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-uri", 0,            "define the uri", NULL);
-    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-name", 0,            "define the name", NULL);
-    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-reqType", 0,            "define the reqType", NULL);
+    psMetadataAddS64(updatereqArgs, PS_LIST_TAIL, "-req_id", 0,       "req_id for which to update", 0);
+    psMetadataAddS64(updatereqArgs, PS_LIST_TAIL, "-req_id_max", 0,   "maximum req_id for which to update", 0);
+    psMetadataAddS16(updatereqArgs, PS_LIST_TAIL, "-fault", 0,        "search by fault code", 0);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-state", 0,        "search by state", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by pstampJob label (LIKE comparision)", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_state", 0,        "new state", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_label", 0,        "new label", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_outProduct", 0,   "new outProduct", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_outdir", 0,   "new outdir", NULL);
+    psMetadataAddS16(updatereqArgs, PS_LIST_TAIL, "-set_fault", 0,        "new fault code", 0);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_uri", 0,          "new uri", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_name", 0,         "new name", NULL);
+    psMetadataAddStr(updatereqArgs, PS_LIST_TAIL, "-set_reqType", 0,      "new reqType", NULL);
+    psMetadataAddBool(updatereqArgs, PS_LIST_TAIL, "-clearfault", 0,      "set fault to zero", false);
 
     // -revertreq
@@ -112,4 +119,12 @@
     psMetadataAddStr(revertreqArgs, PS_LIST_TAIL, "-state", 0,      "state to revert", NULL);
     psMetadataAddStr(revertreqArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by pstampRequest label (LIKE comparision)", NULL);
+
+    // -pendingcleanup
+    psMetadata *pendingcleanupArgs = psMetadataAlloc();
+    psMetadataAddS64(pendingcleanupArgs, PS_LIST_TAIL, "-req_id", 0,   "define req_id", 0);
+    psMetadataAddS64(pendingcleanupArgs, PS_LIST_TAIL, "-ds_id", 0,    "define ds_id", 0);
+    psMetadataAddStr(pendingcleanupArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by pstampRequest label (LIKE comparision)", NULL);
+    psMetadataAddU64(pendingcleanupArgs, PS_LIST_TAIL, "-limit",  0,   "limit result set to N items", 0);
+    psMetadataAddBool(pendingcleanupArgs, PS_LIST_TAIL, "-simple", 0,  "use the simple output format", false);
 
     // -addjob
@@ -144,6 +159,7 @@
     psMetadata *updatejobArgs = psMetadataAlloc();
     psMetadataAddS64(updatejobArgs, PS_LIST_TAIL, "-job_id", 0,            "req_id for which to change state", 0);
-    psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-state", 0,            "new state", NULL);
-    psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-fault", 0,            "new result", NULL);
+    psMetadataAddS64(updatejobArgs, PS_LIST_TAIL, "-dep_id", 0,            "dep_id for which to change state", 0);
+    psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-set_state", 0,            "new state", NULL);
+    psMetadataAddS16(updatejobArgs, PS_LIST_TAIL, "-set_fault", 0,            "new result", 0);
 
     // -revertjob
@@ -159,24 +175,36 @@
     // -getdependent
     psMetadata *getdependentArgs = psMetadataAlloc();
-    psMetadataAddS64(getdependentArgs, PS_LIST_TAIL, "-stage_id", 0, "define id for dependent run (required)", 0);
-    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-stage", 0,    "define stage for dependent run (required)", NULL);
-    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-imagedb", 0,  "define imagedb for depenent run (required)", NULL);
-    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-rlabel", 0,   "define label for dependent run", NULL);
-    psMetadataAddBool(getdependentArgs,PS_LIST_TAIL, "-no_magic", 0, "define no_magic", false);
-    psMetadataAddBool(getdependentArgs,PS_LIST_TAIL, "-no_create", 0, "if no run exists do not create one", false);
+    // arguabely all of these could be -set_ arguments, but since this mode is both a query and
+    // a create if doesn't exist I like it this way
+    psMetadataAddS64(getdependentArgs, PS_LIST_TAIL, "-stage_id", 0, "define stage id for dependent (required)", 0);
+    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-stage", 0,    "define stage for dependent (required)", NULL);
+    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-component", 0, "define component for depenent (required)", NULL);
+    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-imagedb", 0,  "define imagedb for depenent (required)", NULL);
+    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-rlabel", 0,   "define label for dependent ", NULL);
+    psMetadataAddBool(getdependentArgs,PS_LIST_TAIL, "-need_magic", 0, "define need_magic", false);
+    psMetadataAddStr(getdependentArgs, PS_LIST_TAIL, "-outdir", 0,    "define output directory for dependent (required)", NULL);
+    psMetadataAddBool(getdependentArgs,PS_LIST_TAIL, "-no_create", 0, "if no matching dependent do not create one", false);
 
     // -updatedependent
     psMetadata *updatedependentArgs = psMetadataAlloc();
-    psMetadataAddS64(updatedependentArgs, PS_LIST_TAIL, "-dep_id", 0, "define id for dependent run (required)", 0);
-    psMetadataAddStr(updatedependentArgs, PS_LIST_TAIL, "-set_state", 0, "new value for state (required)", NULL);
+    psMetadataAddS64(updatedependentArgs, PS_LIST_TAIL, "-dep_id", 0, "define id for dependent (required)", 0);
+    psMetadataAddStr(updatedependentArgs, PS_LIST_TAIL, "-set_state", 0, "new value for state", NULL);
+    psMetadataAddS16(updatedependentArgs, PS_LIST_TAIL, "-set_fault",  0,   "new value for fault", 0);
+
+    // -revertdependent
+    psMetadata *revertdependentArgs = psMetadataAlloc();
+    psMetadataAddS64(revertdependentArgs, PS_LIST_TAIL, "-dep_id", 0, "define id for dependent", 0);
+    psMetadataAddStr(revertdependentArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK,   "define label for dependent ", NULL);
+    psMetadataAddS16(revertdependentArgs, PS_LIST_TAIL, "-fault",  0,   "define fault", 0);
 
     // -pendingdependent
     psMetadata *pendingdependentArgs = psMetadataAlloc();
-    psMetadataAddS64(pendingdependentArgs, PS_LIST_TAIL, "-stage_id", 0, "define id for dependent run", 0);
-    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-stage", 0,    "define stage for dependent run", NULL);
-    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-imagedb", 0,  "define imagedb for depenent run", NULL);
-    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-rlabel", 0,   "define label for dependent run", NULL);
-    psMetadataAddBool(pendingdependentArgs,PS_LIST_TAIL, "-no_magic", 0, "define no_magic", false);
-    psMetadataAddBool(pendingdependentArgs,PS_LIST_TAIL, "-no_create", 0, "if no run exists do not create one", false);
+    psMetadataAddS64(pendingdependentArgs, PS_LIST_TAIL, "-stage_id", 0, "define id for dependent", 0);
+    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-stage", 0,    "define stage for dependent", NULL);
+    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-component", 0,    "define component for dependent", NULL);
+    psMetadataAddS64(pendingdependentArgs, PS_LIST_TAIL, "-dep_id", 0, "define dep_id for dependent", 0);
+    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK,   "define label for pstampRequest", NULL);
+    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-rlabel", 0,   "define label for dependent", NULL);
+    psMetadataAddStr(pendingdependentArgs, PS_LIST_TAIL, "-imagedb", 0,  "define imagedb for depenent", NULL);
     psMetadataAddU64(pendingdependentArgs, PS_LIST_TAIL, "-limit",  0,    "limit result set to N items", 0);
     psMetadataAddBool(pendingdependentArgs, PS_LIST_TAIL, "-simple", 0,   "use the simple output format", false);
@@ -216,4 +244,5 @@
     PXOPT_ADD_MODE("-completedreq",    "", PSTAMPTOOL_MODE_COMPLETEDREQ, completedreqArgs);
     PXOPT_ADD_MODE("-revertreq",       "", PSTAMPTOOL_MODE_REVERTREQ,    revertreqArgs);
+    PXOPT_ADD_MODE("-pendingcleanup",  "", PSTAMPTOOL_MODE_PENDINGCLEANUP, pendingcleanupArgs);
 
     PXOPT_ADD_MODE("-addjob",          "", PSTAMPTOOL_MODE_ADDJOB,       addjobArgs);
@@ -230,4 +259,5 @@
     PXOPT_ADD_MODE("-updatedependent", "", PSTAMPTOOL_MODE_UPDATEDEPENDENT, updatedependentArgs);
     PXOPT_ADD_MODE("-pendingdependent","", PSTAMPTOOL_MODE_PENDINGDEPENDENT, pendingdependentArgs);
+    PXOPT_ADD_MODE("-revertdependent","", PSTAMPTOOL_MODE_REVERTDEPENDENT, revertdependentArgs);
 
     PXOPT_ADD_MODE("-addproject",      "", PSTAMPTOOL_MODE_ADDPROJECT, addprojectArgs);
Index: /branches/pap/ippTools/src/pxchip.c
===================================================================
--- /branches/pap/ippTools/src/pxchip.c	(revision 28002)
+++ /branches/pap/ippTools/src/pxchip.c	(revision 28003)
@@ -69,9 +69,9 @@
     psMetadataAddF64(md,  PS_LIST_TAIL, "-posang_min",         0, "search by min rotator position angle", NAN);
     psMetadataAddF64(md,  PS_LIST_TAIL, "-posang_max",         0, "search by max rotator position angle", NAN);
-    psMetadataAddF32(md,  PS_LIST_TAIL, "-sun_angle_min",         0, "search by min solar angle", NAN);
-    psMetadataAddF32(md,  PS_LIST_TAIL, "-sun_angle_max",         0, "search by max solar angle", NAN);
+    psMetadataAddF32(md,  PS_LIST_TAIL, "-sun_angle_min",      0, "search by min solar angle", NAN);
+    psMetadataAddF32(md,  PS_LIST_TAIL, "-sun_angle_max",      0, "search by max solar angle", NAN);
     psMetadataAddStr(md,  PS_LIST_TAIL, "-object",             0, "search by exposure object", NULL);
     psMetadataAddStr(md,  PS_LIST_TAIL, "-comment",            0, "search by comment field (LIKE comparison)", NULL);
-    psMetadataAddStr(md,  PS_LIST_TAIL, "-obs_mode", 0, "search by observation mode", NULL);
+    psMetadataAddStr(md,  PS_LIST_TAIL, "-obs_mode",           0, "search by observation mode", NULL);
     return true;
 }
@@ -121,5 +121,5 @@
     PXOPT_COPY_F64(config->args, where, "-posang_min", "rawExp.posang", ">=");
     PXOPT_COPY_F64(config->args, where, "-posang_max", "rawExp.posang", "<");
-    PXOPT_COPY_STR(config->args, where, "-object", "rawExp.object", "==");
+    PXOPT_COPY_STR(config->args, where, "-object", "rawExp.object", "LIKE");
     PXOPT_COPY_F32(config->args, where, "-sun_angle_min", "rawExp.sun_angle", ">=");
     PXOPT_COPY_F32(config->args, where, "-sun_angle_max", "rawExp.sun_angle", "<");
Index: /branches/pap/ippTools/src/pxmagic.c
===================================================================
--- /branches/pap/ippTools/src/pxmagic.c	(revision 28002)
+++ /branches/pap/ippTools/src/pxmagic.c	(revision 28003)
@@ -85,6 +85,7 @@
     }
     if (destreaked) {
-        psStringAppend(out, " AND %s.magicked > 0", table);
+        psStringAppend(out, " AND %s.magicked != 0", table);
     }
+    // Note -magicked is  handled by the caller. XXX: Why?
     return true;
 }
Index: /branches/pap/ippTools/src/pxtools.h
===================================================================
--- /branches/pap/ippTools/src/pxtools.h	(revision 28002)
+++ /branches/pap/ippTools/src/pxtools.h	(revision 28003)
@@ -286,4 +286,6 @@
   PXOPT_COPY_PRIMITIVE(from, to, psU64, U64, oldname, newname, comment)
 
+#define PXOPT_COPY_BOOL(from, to, oldname, newname, comment) \
+  PXOPT_COPY_V(from, to, psBool, Bool, oldname, newname, comment)
 
 /*** these PXOPT_ADD_WHERE macros are used to construct the default sql elements ***/
Index: /branches/pap/ippTools/src/regtool.c
===================================================================
--- /branches/pap/ippTools/src/regtool.c	(revision 28002)
+++ /branches/pap/ippTools/src/regtool.c	(revision 28003)
@@ -350,4 +350,8 @@
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     PXOPT_LOOKUP_BOOL(faulted, config->args, "-faulted", false);
+    PXOPT_LOOKUP_BOOL(allfiles, config->args, "-allfiles", false);
+    if (allfiles) {
+        faulted = false;
+    }
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
@@ -389,5 +393,5 @@
         // list only faulted rows
         psStringAppend(&query, " %s", "AND rawImfile.fault != 0");
-    } else {
+    } else if (!allfiles) {
         // don't list faulted rows
         psStringAppend(&query, " %s", "AND rawImfile.fault = 0");
Index: /branches/pap/ippTools/src/regtoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/regtoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/regtoolConfig.c	(revision 28003)
@@ -144,4 +144,5 @@
     ADD_OPT(U64,  processedimfileArgs, "-limit",     "limit result set to N items",           0);
     ADD_OPT(Bool, processedimfileArgs, "-faulted",   "only return imfiles with a fault status set", false);
+    ADD_OPT(Bool, processedimfileArgs, "-allfiles",   "return imfiles regardless of fault status", false);
     ADD_OPT(Bool, processedimfileArgs, "-all",   "list without search arguments", false);
     ADD_OPT(Bool, processedimfileArgs, "-simple",    "use the simple output format",          false);
Index: /branches/pap/ippTools/src/stacktool.c
===================================================================
--- /branches/pap/ippTools/src/stacktool.c	(revision 28002)
+++ /branches/pap/ippTools/src/stacktool.c	(revision 28003)
@@ -155,4 +155,5 @@
     PXOPT_COPY_F32(config->args,  where, "-select_good_frac_min",      "warpSkyfile.good_frac", ">=");
     PXOPT_COPY_STR(config->args,  where, "-select_skycell_id",         "warpSkyfile.skycell_id", "==");
+    PXOPT_COPY_STR(config->args,  where, "-select_data_group",         "warpRun.data_group", "==");
     pxAddLabelSearchArgs (config, where, "-select_label",              "warpRun.label", "LIKE"); // define using warp label
 
Index: /branches/pap/ippTools/src/stacktoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/stacktoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/stacktoolConfig.c	(revision 28003)
@@ -59,4 +59,5 @@
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_exp_type", 0, "search for exp_type", "object");
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_label", PS_META_DUPLICATE_OK, "search by warpRun label (LIKE comparison, multiple OK)", NULL);
+    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_data_group", 0 , "search by warpRun data_group", NULL);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_comment", 0, "search for comment (LIKE)", NULL);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_inst", 0, "search for camera", NULL);
Index: /branches/pap/ippTools/src/staticskytool.c
===================================================================
--- /branches/pap/ippTools/src/staticskytool.c	(revision 28002)
+++ /branches/pap/ippTools/src/staticskytool.c	(revision 28003)
@@ -107,9 +107,9 @@
 
     // optional
-    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
-    PXOPT_LOOKUP_STR(data_group, config->args, "-set_data_group", false, false);
-    PXOPT_LOOKUP_STR(dist_group, config->args, "-set_dist_group", false, false);
-    PXOPT_LOOKUP_STR(reduction, config->args, "-set_reduction", false, false);
-    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
+    PXOPT_LOOKUP_STR(label,       config->args, "-set_label", false, false);
+    PXOPT_LOOKUP_STR(data_group,  config->args, "-set_data_group", false, false);
+    PXOPT_LOOKUP_STR(dist_group,  config->args, "-set_dist_group", false, false);
+    PXOPT_LOOKUP_STR(reduction,   config->args, "-set_reduction", false, false);
+    PXOPT_LOOKUP_STR(note,        config->args, "-set_note", false, false);
     PXOPT_LOOKUP_TIME(registered, config->args, "-set_registered", false, false);
 
@@ -118,10 +118,10 @@
 
     PXOPT_COPY_F32(config->args, where, "-select_good_frac_min", "stackSumSkyfile.good_frac", ">=");
-    PXOPT_COPY_STR(config->args, where, "-select_skycell_id", "stackRun.skycell_id", "==");
-    pxAddLabelSearchArgs(config, where, "-select_label", "stackRun.label", "LIKE");
-    pxAddLabelSearchArgs(config, where, "-select_filter", "stackRun.filter", "LIKE");
+    PXOPT_COPY_STR(config->args, where, "-select_skycell_id",    "stackRun.skycell_id",       "==");
+    pxAddLabelSearchArgs(config, where, "-select_label",         "stackRun.label",            "LIKE");
+    pxAddLabelSearchArgs(config, where, "-select_filter",        "stackRun.filter",           "LIKE");
 
     // these are used to build the HAVING restriction
-    PXOPT_COPY_S32(config->args, having, "-min_num", "num", ">=");
+    PXOPT_COPY_S32(config->args, having, "-min_num",    "num",        ">=");
     PXOPT_COPY_S32(config->args, having, "-min_filter", "num_filter", ">=");
 
Index: /branches/pap/ippTools/src/staticskytoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/staticskytoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/staticskytoolConfig.c	(revision 28003)
@@ -46,17 +46,18 @@
 
     // -definebyquery
+    // XXX need a 'ra_min,max', 'dec_min,max' : to do this, we need a table of skycell boundaries
     psMetadata *definebyqueryArgs = psMetadataAlloc();
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_workdir", 0, "define workdir (required)", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_label", 0, "define label", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_data_group", 0, "define data group", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_dist_group", 0, "define dist group", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_note", 0, "define note", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-set_reduction", 0, "define reduction", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-select_skycell_id", 0, "search for skycell_id", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-select_tess_id", 0, "search for tess_id", NULL);
+    psMetadataAddF32(definebyqueryArgs,  PS_LIST_TAIL, "-select_good_frac_min", 0, "define min good_frac", 0.0);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-select_label", PS_META_DUPLICATE_OK, "search by stackRun label (LIKE comparison, multiple OK)", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-select_filter", PS_META_DUPLICATE_OK, "search by filter (LIKE comparison, multiple OK)", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-set_workdir", 0, "define workdir (required)", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-set_label", 0, "define label", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-set_data_group", 0, "define data group", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-set_dist_group", 0, "define dist group", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-set_note", 0, "define note", NULL);
+    psMetadataAddStr(definebyqueryArgs,  PS_LIST_TAIL, "-set_reduction", 0, "define reduction", NULL);
     psMetadataAddTime(definebyqueryArgs, PS_LIST_TAIL, "-set_registered", 0, "time detrend run was registered", now);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_skycell_id", 0, "search for skycell_id", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_tess_id", 0, "search for tess_id", NULL);
-    psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-select_good_frac_min", 0, "define min good_frac", 0.0);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_label", PS_META_DUPLICATE_OK, "search by stackRun label (LIKE comparison, multiple OK)", NULL);
-    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-select_filter", PS_META_DUPLICATE_OK, "search by filter (LIKE comparison, multiple OK)", NULL);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-pretend",  0, "do not actually modify the database", false);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
@@ -64,5 +65,5 @@
     // -updaterun
     psMetadata *updaterunArgs = psMetadataAlloc();
-    psMetadataAddS64(updaterunArgs, PS_LIST_TAIL, "-ss_id", 0, "search by stack ID", 0);
+    psMetadataAddS64(updaterunArgs, PS_LIST_TAIL, "-sky_id", 0, "search by stack ID", 0);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-state", 0, "search by state", NULL);
     psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-label", 0, "search by label", 0);
@@ -75,5 +76,5 @@
     // -inputs
     psMetadata *inputsArgs = psMetadataAlloc();
-    psMetadataAddS64(inputsArgs, PS_LIST_TAIL, "-ss_id", 0, "search by staticsky ID", 0);
+    psMetadataAddS64(inputsArgs, PS_LIST_TAIL, "-sky_id", 0, "search by staticsky ID", 0);
     psMetadataAddU64(inputsArgs, PS_LIST_TAIL, "-limit", 0, "limit result set to N items", 0);
     psMetadataAddBool(inputsArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
@@ -81,5 +82,5 @@
     // -todo
     psMetadata *todoArgs = psMetadataAlloc();
-    psMetadataAddS64(todoArgs, PS_LIST_TAIL, "-ss_id", 0, "search by staticsky ID", 0);
+    psMetadataAddS64(todoArgs, PS_LIST_TAIL, "-sky_id", 0, "search by staticsky ID", 0);
     psMetadataAddStr(todoArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by label", NULL);
     psMetadataAddU64(todoArgs, PS_LIST_TAIL, "-limit", 0, "limit result set to N items", 0);
@@ -88,5 +89,5 @@
     // -addresult
     psMetadata *addresultArgs = psMetadataAlloc();
-    psMetadataAddS64(addresultArgs, PS_LIST_TAIL, "-ss_id", 0, "define stack ID (required)", 0);
+    psMetadataAddS64(addresultArgs, PS_LIST_TAIL, "-sky_id", 0, "define stack ID (required)", 0);
     psMetadataAddStr(addresultArgs, PS_LIST_TAIL, "-path_base", 0, "define base output location", 0);
     psMetadataAddF32(addresultArgs, PS_LIST_TAIL, "-dtime_phot", 0, "define photometry time", NAN);
@@ -100,5 +101,5 @@
     // -result
     psMetadata *resultArgs= psMetadataAlloc();
-    psMetadataAddS64(resultArgs, PS_LIST_TAIL, "-ss_id", 0, "search by staticsky ID", 0);
+    psMetadataAddS64(resultArgs, PS_LIST_TAIL, "-sky_id", 0, "search by staticsky ID", 0);
     psMetadataAddStr(resultArgs, PS_LIST_TAIL, "-tess_id", 0, "search by tess ID", 0);
     psMetadataAddStr(resultArgs, PS_LIST_TAIL, "-skycell_id", 0, "search by skycell ID", 0);
@@ -111,5 +112,5 @@
     // -revert
     psMetadata *revertArgs= psMetadataAlloc();
-    psMetadataAddS64(revertArgs, PS_LIST_TAIL, "-ss_id", 0, "search by staticsky ID", 0);
+    psMetadataAddS64(revertArgs, PS_LIST_TAIL, "-sky_id", 0, "search by staticsky ID", 0);
     psMetadataAddStr(revertArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by label", 0);
     psMetadataAddS16(revertArgs, PS_LIST_TAIL, "-fault", 0, "search by fault code", 0);
@@ -118,10 +119,10 @@
     // -updateresult
     psMetadata *updateresultArgs = psMetadataAlloc();
-    psMetadataAddS64(updateresultArgs, PS_LIST_TAIL, "-ss_id", 0, "define staticksky ID (required)", 0);
+    psMetadataAddS64(updateresultArgs, PS_LIST_TAIL, "-sky_id", 0, "define staticksky ID (required)", 0);
     psMetadataAddS16(updateresultArgs, PS_LIST_TAIL, "-fault", 0, "set fault code (required)", 0);
 
     // -exportrun
     psMetadata *exportrunArgs = psMetadataAlloc();
-    psMetadataAddS64(exportrunArgs, PS_LIST_TAIL, "-ss_id", 0, "export this staticsky ID (required)", 0);
+    psMetadataAddS64(exportrunArgs, PS_LIST_TAIL, "-sky_id", 0, "export this staticsky ID (required)", 0);
     psMetadataAddStr(exportrunArgs, PS_LIST_TAIL, "-outfile", 0, "export to this file (required)", NULL);
     psMetadataAddU64(exportrunArgs, PS_LIST_TAIL, "-limit", 0, "limit result set to N items", 0);
Index: /branches/pap/ippTools/src/warptool.c
===================================================================
--- /branches/pap/ippTools/src/warptool.c	(revision 28002)
+++ /branches/pap/ippTools/src/warptool.c	(revision 28003)
@@ -59,4 +59,6 @@
 static bool importrunMode(pxConfig *config);
 static bool runstateMode(pxConfig *config);
+static bool listrunMode(pxConfig *config);
+static bool setskyfiletoupdateMode(pxConfig *config);
 
 static bool parseAndInsertSkyCellMap(pxConfig *config, const char *mapfile);
@@ -110,4 +112,6 @@
         MODECASE(WARPTOOL_MODE_IMPORTRUN,          importrunMode);
         MODECASE(WARPTOOL_MODE_RUNSTATE,           runstateMode);
+        MODECASE(WARPTOOL_MODE_LISTRUN,            listrunMode);
+        MODECASE(WARPTOOL_MODE_SETSKYFILETOUPDATE, setskyfiletoupdateMode);
 
         default:
@@ -244,4 +248,6 @@
     PXOPT_COPY_F64(config->args,   where, "-posang_max",         "rawExp.posang",         "<");
     PXOPT_COPY_STR(config->args,   where, "-object",             "rawExp.object",         "==");
+    PXOPT_COPY_STR(config->args,   where, "-comment",            "rawExp.comment",        "LIKE");
+    PXOPT_COPY_STR(config->args,   where, "-obs_mode",           "rawExp.obs_mode",       "LIKE");
     PXOPT_COPY_F32(config->args,   where, "-sun_angle_min",      "rawExp.sun_angle",      ">=");
     PXOPT_COPY_F32(config->args,   where, "-sun_angle_max",      "rawExp.sun_angle",      "<");
@@ -269,4 +275,5 @@
     PXOPT_LOOKUP_TIME(registered, config->args, "-registered", false, false);
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
 
     // check mode
@@ -306,4 +313,15 @@
     if (!psArrayLength(output)) {
         psTrace("warptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (pretend) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "rawExp", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
         psFree(output);
         return true;
@@ -916,12 +934,16 @@
 
     // treat limit == 0 as "no limit"
+    psString limitString = psStringCopy("\n");
     if (limit) {
-        psString limitString = psDBGenerateLimitSQL(limit);
+        // We apply the limit to both sides of the UNION
+        // to avoid slow queries and to the query itself
+        // to satisfy the user's requested limit
+        psStringAppend(&limitString, "%s", psDBGenerateLimitSQL(limit));
         psStringAppend(&query, " %s", limitString);
-        psFree(limitString);
-    }
-
+    }
+
+#define TWO_WHERES
 #ifdef TWO_WHERES
-    if (!p_psDBRunQueryF(config->dbh, query, whereStr, whereStr)) {
+    if (!p_psDBRunQueryF(config->dbh, query, whereStr, limitString, whereStr,  limitString)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
@@ -935,4 +957,5 @@
     }
 #endif
+    psFree(limitString);
     psFree(whereStr);
     psFree(query);
@@ -994,5 +1017,5 @@
     PXOPT_LOOKUP_STR(hostname, config->args, "-hostname", false, false);
     PXOPT_LOOKUP_F32(good_frac, config->args, "-good_frac", false, false);
-    PXOPT_LOOKUP_S64(magicked, config->args, "-magicked", false, false);
+    PXOPT_LOOKUP_S64(magicked, config->args, "-set_magicked", false, false);
 
     // default values
@@ -1242,5 +1265,5 @@
     if (psListLength(where->list)) {
         psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-        psStringAppend(&query, " AND %s", whereClause);
+        psStringAppend(&query, " WHERE %s", whereClause);
         psFree(whereClause);
     } else if (!all && !where2) {
@@ -1248,9 +1271,13 @@
         return false;
     }
+
+    if (where2) {
+        if (psListLength(where->list)) {
+            psStringAppend(&query, " %s", where2);
+        } else {
+            psStringAppend(&query, " WHERE 1 %s", where2);
+        }
+    }
     psFree(where);
-
-    if (where2) {
-        psStringAppend(&query, " %s", where2);
-    }
 
     // treat limit == 0 as "no limit"
@@ -1322,49 +1349,46 @@
     }
 
-    if (!psDBTransaction(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(where);
-        return false;
-    }
-
-    // Delete product
-    int numDeleted;                     // Number deleted
-    {
-        psString query = pxDataGet("warptool_revertwarped_delete.sql");
-        if (!query) {
-            psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
-
-        if (psListLength(where->list)) {
-            psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
-            psStringAppend(&query, " AND %s", whereClause);
-            psFree(whereClause);
-        }
-
-        if (!p_psDBRunQuery(config->dbh, query)) {
-            psError(PS_ERR_UNKNOWN, false, "database error");
-            psFree(query);
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            return false;
-        }
+    psString query = pxDataGet("warptool_revertwarped_delete.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+    psString query_updated = pxDataGet("warptool_revertwarped_updated.sql");
+    if (!query_updated) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psStringAppend(&query_updated, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
-
-        numDeleted = psDBAffectedRows(config->dbh);
-    }
+        return false;
+    }
+    psFree(query);
+
+    int numDeleted = psDBAffectedRows(config->dbh);
 
     psLogMsg("warptool", PS_LOG_INFO, "Deleted %d warpSkyfiles", numDeleted);
 
-    psFree(where);
-
-    if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
+    // fix any faulted warpSkyfiles in data_state 'update'
+
+    if (!p_psDBRunQuery(config->dbh, query_updated)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query_updated);
+        return false;
+    }
+    psFree(query_updated);
+
+    int numUpdated = psDBAffectedRows(config->dbh);
+
+    psLogMsg("warptool", PS_LOG_INFO, "Updated %d warpSkyfiles", numUpdated);
 
     return true;
@@ -1665,13 +1689,17 @@
     }
 
-    char *set_magicked_skyfile = "";
-    char *set_magicked_run = "";
+    psString set_magicked_skyfile = psStringCopy("");
+    psString set_magicked_run = psStringCopy("");
     if (!strcmp(data_state, "full")) {
-        set_magicked_skyfile = "\n , warpSkyfile.magicked = IF((warpSkyfile.magicked < 0 AND chipRun.magicked = 0), warpSkyfile.magicked, chipRun.magicked)";
-        set_magicked_run = "\n,  warpRun.magicked = IF((warpRun.magicked < 0 AND chipRun.magicked = 0), warpRun.magicked, chipRun.magicked)";
-
+        // magicked is only an argument for for -tofullskyfile
+        PXOPT_LOOKUP_S64(magicked, config->args, "-set_magicked", false, false);
+        if (magicked) {
+            psStringAppend(&set_magicked_skyfile, "\n , warpSkyfile.magicked = %" PRId64, magicked);
+            psStringAppend(&set_magicked_run, "\n,  warpRun.magicked = %" PRId64, magicked);
+        }
     } else if (!strcmp(data_state, "cleaned") || !strcmp(data_state, "purged")) {
-        set_magicked_skyfile = "\n, warpSkyfile.magicked = IF(warpSkyfile.magicked = 0, 0, -1)";
-        set_magicked_run = "\n, warpRun.magicked = IF(warpRun.magicked = 0, 0, -1)";
+        // if magicked is currently nonzero set it to -1
+        // Set warpRun.magicked when the first skyfile is cleaned
+        psStringAppend(&set_magicked_skyfile, "\n, warpSkyfile.magicked = IF(warpSkyfile.magicked = 0, 0, -1), warpRun.magicked = IF(warpRun.magicked = 0, 0, -1)");
     }
 
@@ -1686,4 +1714,5 @@
     }
     psFree(query);
+    psFree(set_magicked_skyfile);
 
     query = pxDataGet("warptool_change_run_state.sql");
@@ -1696,4 +1725,5 @@
         return false;
     }
+    psFree(set_magicked_run);
 
     if (!psDBCommit(config->dbh)) {
@@ -2026,2 +2056,154 @@
     return true;
 }
+
+static bool listrunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-warp_id",    "warpRun.warp_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-tess_id",    "warpRun.tess_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-state",      "warpRun.state", "==");
+    PXOPT_COPY_S64(config->args, where, "-exp_id",     "rawExp.exp_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-exp_name",   "rawExp.exp_name", "==");
+    PXOPT_COPY_S64(config->args, where, "-fake_id",    "fakeRun.fake_id", "==");
+    PXOPT_COPY_TIME(config->args, where, "-dateobs_begin", "rawExp.dateobs",  ">=");
+    PXOPT_COPY_TIME(config->args, where, "-dateobs_end",   "rawExp.dateobs",  "<=");
+    PXOPT_COPY_STR(config->args, where, "-filter",    "rawExp.filter", "LIKE");
+    PXOPT_COPY_S64(config->args, where, "-magicked", "warpRun.magicked", "==");
+    pxAddLabelSearchArgs (config, where, "-label",   "warpRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group",   "warpRun.data_group", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-dist_group",   "warpRun.dist_group", "LIKE");
+
+    PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
+
+    // find all rawImfiles matching the default query
+    psString query = pxDataGet("warptool_listrun.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    // generate where strings for arguments that require extra processing
+    // beyond PXOPT_COPY*
+    psString where2 = NULL;
+    if (!pxmagicAddWhere(config, &where2, "warpRun")) {
+        psError(psErrorCodeLast(), false, "pxMagicAddWhere failed");
+        return false;
+    }
+    if (!pxspaceAddWhere(config, &where2, "rawExp")) {
+        psError(psErrorCodeLast(), false, "pxSpaceAddWhere failed");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s", whereClause);
+        psFree(whereClause);
+    } else if (!all && !where2) {
+        psError(PXTOOLS_ERR_CONFIG, true, "search parameters or -all are required");
+        return false;
+    }
+
+    if (where2) {
+        if (psListLength(where->list)) {
+            psStringAppend(&query, " %s", where2);
+        } else {
+            psStringAppend(&query, " WHERE 1 %s", where2);
+        }
+    }
+    psFree(where);
+
+    if (pstamp_order) {
+        // put runs in order of exposure id with newest chip Runs first
+        // The postage stamp parser depends on this behavior
+        psStringAppend(&query, "\nORDER by exp_id, warp_id DESC");
+    }
+
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psErrorCode err = psErrorCodeLast();
+        switch (err) {
+            case PS_ERR_DB_CLIENT:
+                psError(PXTOOLS_ERR_SYS, false, "database error");
+            case PS_ERR_DB_SERVER:
+                psError(PXTOOLS_ERR_PROG, false, "database error");
+            default:
+                psError(PXTOOLS_ERR_PROG, false, "unknown error");
+        }
+
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("warptool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (psArrayLength(output)) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "warpRun", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    return true;
+}
+
+// a very specfic function to queue a cleaned warpSkyfile to be updated
+static bool setskyfiletoupdateMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+
+    PXOPT_LOOKUP_S64(warp_id, config->args, "-warp_id", true, false);
+    PXOPT_LOOKUP_STR(skycell_id, config->args, "-skycell_id", false, false);
+    PXOPT_LOOKUP_STR(label, config->args, "-set_label", false, false);
+
+    psString query = pxDataGet("warptool_setskyfiletoupdate.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    psString setHook = psStringCopy("");
+    if (label) {
+        psStringAppend(&setHook, "\n , warpRun.label = '%s'", label);
+    }
+
+    if (skycell_id) {
+        psStringAppend(&query, " AND (warpSkyfile.skycell_id = '%s')", skycell_id);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, setHook, warp_id)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    psFree(setHook);
+    psFree(query);
+
+    return true;
+}
Index: /branches/pap/ippTools/src/warptool.h
===================================================================
--- /branches/pap/ippTools/src/warptool.h	(revision 28002)
+++ /branches/pap/ippTools/src/warptool.h	(revision 28003)
@@ -55,4 +55,6 @@
     WARPTOOL_MODE_IMPORTRUN,
     WARPTOOL_MODE_RUNSTATE,
+    WARPTOOL_MODE_LISTRUN,
+    WARPTOOL_MODE_SETSKYFILETOUPDATE,
 } warptoolMode;
 
Index: /branches/pap/ippTools/src/warptoolConfig.c
===================================================================
--- /branches/pap/ippTools/src/warptoolConfig.c	(revision 28002)
+++ /branches/pap/ippTools/src/warptoolConfig.c	(revision 28003)
@@ -89,6 +89,8 @@
     psMetadataAddF64(definebyqueryArgs, PS_LIST_TAIL, "-posang_max",         0, "search by max rotator position angle", NAN);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-object",             0, "search by exposure object", NULL);
-    psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-sun_angle_min",         0, "search by min solar angle", NAN);
-    psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-sun_angle_max",         0, "search by max solar angle", NAN);
+    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-comment",            0, "search by comment field (LIKE comparison)", NULL);
+    psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-obs_mode",           0, "search by observation mode", NULL);
+    psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-sun_angle_min",      0, "search by min solar angle", NAN);
+    psMetadataAddF32(definebyqueryArgs, PS_LIST_TAIL, "-sun_angle_max",      0, "search by max solar angle", NAN);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-reduction",          0, "search by fakeRun reduction class", NULL);
     psMetadataAddStr(definebyqueryArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search on fakeRun label", NULL);
@@ -106,4 +108,5 @@
     psMetadataAddTime(definebyqueryArgs, PS_LIST_TAIL, "-registered",  0,            "time detrend run was registered", now);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-simple",  0,            "use the simple output format", false);
+    psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-pretend",  0,            "do not actually modify the database", false);
 
     // -definerun
@@ -217,5 +220,5 @@
     psMetadataAddStr(addwarpedArgs, PS_LIST_TAIL, "-hostname", 0,            "define hostname", 0);
     psMetadataAddF32(addwarpedArgs, PS_LIST_TAIL, "-good_frac",  0,            "define %% of good pixels", NAN);
-    psMetadataAddS64(addwarpedArgs, PS_LIST_TAIL, "-magicked",  0, "define if this skycell has been magicked", 0);
+    psMetadataAddS64(addwarpedArgs, PS_LIST_TAIL, "-set_magicked",  0, "define if this skycell has been magicked", 0);
     psMetadataAddS16(addwarpedArgs, PS_LIST_TAIL, "-fault",  0,            "set fault code", 0);
     psMetadataAddS16(addwarpedArgs, PS_LIST_TAIL, "-quality",  0,            "set quality", 0);
@@ -236,4 +239,5 @@
     psMetadataAddStr(warpedArgs, PS_LIST_TAIL,  "-label",  PS_META_DUPLICATE_OK, "search by warpRun label", NULL);
     psMetadataAddStr(warpedArgs, PS_LIST_TAIL,  "-data_group",  PS_META_DUPLICATE_OK, "search by warpRun data_group", NULL);
+    psMetadataAddStr(warpedArgs, PS_LIST_TAIL,  "-dist_group",  PS_META_DUPLICATE_OK, "search by warpRun dist_group", NULL);
     // add magic related arguments
     pxmagicAddArguments(warpedArgs);
@@ -244,4 +248,30 @@
     psMetadataAddU64(warpedArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
     psMetadataAddBool(warpedArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
+
+    // -listrun
+    psMetadata *listrunArgs = psMetadataAlloc();
+    psMetadataAddS64(listrunArgs, PS_LIST_TAIL, "-warp_id", 0,           "search by warptool ID", 0);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL, "-tess_id",  0,          "search by tessellation ID", NULL);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL, "-state",  0,            "search by state", NULL);
+    psMetadataAddS64(listrunArgs, PS_LIST_TAIL, "-exp_id", 0,            "search by exposure tag", 0);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL, "-exp_name", 0,          "search by exposure tag", 0);
+    psMetadataAddS64(listrunArgs, PS_LIST_TAIL, "-fake_id", 0,           "search by phase 3 version of exposure tag", 0);
+    psMetadataAddTime(listrunArgs, PS_LIST_TAIL, "-dateobs_begin", 0,    "search for exposures by time (>=)", NULL);
+    psMetadataAddTime(listrunArgs, PS_LIST_TAIL, "-dateobs_end", 0,      "search for exposures by time (<=)", NULL);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-filter", 0,           "search for exposures by filter", NULL);
+    psMetadataAddS16(listrunArgs, PS_LIST_TAIL,  "-fault",  0,           "search by fault code", 0);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-label",  PS_META_DUPLICATE_OK, "search by warpRun label", NULL);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-data_group",  PS_META_DUPLICATE_OK, "search by warpRun data_group", NULL);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-dist_group",  PS_META_DUPLICATE_OK, "search by warpRun dist_group", NULL);
+    // add magic related arguments
+    pxmagicAddArguments(listrunArgs);
+    // add arguments for spatial search
+    pxspaceAddArguments(listrunArgs);
+
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-pstamp_order",  0,    "order results for postage stamp server", false);
+
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-all",  0,             "search without arguments", false);
+    psMetadataAddU64(listrunArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
+    psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
 
     // -revertwarped
@@ -315,4 +345,5 @@
     psMetadataAddS64(tofullskyfileArgs, PS_LIST_TAIL, "-warp_id", 0,    "warptool ID to update", 0);
     psMetadataAddStr(tofullskyfileArgs, PS_LIST_TAIL, "-skycell_id", 0, "skycell ID to update", NULL);
+    psMetadataAddS64(tofullskyfileArgs, PS_LIST_TAIL, "-set_magicked",  0, "new value for magicked", 0);
 
     // -updateskyfile
@@ -345,4 +376,10 @@
     psMetadataAddU64(runstateArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
     psMetadataAddBool(runstateArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
+
+    // -setskyfiletoupdate
+    psMetadata *setskyfiletoupdateArgs = psMetadataAlloc();
+    psMetadataAddS64(setskyfiletoupdateArgs, PS_LIST_TAIL, "-warp_id", 0,           "search by warptool ID (required)", 0);
+    psMetadataAddStr(setskyfiletoupdateArgs, PS_LIST_TAIL, "-skycell_id",  0,       "search by tessellation ID", NULL);
+    psMetadataAddStr(setskyfiletoupdateArgs, PS_LIST_TAIL, "-set_label",  0,        "new value for warpRun.label", NULL);
 
 
@@ -364,4 +401,5 @@
     PXOPT_ADD_MODE("-advancerun",      "", WARPTOOL_MODE_ADVANCERUN,     advancerunArgs);
     PXOPT_ADD_MODE("-warped",          "", WARPTOOL_MODE_WARPED,         warpedArgs);
+    PXOPT_ADD_MODE("-listrun",         "", WARPTOOL_MODE_LISTRUN,        listrunArgs);
     PXOPT_ADD_MODE("-runstate",        "", WARPTOOL_MODE_RUNSTATE,       runstateArgs);
     PXOPT_ADD_MODE("-revertwarped",    "", WARPTOOL_MODE_REVERTWARPED,   revertwarpedArgs);
@@ -377,4 +415,5 @@
     PXOPT_ADD_MODE("-tofullskyfile", "set skyfile as full (updated)", WARPTOOL_MODE_TOFULLSKYFILE, tofullskyfileArgs);
     PXOPT_ADD_MODE("-updateskyfile", "update fault code for skyfile", WARPTOOL_MODE_UPDATESKYFILE, updateskyfileArgs);
+    PXOPT_ADD_MODE("-setskyfiletoupdate", "set cleaned skyfile to be updated", WARPTOOL_MODE_SETSKYFILETOUPDATE, setskyfiletoupdateArgs);
     PXOPT_ADD_MODE("-exportrun",            "export run for import on other database", WARPTOOL_MODE_EXPORTRUN, exportrunArgs);
     PXOPT_ADD_MODE("-importrun",            "import run from metadata file",           WARPTOOL_MODE_IMPORTRUN, importrunArgs);
Index: /branches/pap/ippconfig/dvo.photcodes
===================================================================
--- /branches/pap/ippconfig/dvo.photcodes	(revision 28002)
+++ /branches/pap/ippconfig/dvo.photcodes	(revision 28003)
@@ -541,313 +541,324 @@
   4504  SIMMOSAIC.y.03       dep  25.000  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
 
-# 2007.10.02 : predicted g zero-points from 2006 NSF proposal
-  10001 GPC1.g.XY01          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10002 GPC1.g.XY02          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10003 GPC1.g.XY03          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10004 GPC1.g.XY04          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10005 GPC1.g.XY05          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10006 GPC1.g.XY06          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10010 GPC1.g.XY10          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10011 GPC1.g.XY11          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10012 GPC1.g.XY12          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10013 GPC1.g.XY13          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10014 GPC1.g.XY14          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10015 GPC1.g.XY15          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10016 GPC1.g.XY16          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10017 GPC1.g.XY17          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10020 GPC1.g.XY20          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10021 GPC1.g.XY21          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10022 GPC1.g.XY22          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10023 GPC1.g.XY23          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10024 GPC1.g.XY24          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10025 GPC1.g.XY25          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10026 GPC1.g.XY26          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10027 GPC1.g.XY27          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10030 GPC1.g.XY30          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10031 GPC1.g.XY31          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10032 GPC1.g.XY32          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10033 GPC1.g.XY33          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10034 GPC1.g.XY34          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10035 GPC1.g.XY35          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10036 GPC1.g.XY36          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10037 GPC1.g.XY37          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10040 GPC1.g.XY40          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10041 GPC1.g.XY41          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10042 GPC1.g.XY42          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10043 GPC1.g.XY43          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10044 GPC1.g.XY44          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10045 GPC1.g.XY45          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10046 GPC1.g.XY46          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10047 GPC1.g.XY47          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10050 GPC1.g.XY50          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10051 GPC1.g.XY51          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10052 GPC1.g.XY52          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10053 GPC1.g.XY53          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10054 GPC1.g.XY54          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10055 GPC1.g.XY55          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10056 GPC1.g.XY56          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10057 GPC1.g.XY57          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10060 GPC1.g.XY60          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10061 GPC1.g.XY61          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10062 GPC1.g.XY62          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10063 GPC1.g.XY63          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10064 GPC1.g.XY64          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10065 GPC1.g.XY65          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10066 GPC1.g.XY66          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10067 GPC1.g.XY67          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10071 GPC1.g.XY71          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10072 GPC1.g.XY72          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10073 GPC1.g.XY73          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10074 GPC1.g.XY74          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10075 GPC1.g.XY75          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10076 GPC1.g.XY76          dep  24.900  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-
-# 2007.10.02 : predicted r zero-points from 2006 NSF proposal
-  10101 GPC1.r.XY01          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10102 GPC1.r.XY02          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10103 GPC1.r.XY03          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10104 GPC1.r.XY04          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10105 GPC1.r.XY05          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10106 GPC1.r.XY06          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10110 GPC1.r.XY10          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10111 GPC1.r.XY11          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10112 GPC1.r.XY12          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10113 GPC1.r.XY13          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10114 GPC1.r.XY14          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10115 GPC1.r.XY15          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10116 GPC1.r.XY16          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10117 GPC1.r.XY17          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10120 GPC1.r.XY20          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10121 GPC1.r.XY21          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10122 GPC1.r.XY22          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10123 GPC1.r.XY23          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10124 GPC1.r.XY24          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10125 GPC1.r.XY25          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10126 GPC1.r.XY26          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10127 GPC1.r.XY27          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10130 GPC1.r.XY30          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10131 GPC1.r.XY31          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10132 GPC1.r.XY32          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10133 GPC1.r.XY33          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10134 GPC1.r.XY34          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10135 GPC1.r.XY35          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10136 GPC1.r.XY36          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10137 GPC1.r.XY37          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10140 GPC1.r.XY40          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10141 GPC1.r.XY41          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10142 GPC1.r.XY42          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10143 GPC1.r.XY43          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10144 GPC1.r.XY44          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10145 GPC1.r.XY45          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10146 GPC1.r.XY46          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10147 GPC1.r.XY47          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10150 GPC1.r.XY50          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10151 GPC1.r.XY51          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10152 GPC1.r.XY52          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10153 GPC1.r.XY53          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10154 GPC1.r.XY54          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10155 GPC1.r.XY55          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10156 GPC1.r.XY56          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10157 GPC1.r.XY57          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10160 GPC1.r.XY60          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10161 GPC1.r.XY61          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10162 GPC1.r.XY62          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10163 GPC1.r.XY63          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10164 GPC1.r.XY64          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10165 GPC1.r.XY65          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10166 GPC1.r.XY66          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10167 GPC1.r.XY67          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10171 GPC1.r.XY71          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10172 GPC1.r.XY72          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10173 GPC1.r.XY73          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10174 GPC1.r.XY74          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10175 GPC1.r.XY75          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10176 GPC1.r.XY76          dep  25.100  0.000 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-
-# 2007.10.02 : predicted i zero-points from 2006 NSF proposal
-  10201 GPC1.i.XY01          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10202 GPC1.i.XY02          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10203 GPC1.i.XY03          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10204 GPC1.i.XY04          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10205 GPC1.i.XY05          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10206 GPC1.i.XY06          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10210 GPC1.i.XY10          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10211 GPC1.i.XY11          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10212 GPC1.i.XY12          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10213 GPC1.i.XY13          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10214 GPC1.i.XY14          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10215 GPC1.i.XY15          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10216 GPC1.i.XY16          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10217 GPC1.i.XY17          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10220 GPC1.i.XY20          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10221 GPC1.i.XY21          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10222 GPC1.i.XY22          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10223 GPC1.i.XY23          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10224 GPC1.i.XY24          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10225 GPC1.i.XY25          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10226 GPC1.i.XY26          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10227 GPC1.i.XY27          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10230 GPC1.i.XY30          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10231 GPC1.i.XY31          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10232 GPC1.i.XY32          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10233 GPC1.i.XY33          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10234 GPC1.i.XY34          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10235 GPC1.i.XY35          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10236 GPC1.i.XY36          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10237 GPC1.i.XY37          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10240 GPC1.i.XY40          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10241 GPC1.i.XY41          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10242 GPC1.i.XY42          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10243 GPC1.i.XY43          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10244 GPC1.i.XY44          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10245 GPC1.i.XY45          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10246 GPC1.i.XY46          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10247 GPC1.i.XY47          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10250 GPC1.i.XY50          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10251 GPC1.i.XY51          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10252 GPC1.i.XY52          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10253 GPC1.i.XY53          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10254 GPC1.i.XY54          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10255 GPC1.i.XY55          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10256 GPC1.i.XY56          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10257 GPC1.i.XY57          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10260 GPC1.i.XY60          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10261 GPC1.i.XY61          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10262 GPC1.i.XY62          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10263 GPC1.i.XY63          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10264 GPC1.i.XY64          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10265 GPC1.i.XY65          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10266 GPC1.i.XY66          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10267 GPC1.i.XY67          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10271 GPC1.i.XY71          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10272 GPC1.i.XY72          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10273 GPC1.i.XY73          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10274 GPC1.i.XY74          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10275 GPC1.i.XY75          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10276 GPC1.i.XY76          dep  25.000  0.000 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-
-# 2007.10.02 : predicted z zero-points from 2006 NSF proposal
-  10301 GPC1.z.XY01          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10302 GPC1.z.XY02          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10303 GPC1.z.XY03          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10304 GPC1.z.XY04          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10305 GPC1.z.XY05          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10306 GPC1.z.XY06          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10310 GPC1.z.XY10          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10311 GPC1.z.XY11          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10312 GPC1.z.XY12          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10313 GPC1.z.XY13          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10314 GPC1.z.XY14          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10315 GPC1.z.XY15          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10316 GPC1.z.XY16          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10317 GPC1.z.XY17          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10320 GPC1.z.XY20          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10321 GPC1.z.XY21          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10322 GPC1.z.XY22          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10323 GPC1.z.XY23          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10324 GPC1.z.XY24          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10325 GPC1.z.XY25          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10326 GPC1.z.XY26          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10327 GPC1.z.XY27          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10330 GPC1.z.XY30          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10331 GPC1.z.XY31          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10332 GPC1.z.XY32          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10333 GPC1.z.XY33          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10334 GPC1.z.XY34          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10335 GPC1.z.XY35          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10336 GPC1.z.XY36          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10337 GPC1.z.XY37          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10340 GPC1.z.XY40          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10341 GPC1.z.XY41          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10342 GPC1.z.XY42          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10343 GPC1.z.XY43          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10344 GPC1.z.XY44          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10345 GPC1.z.XY45          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10346 GPC1.z.XY46          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10347 GPC1.z.XY47          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10350 GPC1.z.XY50          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10351 GPC1.z.XY51          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10352 GPC1.z.XY52          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10353 GPC1.z.XY53          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10354 GPC1.z.XY54          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10355 GPC1.z.XY55          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10356 GPC1.z.XY56          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10357 GPC1.z.XY57          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10360 GPC1.z.XY60          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10361 GPC1.z.XY61          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10362 GPC1.z.XY62          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10363 GPC1.z.XY63          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10364 GPC1.z.XY64          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10365 GPC1.z.XY65          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10366 GPC1.z.XY66          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10367 GPC1.z.XY67          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10371 GPC1.z.XY71          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10372 GPC1.z.XY72          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10373 GPC1.z.XY73          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10374 GPC1.z.XY74          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10375 GPC1.z.XY75          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10376 GPC1.z.XY76          dep  24.600  0.000 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-
-# 2007.10.02 : predicted y zero-points from 2006 NSF proposal
-  10401 GPC1.y.XY01          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10402 GPC1.y.XY02          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10403 GPC1.y.XY03          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10404 GPC1.y.XY04          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10405 GPC1.y.XY05          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10406 GPC1.y.XY06          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10410 GPC1.y.XY10          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10411 GPC1.y.XY11          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10412 GPC1.y.XY12          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10413 GPC1.y.XY13          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10414 GPC1.y.XY14          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10415 GPC1.y.XY15          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10416 GPC1.y.XY16          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10417 GPC1.y.XY17          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10420 GPC1.y.XY20          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10421 GPC1.y.XY21          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10422 GPC1.y.XY22          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10423 GPC1.y.XY23          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10424 GPC1.y.XY24          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10425 GPC1.y.XY25          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10426 GPC1.y.XY26          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10427 GPC1.y.XY27          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10430 GPC1.y.XY30          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10431 GPC1.y.XY31          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10432 GPC1.y.XY32          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10433 GPC1.y.XY33          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10434 GPC1.y.XY34          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10435 GPC1.y.XY35          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10436 GPC1.y.XY36          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10437 GPC1.y.XY37          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10440 GPC1.y.XY40          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10441 GPC1.y.XY41          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10442 GPC1.y.XY42          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10443 GPC1.y.XY43          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10444 GPC1.y.XY44          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10445 GPC1.y.XY45          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10446 GPC1.y.XY46          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10447 GPC1.y.XY47          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10450 GPC1.y.XY50          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10451 GPC1.y.XY51          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10452 GPC1.y.XY52          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10453 GPC1.y.XY53          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10454 GPC1.y.XY54          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10455 GPC1.y.XY55          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10456 GPC1.y.XY56          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10457 GPC1.y.XY57          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10460 GPC1.y.XY60          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10461 GPC1.y.XY61          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10462 GPC1.y.XY62          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10463 GPC1.y.XY63          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10464 GPC1.y.XY64          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10465 GPC1.y.XY65          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10466 GPC1.y.XY66          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10467 GPC1.y.XY67          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10471 GPC1.y.XY71          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10472 GPC1.y.XY72          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10473 GPC1.y.XY73          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10474 GPC1.y.XY74          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10475 GPC1.y.XY75          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
-  10476 GPC1.y.XY76          dep  22.200  0.000 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+# 2007.10.02 : predicted g zero-points from 2006 NSF proposal was 24.90
+# 2010.05.14 : nominal zero point as measured by Eddie Schlafly (http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/GPC_Zero_Points_July09)
+# 2010.05.14 : airmass slope from Megacam (not measured)
+  10001 GPC1.g.XY01          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10002 GPC1.g.XY02          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10003 GPC1.g.XY03          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10004 GPC1.g.XY04          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10005 GPC1.g.XY05          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10006 GPC1.g.XY06          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10010 GPC1.g.XY10          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10011 GPC1.g.XY11          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10012 GPC1.g.XY12          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10013 GPC1.g.XY13          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10014 GPC1.g.XY14          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10015 GPC1.g.XY15          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10016 GPC1.g.XY16          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10017 GPC1.g.XY17          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10020 GPC1.g.XY20          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10021 GPC1.g.XY21          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10022 GPC1.g.XY22          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10023 GPC1.g.XY23          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10024 GPC1.g.XY24          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10025 GPC1.g.XY25          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10026 GPC1.g.XY26          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10027 GPC1.g.XY27          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10030 GPC1.g.XY30          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10031 GPC1.g.XY31          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10032 GPC1.g.XY32          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10033 GPC1.g.XY33          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10034 GPC1.g.XY34          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10035 GPC1.g.XY35          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10036 GPC1.g.XY36          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10037 GPC1.g.XY37          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10040 GPC1.g.XY40          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10041 GPC1.g.XY41          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10042 GPC1.g.XY42          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10043 GPC1.g.XY43          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10044 GPC1.g.XY44          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10045 GPC1.g.XY45          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10046 GPC1.g.XY46          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10047 GPC1.g.XY47          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10050 GPC1.g.XY50          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10051 GPC1.g.XY51          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10052 GPC1.g.XY52          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10053 GPC1.g.XY53          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10054 GPC1.g.XY54          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10055 GPC1.g.XY55          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10056 GPC1.g.XY56          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10057 GPC1.g.XY57          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10060 GPC1.g.XY60          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10061 GPC1.g.XY61          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10062 GPC1.g.XY62          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10063 GPC1.g.XY63          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10064 GPC1.g.XY64          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10065 GPC1.g.XY65          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10066 GPC1.g.XY66          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10067 GPC1.g.XY67          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10071 GPC1.g.XY71          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10072 GPC1.g.XY72          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10073 GPC1.g.XY73          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10074 GPC1.g.XY74          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10075 GPC1.g.XY75          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10076 GPC1.g.XY76          dep  24.580 -0.150 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+
+# 2007.10.02 : predicted r zero-points from 2006 NSF proposal was 25.10
+# 2010.05.14 : nominal zero point as measured by Eddie Schlafly (http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/GPC_Zero_Points_July09)
+# 2010.05.14 : airmass slope from Megacam (not measured)
+  10101 GPC1.r.XY01          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10102 GPC1.r.XY02          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10103 GPC1.r.XY03          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10104 GPC1.r.XY04          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10105 GPC1.r.XY05          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10106 GPC1.r.XY06          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10110 GPC1.r.XY10          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10111 GPC1.r.XY11          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10112 GPC1.r.XY12          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10113 GPC1.r.XY13          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10114 GPC1.r.XY14          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10115 GPC1.r.XY15          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10116 GPC1.r.XY16          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10117 GPC1.r.XY17          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10120 GPC1.r.XY20          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10121 GPC1.r.XY21          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10122 GPC1.r.XY22          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10123 GPC1.r.XY23          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10124 GPC1.r.XY24          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10125 GPC1.r.XY25          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10126 GPC1.r.XY26          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10127 GPC1.r.XY27          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10130 GPC1.r.XY30          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10131 GPC1.r.XY31          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10132 GPC1.r.XY32          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10133 GPC1.r.XY33          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10134 GPC1.r.XY34          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10135 GPC1.r.XY35          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10136 GPC1.r.XY36          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10137 GPC1.r.XY37          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10140 GPC1.r.XY40          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10141 GPC1.r.XY41          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10142 GPC1.r.XY42          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10143 GPC1.r.XY43          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10144 GPC1.r.XY44          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10145 GPC1.r.XY45          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10146 GPC1.r.XY46          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10147 GPC1.r.XY47          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10150 GPC1.r.XY50          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10151 GPC1.r.XY51          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10152 GPC1.r.XY52          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10153 GPC1.r.XY53          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10154 GPC1.r.XY54          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10155 GPC1.r.XY55          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10156 GPC1.r.XY56          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10157 GPC1.r.XY57          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10160 GPC1.r.XY60          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10161 GPC1.r.XY61          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10162 GPC1.r.XY62          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10163 GPC1.r.XY63          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10164 GPC1.r.XY64          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10165 GPC1.r.XY65          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10166 GPC1.r.XY66          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10167 GPC1.r.XY67          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10171 GPC1.r.XY71          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10172 GPC1.r.XY72          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10173 GPC1.r.XY73          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10174 GPC1.r.XY74          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10175 GPC1.r.XY75          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10176 GPC1.r.XY76          dep  24.800 -0.100 0.000     -     - 0.0000     0     2   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+
+# 2007.10.02 : predicted i zero-points from 2006 NSF proposal was 25.00
+# 2010.05.14 : nominal zero point as measured by Eddie Schlafly (http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/GPC_Zero_Points_July09)
+# 2010.05.14 : airmass slope from Megacam (not measured)
+  10201 GPC1.i.XY01          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10202 GPC1.i.XY02          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10203 GPC1.i.XY03          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10204 GPC1.i.XY04          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10205 GPC1.i.XY05          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10206 GPC1.i.XY06          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10210 GPC1.i.XY10          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10211 GPC1.i.XY11          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10212 GPC1.i.XY12          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10213 GPC1.i.XY13          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10214 GPC1.i.XY14          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10215 GPC1.i.XY15          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10216 GPC1.i.XY16          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10217 GPC1.i.XY17          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10220 GPC1.i.XY20          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10221 GPC1.i.XY21          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10222 GPC1.i.XY22          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10223 GPC1.i.XY23          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10224 GPC1.i.XY24          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10225 GPC1.i.XY25          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10226 GPC1.i.XY26          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10227 GPC1.i.XY27          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10230 GPC1.i.XY30          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10231 GPC1.i.XY31          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10232 GPC1.i.XY32          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10233 GPC1.i.XY33          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10234 GPC1.i.XY34          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10235 GPC1.i.XY35          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10236 GPC1.i.XY36          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10237 GPC1.i.XY37          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10240 GPC1.i.XY40          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10241 GPC1.i.XY41          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10242 GPC1.i.XY42          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10243 GPC1.i.XY43          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10244 GPC1.i.XY44          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10245 GPC1.i.XY45          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10246 GPC1.i.XY46          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10247 GPC1.i.XY47          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10250 GPC1.i.XY50          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10251 GPC1.i.XY51          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10252 GPC1.i.XY52          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10253 GPC1.i.XY53          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10254 GPC1.i.XY54          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10255 GPC1.i.XY55          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10256 GPC1.i.XY56          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10257 GPC1.i.XY57          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10260 GPC1.i.XY60          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10261 GPC1.i.XY61          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10262 GPC1.i.XY62          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10263 GPC1.i.XY63          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10264 GPC1.i.XY64          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10265 GPC1.i.XY65          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10266 GPC1.i.XY66          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10267 GPC1.i.XY67          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10271 GPC1.i.XY71          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10272 GPC1.i.XY72          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10273 GPC1.i.XY73          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10274 GPC1.i.XY74          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10275 GPC1.i.XY75          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10276 GPC1.i.XY76          dep  24.740 -0.040 0.000     -     - 0.0000     0     3   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+
+# 2007.10.02 : predicted z zero-points from 2006 NSF proposal was 24.60
+# 2010.05.14 : nominal zero point as measured by Eddie Schlafly (http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/GPC_Zero_Points_July09)
+# 2010.05.14 : airmass slope from Megacam (not measured)
+  10301 GPC1.z.XY01          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10302 GPC1.z.XY02          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10303 GPC1.z.XY03          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10304 GPC1.z.XY04          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10305 GPC1.z.XY05          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10306 GPC1.z.XY06          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10310 GPC1.z.XY10          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10311 GPC1.z.XY11          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10312 GPC1.z.XY12          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10313 GPC1.z.XY13          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10314 GPC1.z.XY14          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10315 GPC1.z.XY15          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10316 GPC1.z.XY16          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10317 GPC1.z.XY17          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10320 GPC1.z.XY20          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10321 GPC1.z.XY21          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10322 GPC1.z.XY22          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10323 GPC1.z.XY23          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10324 GPC1.z.XY24          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10325 GPC1.z.XY25          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10326 GPC1.z.XY26          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10327 GPC1.z.XY27          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10330 GPC1.z.XY30          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10331 GPC1.z.XY31          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10332 GPC1.z.XY32          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10333 GPC1.z.XY33          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10334 GPC1.z.XY34          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10335 GPC1.z.XY35          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10336 GPC1.z.XY36          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10337 GPC1.z.XY37          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10340 GPC1.z.XY40          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10341 GPC1.z.XY41          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10342 GPC1.z.XY42          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10343 GPC1.z.XY43          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10344 GPC1.z.XY44          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10345 GPC1.z.XY45          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10346 GPC1.z.XY46          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10347 GPC1.z.XY47          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10350 GPC1.z.XY50          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10351 GPC1.z.XY51          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10352 GPC1.z.XY52          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10353 GPC1.z.XY53          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10354 GPC1.z.XY54          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10355 GPC1.z.XY55          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10356 GPC1.z.XY56          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10357 GPC1.z.XY57          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10360 GPC1.z.XY60          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10361 GPC1.z.XY61          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10362 GPC1.z.XY62          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10363 GPC1.z.XY63          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10364 GPC1.z.XY64          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10365 GPC1.z.XY65          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10366 GPC1.z.XY66          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10367 GPC1.z.XY67          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10371 GPC1.z.XY71          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10372 GPC1.z.XY72          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10373 GPC1.z.XY73          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10374 GPC1.z.XY74          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10375 GPC1.z.XY75          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10376 GPC1.z.XY76          dep  24.260 -0.030 0.000     -     - 0.0000     0     4   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+
+# 2007.10.02 : predicted y zero-points from 2006 NSF proposal was 23.00
+# 2007.10.02 : measured y zero-points for the y2 filter was 22.20
+# 2010.05.14 : nominal zero point as measured by Eddie Schlafly (http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/GPC_Zero_Points_July09)
+# 2010.05.14 : airmass slope from Megacam (not measured)
+  10401 GPC1.y.XY01          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10402 GPC1.y.XY02          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10403 GPC1.y.XY03          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10404 GPC1.y.XY04          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10405 GPC1.y.XY05          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10406 GPC1.y.XY06          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10410 GPC1.y.XY10          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10411 GPC1.y.XY11          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10412 GPC1.y.XY12          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10413 GPC1.y.XY13          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10414 GPC1.y.XY14          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10415 GPC1.y.XY15          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10416 GPC1.y.XY16          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10417 GPC1.y.XY17          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10420 GPC1.y.XY20          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10421 GPC1.y.XY21          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10422 GPC1.y.XY22          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10423 GPC1.y.XY23          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10424 GPC1.y.XY24          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10425 GPC1.y.XY25          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10426 GPC1.y.XY26          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10427 GPC1.y.XY27          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10430 GPC1.y.XY30          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10431 GPC1.y.XY31          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10432 GPC1.y.XY32          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10433 GPC1.y.XY33          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10434 GPC1.y.XY34          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10435 GPC1.y.XY35          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10436 GPC1.y.XY36          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10437 GPC1.y.XY37          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10440 GPC1.y.XY40          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10441 GPC1.y.XY41          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10442 GPC1.y.XY42          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10443 GPC1.y.XY43          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10444 GPC1.y.XY44          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10445 GPC1.y.XY45          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10446 GPC1.y.XY46          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10447 GPC1.y.XY47          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10450 GPC1.y.XY50          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10451 GPC1.y.XY51          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10452 GPC1.y.XY52          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10453 GPC1.y.XY53          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10454 GPC1.y.XY54          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10455 GPC1.y.XY55          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10456 GPC1.y.XY56          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10457 GPC1.y.XY57          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10460 GPC1.y.XY60          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10461 GPC1.y.XY61          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10462 GPC1.y.XY62          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10463 GPC1.y.XY63          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10464 GPC1.y.XY64          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10465 GPC1.y.XY65          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10466 GPC1.y.XY66          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10467 GPC1.y.XY67          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10471 GPC1.y.XY71          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10472 GPC1.y.XY72          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10473 GPC1.y.XY73          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10474 GPC1.y.XY74          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10475 GPC1.y.XY75          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
+  10476 GPC1.y.XY76          dep  23.410 -0.030 0.000     -     - 0.0000     0     5   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
 
   11000 GPC1.g.SkyChip       dep  25.000  0.000 0.000     -     - 0.0000     0     1   0.000 0.000 0.000  0.000   0x0000 0x0000  0x0000 0x0000	
Index: /branches/pap/ippconfig/gpc1/ppStack.config
===================================================================
--- /branches/pap/ippconfig/gpc1/ppStack.config	(revision 28002)
+++ /branches/pap/ippconfig/gpc1/ppStack.config	(revision 28003)
@@ -7,4 +7,5 @@
         z.00000       F32     0.0
         y.00000       F32     0.0
+        w.00000       F32     0.0
 END
 ZP.TARGET       METADATA	        # Target zero point by filter
@@ -14,3 +15,4 @@
         z.00000       F32     25.0
         y.00000       F32     25.0
+        w.00000       F32     25.0
 END
Index: /branches/pap/ippconfig/recipes/filerules-mef.mdc
===================================================================
--- /branches/pap/ippconfig/recipes/filerules-mef.mdc	(revision 28002)
+++ /branches/pap/ippconfig/recipes/filerules-mef.mdc	(revision 28003)
@@ -134,4 +134,7 @@
 PPSIM.INPUT             INPUT    @FILES        FPA        IMAGE     
 PPSIM.REAL.SOURCES      INPUT    @FILES        CHIP       CMF       
+
+PPCOORD.ASTROM		INPUT	 @FILES	       FPA	  WCS
+PPCOORD.RAW		INPUT	 @FILES	       CHIP	  IMAGE
 
 ## files used by ppNoiseMap
Index: /branches/pap/ippconfig/recipes/filerules-simple.mdc
===================================================================
--- /branches/pap/ippconfig/recipes/filerules-simple.mdc	(revision 28002)
+++ /branches/pap/ippconfig/recipes/filerules-simple.mdc	(revision 28003)
@@ -1,5 +1,4 @@
 ### File rules for PHU=FPA, EXT=NONE
 ### The default type of NONE means no compression
-
 
 PSASTRO.INPUT      STR PSASTRO.INPUT.CMF
@@ -15,260 +14,281 @@
 
 ## files used by ppImage
-PPIMAGE.INPUT           INPUT    @FILES        FPA        IMAGE     
-PPIMAGE.INPUT.MASK      INPUT    @FILES        FPA        MASK      
-PPIMAGE.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE  
-PPIMAGE.INPUT.PSF       INPUT    @FILES        READOUT    PSF       
-PPIMAGE.INPUT.SRC       INPUT    @FILES        READOUT    CMF       
-PPIMAGE.MASK            INPUT    @DETDB        CHIP       MASK
-PPIMAGE.BIAS            INPUT    @DETDB        CHIP       IMAGE     
-PPIMAGE.DARK            INPUT    @DETDB        CHIP       DARK     
-PPIMAGE.FLAT            INPUT    @DETDB        CHIP       IMAGE     
-PPIMAGE.FRINGE          INPUT    @DETDB        CHIP       FRINGE
-PPIMAGE.SHUTTER         INPUT    @DETDB        CHIP       IMAGE     
-
-## Files used by ppMerge
-PPMERGE.INPUT           INPUT    @FILES        CHIP       IMAGE
-PPMERGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-PPMERGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+PPIMAGE.INPUT             INPUT    @FILES        FPA        IMAGE     
+PPIMAGE.INPUT.MASK        INPUT    @FILES        FPA        MASK      
+PPIMAGE.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE  
+PPIMAGE.INPUT.PSF         INPUT    @FILES        READOUT    PSF       
+PPIMAGE.INPUT.SRC         INPUT    @FILES        READOUT    CMF       
+PPIMAGE.MASK              INPUT    @DETDB        CHIP       MASK
+PPIMAGE.BIAS              INPUT    @DETDB        CHIP       IMAGE     
+PPIMAGE.DARK              INPUT    @DETDB        CHIP       DARK     
+PPIMAGE.FLAT              INPUT    @DETDB        CHIP       IMAGE     
+PPIMAGE.FRINGE            INPUT    @DETDB        CHIP       FRINGE
+PPIMAGE.SHUTTER           INPUT    @DETDB        CHIP       IMAGE     
+                          
+## Files used by ppMerge  
+PPMERGE.INPUT             INPUT    @FILES        CHIP       IMAGE
+PPMERGE.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+PPMERGE.INPUT.VARIANCE    INPUT    @FILES        CHIP       VARIANCE
 
 ## files used to build and apply the flat-field correction images
-DVOCORR.INPUT           INPUT    @FILES        CHIP       IMAGE
-DVOCORR.REFHEAD         INPUT    @FILES        CHIP       HEADER
-DVOFLAT.INPUT           INPUT    @FILES        CHIP       IMAGE
-DVOFLAT.CORR            INPUT    @DETDB        CHIP       IMAGE
-
-## files used by psphot 
-PSPHOT.LOAD             INPUT    @FILES        CHIP       IMAGE
-PSPHOT.INPUT            INPUT    @FILES        CHIP       IMAGE     
-PSPHOT.MASK             INPUT    @FILES        CHIP       MASK     
-PSPHOT.VARIANCE         INPUT    @FILES        CHIP       VARIANCE   
-PSPHOT.PSF.LOAD         INPUT    @FILES        CHIP       PSF       
-PSPHOT.INPUT.CMF        INPUT    @FILES        CHIP       CMF       
-PSPHOT.INPUT.TEXT       INPUT    @FILES        CHIP       SRCTEXT       
+DVOCORR.INPUT             INPUT    @FILES        CHIP       IMAGE
+DVOCORR.REFHEAD           INPUT    @FILES        CHIP       HEADER
+DVOFLAT.INPUT             INPUT    @FILES        CHIP       IMAGE
+DVOFLAT.CORR              INPUT    @DETDB        CHIP       IMAGE
+                          
+## files used by psphot   
+PSPHOT.LOAD               INPUT    @FILES        CHIP       IMAGE
+PSPHOT.INPUT              INPUT    @FILES        CHIP       IMAGE     
+PSPHOT.MASK               INPUT    @FILES        CHIP       MASK     
+PSPHOT.VARIANCE           INPUT    @FILES        CHIP       VARIANCE   
+PSPHOT.PSF.LOAD           INPUT    @FILES        CHIP       PSF       
+PSPHOT.INPUT.CMF          INPUT    @FILES        CHIP       CMF       
+PSPHOT.INPUT.TEXT         INPUT    @FILES        CHIP       SRCTEXT       
+
+## files used by psphotStack
+PSPHOT.STACK.INPUT.RAW    INPUT    @FILES        CHIP       IMAGE
+PSPHOT.STACK.MASK.RAW     INPUT    @FILES        CHIP       MASK     
+PSPHOT.STACK.VARIANCE.RAW INPUT    @FILES        CHIP       VARIANCE     
+PSPHOT.STACK.PSF.RAW      INPUT    @FILES        CHIP       PSF       
+PSPHOT.STACK.INPUT.CNV    INPUT    @FILES        CHIP       IMAGE
+PSPHOT.STACK.MASK.CNV     INPUT    @FILES        CHIP       MASK     
+PSPHOT.STACK.VARIANCE.CNV INPUT    @FILES        CHIP       VARIANCE     
+PSPHOT.STACK.PSF.CNV      INPUT    @FILES        CHIP       PSF       
+PSPHOT.STACK.SOURCES      INPUT    @FILES        FPA        CMF
 
 ## files used by psastro 
-PSASTRO.INPUT.CMP       INPUT    @FILES        CHIP       CMP       
-PSASTRO.INPUT.CMF       INPUT    @FILES        CHIP       CMF       
-PSASTRO.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-PSASTRO.REFMASK         INPUT    @DETDB        CHIP       MASK
-PSASTRO.WCS             INPUT    @FILES        CHIP       CMF
-PSASTRO.MODEL           INPUT    @DETDB        FPA        ASTROM
-
-PSASTRO.EXTRACT.ASTROM  INPUT    @FILES        CHIP       CMF
-PSASTRO.EXTRACT.INPUT   INPUT    @FILES        CHIP       IMAGE
+PSASTRO.INPUT.CMP         INPUT    @FILES        CHIP       CMP       
+PSASTRO.INPUT.CMF         INPUT    @FILES        CHIP       CMF       
+PSASTRO.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+PSASTRO.REFMASK           INPUT    @DETDB        CHIP       MASK
+PSASTRO.WCS               INPUT    @FILES        CHIP       CMF
+PSASTRO.MODEL             INPUT    @DETDB        FPA        ASTROM
+
+PSASTRO.EXTRACT.ASTROM    INPUT    @FILES        CHIP       CMF
+PSASTRO.EXTRACT.INPUT     INPUT    @FILES        CHIP       IMAGE
 
 ## files used by pswarp
-PSWARP.INPUT            INPUT    @FILES        FPA        IMAGE     
-PSWARP.VARIANCE         INPUT    @FILES        FPA        VARIANCE
-PSWARP.MASK             INPUT    @FILES        FPA        MASK
-PSWARP.SKYCELL          INPUT    @FILES        FPA        IMAGE     
-PSWARP.ASTROM           INPUT    @FILES        FPA        CMF
+PSWARP.INPUT              INPUT    @FILES        FPA        IMAGE     
+PSWARP.VARIANCE           INPUT    @FILES        FPA        VARIANCE
+PSWARP.MASK               INPUT    @FILES        FPA        MASK
+PSWARP.SKYCELL            INPUT    @FILES        FPA        IMAGE     
+PSWARP.ASTROM             INPUT    @FILES        FPA        CMF
 
 ## files used by ppsub
-PPSUB.INPUT             INPUT    @FILES        FPA        IMAGE
-PPSUB.INPUT.MASK        INPUT    @FILES        FPA        MASK
-PPSUB.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
-PPSUB.INPUT.SOURCES     INPUT    @FILES        FPA        CMF
-PPSUB.REF               INPUT    @FILES        FPA        IMAGE
-PPSUB.REF.MASK          INPUT    @FILES        FPA        MASK
-PPSUB.REF.VARIANCE      INPUT    @FILES        FPA        VARIANCE
-PPSUB.REF.SOURCES       INPUT    @FILES        FPA        CMF
-PPSUB.INPUT.KERNEL      INPUT    @FILES        FPA        SUBKERNEL
+PPSUB.INPUT               INPUT    @FILES        FPA        IMAGE
+PPSUB.INPUT.MASK          INPUT    @FILES        FPA        MASK
+PPSUB.INPUT.VARIANCE      INPUT    @FILES        FPA        VARIANCE
+PPSUB.INPUT.SOURCES       INPUT    @FILES        FPA        CMF
+PPSUB.INPUT.KERNEL        INPUT    @FILES        FPA        SUBKERNEL
+PPSUB.REF                 INPUT    @FILES        FPA        IMAGE
+PPSUB.REF.MASK            INPUT    @FILES        FPA        MASK
+PPSUB.REF.VARIANCE        INPUT    @FILES        FPA        VARIANCE
+PPSUB.REF.SOURCES         INPUT    @FILES        FPA        CMF
 
 ## files used by ppstack
-PPSTACK.INPUT           INPUT    @FILES        FPA        IMAGE
-PPSTACK.INPUT.MASK      INPUT    @FILES        FPA        MASK
-PPSTACK.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
-PPSTACK.INPUT.PSF       INPUT    @FILES        CHIP       PSF
-PPSTACK.INPUT.SOURCES   INPUT    @FILES        FPA        CMF
+PPSTACK.INPUT             INPUT    @FILES        FPA        IMAGE
+PPSTACK.INPUT.MASK        INPUT    @FILES        FPA        MASK
+PPSTACK.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
+PPSTACK.INPUT.PSF         INPUT    @FILES        CHIP       PSF
+PPSTACK.INPUT.SOURCES     INPUT    @FILES        FPA        CMF
 
 ## files used by ppstamp
-PPSTAMP.INPUT           INPUT    @FILES        FPA        IMAGE
-PPSTAMP.INPUT.MASK      INPUT    @FILES        FPA        MASK
-PPSTAMP.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
+PPSTAMP.INPUT             INPUT    @FILES        FPA        IMAGE
+PPSTAMP.INPUT.MASK        INPUT    @FILES        FPA        MASK
+PPSTAMP.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
 
 # files used by pparith
-PPARITH.INPUT.IMAGE     INPUT    @FILES        CHIP       IMAGE
-PPARITH.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-
-PPSKYCELL.IMAGE      	INPUT 	 @FILES        CHIP       IMAGE
-PPSKYCELL.MASK      	INPUT 	 @FILES        CHIP       MASK
-
-PPSIM.INPUT             INPUT    @FILES        FPA        IMAGE     
-PPSIM.REAL.SOURCES      INPUT    @FILES        CHIP       CMF       
+PPARITH.INPUT.IMAGE       INPUT    @FILES        CHIP       IMAGE
+PPARITH.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+
+PPSKYCELL.IMAGE           INPUT    @FILES        CHIP       IMAGE
+PPSKYCELL.MASK            INPUT    @FILES        CHIP       MASK
+
+PPSIM.INPUT               INPUT    @FILES        FPA        IMAGE     
+PPSIM.REAL.SOURCES        INPUT    @FILES        CHIP       CMF       
+
+PPCOORD.ASTROM		  INPUT	   @FILES	 FPA	    WCS
+PPCOORD.RAW		  INPUT	   @FILES	 CHIP	    IMAGE
 
 ## files used by ppNoiseMap
-PPNOISEMAP.INPUT        INPUT    @FILES        CHIP       IMAGE
+PPNOISEMAP.INPUT          INPUT    @FILES        CHIP       IMAGE
 
 ## files used by censorObject 
-CENSOR.INPUT       	INPUT    @FILES        CHIP       CMF
-CENSOR.INPUT.MASK       INPUT    @FILES        CHIP       MASK
+CENSOR.INPUT              INPUT    @FILES        CHIP       CMF
+CENSOR.INPUT.MASK         INPUT    @FILES        CHIP       MASK
 
 ## Files used by ppSmooth
-PPSMOOTH.INPUT          INPUT    @FILES        CHIP       IMAGE
-PPSMOOTH.INPUT.MASK     INPUT    @FILES        CHIP       MASK
-PPSMOOTH.INPUT.VARIANCE INPUT    @FILES        CHIP       VARIANCE
+PPSMOOTH.INPUT            INPUT    @FILES        CHIP       IMAGE
+PPSMOOTH.INPUT.MASK       INPUT    @FILES        CHIP       MASK
+PPSMOOTH.INPUT.VARIANCE   INPUT    @FILES        CHIP       VARIANCE
 
 ## Files used by ppbgrestore
-PPBGRESTORE.INPUT       INPUT    @FILES        FPA        IMAGE
-PPBGRESTORE.BACKMDL     INPUT    @FILES        FPA        IMAGE
+PPBGRESTORE.INPUT         INPUT    @FILES        FPA        IMAGE
+PPBGRESTORE.BACKMDL       INPUT    @FILES        FPA        IMAGE
+
+PPVIZPATTERN.INPUT        INPUT    @FILES        CHIP       PATTERN
 
 ### output file definitions
-TYPE                    OUTPUT FILENAME.RULE         FILE.TYPE FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
-PPIMAGE.OUTPUT          OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits      MASK      NONE       FPA        TRUE      SIMPLE
-PPIMAGE.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits      VARIANCE  NONE       FPA        TRUE      SIMPLE
-PPIMAGE.OUTPUT.DETMASK  OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.OUTPUT.DETREND  OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.OUTPUT.RESID    OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.CONFIG          OUTPUT {OUTPUT}.ppImage.mdc  TEXT      NONE       FPA        TRUE      NONE
-                                                     
-PPIMAGE.CHIP            OUTPUT {OUTPUT}.ch.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.CHIP.MASK       OUTPUT {OUTPUT}.ch.mk.fits   MASK      NONE       FPA        TRUE      SIMPLE
-PPIMAGE.CHIP.VARIANCE   OUTPUT {OUTPUT}.ch.wt.fits   VARIANCE  NONE       FPA        TRUE      SIMPLE
-                                                     
-PPIMAGE.OUTPUT.FPA1     OUTPUT {OUTPUT}.b1.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.OUTPUT.FPA2     OUTPUT {OUTPUT}.b2.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-                                                     
-PPIMAGE.BIN1            OUTPUT {OUTPUT}.b1.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-PPIMAGE.BIN2            OUTPUT {OUTPUT}.b2.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-                                                     
-PPIMAGE.JPEG1           OUTPUT {OUTPUT}.b1.jpg       JPEG      NONE       FPA        TRUE      NONE
-PPIMAGE.JPEG2           OUTPUT {OUTPUT}.b2.jpg       JPEG      NONE       FPA        TRUE      NONE
-                                                     
-PPIMAGE.STATS           OUTPUT {OUTPUT}.stats        STATS     NONE       FPA        TRUE      NONE
+TYPE                         OUTPUT FILENAME.RULE                 FILE.TYPE       FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
+PPIMAGE.OUTPUT               OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.MASK          OUTPUT {OUTPUT}.mk.fits              MASK            NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.VARIANCE      OUTPUT {OUTPUT}.wt.fits              VARIANCE        NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.DETMASK       OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.DETREND       OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.RESID         OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CONFIG               OUTPUT {OUTPUT}.ppImage.mdc          TEXT            NONE       FPA        TRUE      NONE
+                                                     
+PPIMAGE.CHIP                 OUTPUT {OUTPUT}.ch.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CHIP.DETMASK         OUTPUT {OUTPUT}.ch.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CHIP.MASK            OUTPUT {OUTPUT}.ch.mk.fits           MASK            NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CHIP.VARIANCE        OUTPUT {OUTPUT}.ch.wt.fits           VARIANCE        NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CHIP.RESID           OUTPUT {OUTPUT}.ch.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+                                                     
+PPIMAGE.OUTPUT.FPA1          OUTPUT {OUTPUT}.b1.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.FPA2          OUTPUT {OUTPUT}.b2.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+                                                     
+PPIMAGE.BIN1                 OUTPUT {OUTPUT}.b1.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+PPIMAGE.BIN2                 OUTPUT {OUTPUT}.b2.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+                                                     
+PPIMAGE.JPEG1                OUTPUT {OUTPUT}.b1.jpg               JPEG            NONE       FPA        TRUE      NONE
+PPIMAGE.JPEG2                OUTPUT {OUTPUT}.b2.jpg               JPEG            NONE       FPA        TRUE      NONE
+PPIMAGE.PATTERN              OUTPUT {OUTPUT}.ptn                  PATTERN         NONE       FPA        TRUE      NONE
+PPIMAGE.STATS                OUTPUT {OUTPUT}.stats                STATS           NONE       FPA        TRUE      NONE
 
 
 ## note: these use the  same output naming convention since they are used for different ppMerge runs
-PPMERGE.OUTPUT.MASK     OUTPUT {OUTPUT}.fits         MASK      NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.BIAS     OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.DARK     OUTPUT {OUTPUT}.fits         DARK      NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.SHUTTER  OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.FLAT     OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.FRINGE   OUTPUT {OUTPUT}.fits         FRINGE    NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.SIGMA    OUTPUT {OUTPUT}.sigma.fits   IMAGE     NONE       FPA        TRUE      SIMPLE
-PPMERGE.OUTPUT.COUNT    OUTPUT {OUTPUT}.count.fits   IMAGE     NONE       FPA        TRUE      SIMPLE
-                                                     
-DVOCORR.OUTPUT          OUTPUT {OUTPUT}.fc.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-DVOFLAT.OUTPUT          OUTPUT {OUTPUT}.co.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
-                                                     
-PSPHOT.RESID            OUTPUT {OUTPUT}.res.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
-PSPHOT.BACKGND          OUTPUT {OUTPUT}.bck.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
-PSPHOT.BACKSUB          OUTPUT {OUTPUT}.sub.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
-PSPHOT.BACKMDL          OUTPUT {OUTPUT}.mdl.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
-PSPHOT.BACKMDL.MEF      OUTPUT {OUTPUT}.mdl.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
-                                                     
-PSPHOT.OUTPUT.RAW       OUTPUT {OUTPUT}              RAW       NONE       FPA        TRUE      NONE
-PSPHOT.OUTPUT.SX        OUTPUT {OUTPUT}.sx           SX        NONE       FPA        TRUE      NONE
-PSPHOT.OUTPUT.OBJ       OUTPUT {OUTPUT}.obj          OBJ       NONE       FPA        TRUE      NONE
-PSPHOT.OUTPUT.CMP       OUTPUT {OUTPUT}.cmp          CMP       NONE       FPA        TRUE      NONE
-PSPHOT.OUTPUT.CMF       OUTPUT {OUTPUT}.cmf          CMF       NONE       CHIP       TRUE      NONE
-PSPHOT.OUT.CMF.MEF      OUTPUT {OUTPUT}.cmf          CMF       NONE       CHIP       TRUE      NONE
-PSPHOT.PSF.RAW.SAVE     OUTPUT {OUTPUT}.psf          PSF       NONE       FPA        TRUE      NONE
-PSPHOT.PSF.SKY.SAVE     OUTPUT {OUTPUT}.psf          PSF       NONE       FPA        TRUE      NONE
+PPMERGE.OUTPUT.MASK          OUTPUT {OUTPUT}.fits                 MASK            NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.BIAS          OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.DARK          OUTPUT {OUTPUT}.fits                 DARK            NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.SHUTTER       OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.FLAT          OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.FRINGE        OUTPUT {OUTPUT}.fits                 FRINGE          NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.SIGMA         OUTPUT {OUTPUT}.sigma.fits           IMAGE           NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.COUNT         OUTPUT {OUTPUT}.count.fits           IMAGE           NONE       FPA        TRUE      SIMPLE
+                                                     
+DVOCORR.OUTPUT               OUTPUT {OUTPUT}.fc.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+DVOFLAT.OUTPUT               OUTPUT {OUTPUT}.co.fits              IMAGE           NONE       FPA        TRUE      SIMPLE
+                                                     
+PSPHOT.RESID                 OUTPUT {OUTPUT}.res.fits             IMAGE           NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKGND               OUTPUT {OUTPUT}.bck.fits             IMAGE           NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKSUB               OUTPUT {OUTPUT}.sub.fits             IMAGE           NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKMDL               OUTPUT {OUTPUT}.mdl.fits             IMAGE           NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKMDL.MEF           OUTPUT {OUTPUT}.mdl.fits             IMAGE           NONE       FPA        TRUE      SIMPLE
+                                                     
+PSPHOT.OUTPUT.RAW            OUTPUT {OUTPUT}                      RAW             NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.SX             OUTPUT {OUTPUT}.sx                   SX              NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.OBJ            OUTPUT {OUTPUT}.obj                  OBJ             NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.CMP            OUTPUT {OUTPUT}.cmp                  CMP             NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.CMF            OUTPUT {OUTPUT}.cmf                  CMF             NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.MEF           OUTPUT {OUTPUT}.cmf                  CMF             NONE       CHIP       TRUE      NONE
+PSPHOT.PSF.RAW.SAVE          OUTPUT {OUTPUT}.psf                  PSF             NONE       FPA        TRUE      NONE
+PSPHOT.PSF.SKY.SAVE          OUTPUT {OUTPUT}.psf                  PSF             NONE       FPA        TRUE      NONE
 
 # outputs for psphotStack:
-PSPHOT.CHISQ.IMAGE      OUTPUT {OUTPUT}.chisq.im.fits IMAGE    NONE       FPA        TRUE      SIMPLE
-PSPHOT.CHISQ.MASK       OUTPUT {OUTPUT}.chisq.mk.fits MASK     NONE       FPA        TRUE      SIMPLE
-PSPHOT.CHISQ.VARIANCE   OUTPUT {OUTPUT}.chisq.wt.fits VARIANCE NONE       FPA        TRUE      SIMPLE
-PSPHOT.STACK.OUTPUT     OUTPUT {OUTPUT}.{FILE.ID}.cmf CMF      NONE       FPA        TRUE      NONE
-                                                     
-SOURCE.PLOT.MOMENTS     OUTPUT {OUTPUT}.mnt.png      KAPA      NONE       FPA        TRUE      NONE
-SOURCE.PLOT.PSFMODEL    OUTPUT {OUTPUT}.psf.png      KAPA      NONE       FPA        TRUE      NONE
-SOURCE.PLOT.APRESID     OUTPUT {OUTPUT}.dap.png      KAPA      NONE       FPA        TRUE      NONE
-                                                     
-PSASTRO.OUTPUT.CMP      OUTPUT {OUTPUT}.smp          CMP       NONE       FPA        TRUE      NONE
-PSASTRO.OUTPUT.CMF      OUTPUT {OUTPUT}.smf          CMF       NONE       FPA        TRUE      NONE
-PSASTRO.OUT.MODEL       OUTPUT {OUTPUT}.asm          ASTROM.MODEL    NONE FPA        TRUE      NONE
-PSASTRO.OUT.REFSTARS    OUTPUT {OUTPUT}.aref.fits    ASTROM.REFSTARS NONE FPA        TRUE      NONE
-PSASTRO.STATS           OUTPUT {OUTPUT}.stats        STATS     NONE       FPA        TRUE      NONE
-PSASTRO.CONFIG          OUTPUT {OUTPUT}.psastro.mdc  TEXT      NONE       FPA        TRUE      NONE
-PSASTRO.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
-                                                     
-PSWARP.OUTPUT           OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      NONE
-PSWARP.OUTPUT.MASK      OUTPUT {OUTPUT}.mask.fits    MASK      NONE       FPA        TRUE      NONE
-PSWARP.OUTPUT.VARIANCE  OUTPUT {OUTPUT}.wt.fits      VARIANCE  NONE       FPA        TRUE      NONE
-PSWARP.OUTPUT.SOURCES   OUTPUT {OUTPUT}.cmf          CMF       NONE       FPA        TRUE      NONE
-PSWARP.BIN1             OUTPUT {OUTPUT}.b1.fits      IMAGE     NONE       FPA        TRUE      NONE
-PSWARP.BIN2             OUTPUT {OUTPUT}.b2.fits      IMAGE     NONE       FPA        TRUE      NONE
-PSWARP.CONFIG           OUTPUT {OUTPUT}.pswarp.mdc   TEXT      NONE       FPA        TRUE      NONE
-                                                     
-SKYCELL.STATS           OUTPUT {OUTPUT}.stats        STATS     NONE       FPA        TRUE      NONE
-SKYCELL.TEMPLATE        OUTPUT {OUTPUT}.skycell      SKYCELL   NONE       FPA        TRUE      NONE
-                                                     
-PPSUB.OUTPUT            OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.MASK       OUTPUT {OUTPUT}.mask.fits    MASK      NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.VARIANCE   OUTPUT {OUTPUT}.wt.fits      VARIANCE  NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.SOURCES    OUTPUT {OUTPUT}.cmf          CMF       NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.KERNELS    OUTPUT {OUTPUT}.subkernel    SUBKERNEL NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.JPEG1      OUTPUT {OUTPUT}.b1.jpg       JPEG      NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.JPEG2      OUTPUT {OUTPUT}.b2.jpg       JPEG      NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.RESID.JPEG OUTPUT {OUTPUT}.res.jpg      JPEG      NONE       FPA        TRUE      NONE
-PPSUB.INVERSE           OUTPUT {OUTPUT}.inv.fits     IMAGE     NONE       FPA        TRUE      NONE
-PPSUB.INVERSE.MASK      OUTPUT {OUTPUT}.inv.mask.fits MASK     NONE       FPA        TRUE      NONE
-PPSUB.INVERSE.VARIANCE  OUTPUT {OUTPUT}.inv.wt.fits  VARIANCE  NONE       FPA        TRUE      NONE
-PPSUB.INVERSE.SOURCES   OUTPUT {OUTPUT}.inv.cmf      CMF       NONE       FPA        TRUE      NONE
-PPSUB.CONFIG            OUTPUT {OUTPUT}.ppSub.mdc    TEXT      NONE       FPA        TRUE      NONE
-PPSUB.INPUT.CONV        OUTPUT {OUTPUT}.inConv.fits     IMAGE  NONE       FPA        TRUE      NONE
-PPSUB.INPUT.CONV.MASK   OUTPUT {OUTPUT}.inConv.mk.fits  MASK   NONE       FPA        TRUE      NONE
-PPSUB.INPUT.CONV.VARIANCE OUTPUT {OUTPUT}.inConv.wt.fits VARIANCE NONE    FPA        TRUE      NONE
-PPSUB.REF.CONV        	OUTPUT {OUTPUT}.refConv.fits    IMAGE  NONE       FPA        TRUE      NONE
-PPSUB.REF.CONV.MASK   	OUTPUT {OUTPUT}.refConv.mk.fits MASK   NONE       FPA        TRUE      NONE
-PPSUB.REF.CONV.VARIANCE OUTPUT {OUTPUT}.refConv.wt.fits VARIANCE NONE     FPA        TRUE      NONE
-					     
-PPSTACK.OUTPUT          OUTPUT {OUTPUT}.fits         IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSTACK.OUTPUT.MASK     OUTPUT {OUTPUT}.mask.fits    MASK      COMP_MASK  FPA        TRUE      NONE
-PPSTACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.weight.fits  VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSTACK.OUTPUT.EXP	OUTPUT {OUTPUT}.exp.fits     IMAGE     EXP	  FPA	     TRUE      NONE
-PPSTACK.OUTPUT.EXPNUM	OUTPUT {OUTPUT}.num.fits     MASK      EXPNUM	  FPA	     TRUE      NONE
-PPSTACK.OUTPUT.EXPWT	OUTPUT {OUTPUT}.expwt.fits   VARIANCE  EXP	  FPA	     TRUE      NONE
-PPSTACK.UNCONV          OUTPUT {OUTPUT}.unconv.fits  IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSTACK.UNCONV.MASK     OUTPUT {OUTPUT}.unconv.mask.fits MASK  COMP_MASK  FPA        TRUE      NONE
-PPSTACK.UNCONV.VARIANCE OUTPUT {OUTPUT}.unconv.wt.fits VARIANCE COMP_WT   FPA        TRUE      NONE
-PPSTACK.UNCONV.EXP	OUTPUT {OUTPUT}.unconv.exp.fits IMAGE  EXP	  FPA	     TRUE      NONE
-PPSTACK.UNCONV.EXPNUM	OUTPUT {OUTPUT}.unconv.num.fits MASK   EXPNUM	  FPA	     TRUE      NONE
-PPSTACK.UNCONV.EXPWT	OUTPUT {OUTPUT}.unconv.expwt.fits VARIANCE EXP	  FPA	     TRUE      NONE
-PPSTACK.TARGET.PSF      OUTPUT {OUTPUT}.target.psf   PSF       NONE       CHIP       TRUE      NONE
-PPSTACK.CONV.KERNEL     OUTPUT {OUTPUT}.{FILE.INDEX}.kernel SUBKERNEL NONE FPA       TRUE      NONE
-PPSTACK.OUTPUT.JPEG1    OUTPUT {OUTPUT}.b1.jpg       JPEG      NONE       FPA        TRUE      NONE
-PPSTACK.OUTPUT.JPEG2    OUTPUT {OUTPUT}.b2.jpg       JPEG      NONE       FPA        TRUE      NONE
-PPSTACK.CONFIG          OUTPUT {OUTPUT}.ppStack.mdc  TEXT      NONE       FPA        TRUE      NONE
+PSPHOT.CHISQ.IMAGE           OUTPUT {OUTPUT}.chisq.im.fits        IMAGE           NONE       FPA        TRUE      SIMPLE
+PSPHOT.CHISQ.MASK            OUTPUT {OUTPUT}.chisq.mk.fits        MASK            NONE       FPA        TRUE      SIMPLE
+PSPHOT.CHISQ.VARIANCE        OUTPUT {OUTPUT}.chisq.wt.fits        VARIANCE        NONE       FPA        TRUE      SIMPLE
+PSPHOT.STACK.OUTPUT.IMAGE    OUTPUT {OUTPUT}.{FILE.ID}.im.fits    IMAGE           NONE       FPA        TRUE      SIMPLE
+PSPHOT.STACK.OUTPUT.MASK     OUTPUT {OUTPUT}.{FILE.ID}.mk.fits    MASK            NONE       FPA        TRUE      SIMPLE
+PSPHOT.STACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.{FILE.ID}.wt.fits    VARIANCE        NONE       FPA        TRUE      SIMPLE
+PSPHOT.STACK.OUTPUT          OUTPUT {OUTPUT}.{FILE.ID}.cmf        CMF             NONE       FPA        TRUE      NONE
+                                                     
+SOURCE.PLOT.MOMENTS          OUTPUT {OUTPUT}.mnt.png              KAPA            NONE       FPA        TRUE      NONE
+SOURCE.PLOT.PSFMODEL         OUTPUT {OUTPUT}.psf.png              KAPA            NONE       FPA        TRUE      NONE
+SOURCE.PLOT.APRESID          OUTPUT {OUTPUT}.dap.png              KAPA            NONE       FPA        TRUE      NONE
+                                                     
+PSASTRO.OUTPUT.CMP           OUTPUT {OUTPUT}.smp                  CMP             NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.CMF           OUTPUT {OUTPUT}.smf                  CMF             NONE       FPA        TRUE      NONE
+PSASTRO.OUT.MODEL            OUTPUT {OUTPUT}.asm                  ASTROM.MODEL    NONE       FPA        TRUE      NONE
+PSASTRO.OUT.REFSTARS         OUTPUT {OUTPUT}.aref.fits            ASTROM.REFSTARS NONE       FPA        TRUE      NONE
+PSASTRO.STATS                OUTPUT {OUTPUT}.stats                STATS           NONE       FPA        TRUE      NONE
+PSASTRO.CONFIG               OUTPUT {OUTPUT}.psastro.mdc          TEXT            NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.MASK          OUTPUT {OUTPUT}.mk.fits              MASK            COMP_MASK  CHIP       TRUE      NONE
+                                                     
+PSWARP.OUTPUT                OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      NONE
+PSWARP.OUTPUT.MASK           OUTPUT {OUTPUT}.mask.fits            MASK            NONE       FPA        TRUE      NONE
+PSWARP.OUTPUT.VARIANCE       OUTPUT {OUTPUT}.wt.fits              VARIANCE        NONE       FPA        TRUE      NONE
+PSWARP.OUTPUT.SOURCES        OUTPUT {OUTPUT}.cmf                  CMF             NONE       FPA        TRUE      NONE
+PSWARP.BIN1                  OUTPUT {OUTPUT}.b1.fits              IMAGE           NONE       FPA        TRUE      NONE
+PSWARP.BIN2                  OUTPUT {OUTPUT}.b2.fits              IMAGE           NONE       FPA        TRUE      NONE
+PSWARP.CONFIG                OUTPUT {OUTPUT}.pswarp.mdc           TEXT            NONE       FPA        TRUE      NONE
+                                                     
+SKYCELL.STATS                OUTPUT {OUTPUT}.stats                STATS           NONE       FPA        TRUE      NONE
+SKYCELL.TEMPLATE             OUTPUT {OUTPUT}.skycell              SKYCELL         NONE       FPA        TRUE      NONE
+                                                     
+PPSUB.OUTPUT                 OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.MASK            OUTPUT {OUTPUT}.mask.fits            MASK            NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.VARIANCE        OUTPUT {OUTPUT}.wt.fits              VARIANCE        NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.SOURCES         OUTPUT {OUTPUT}.cmf                  CMF             NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.KERNELS         OUTPUT {OUTPUT}.subkernel            SUBKERNEL       NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG1           OUTPUT {OUTPUT}.b1.jpg               JPEG            NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG2           OUTPUT {OUTPUT}.b2.jpg               JPEG            NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.RESID.JPEG      OUTPUT {OUTPUT}.res.jpg              JPEG            NONE       FPA        TRUE      NONE
+PPSUB.INVERSE                OUTPUT {OUTPUT}.inv.fits             IMAGE           NONE       FPA        TRUE      NONE
+PPSUB.INVERSE.MASK           OUTPUT {OUTPUT}.inv.mask.fits        MASK            NONE       FPA        TRUE      NONE
+PPSUB.INVERSE.VARIANCE       OUTPUT {OUTPUT}.inv.wt.fits          VARIANCE        NONE       FPA        TRUE      NONE
+PPSUB.INVERSE.SOURCES        OUTPUT {OUTPUT}.inv.cmf              CMF             NONE       FPA        TRUE      NONE
+PPSUB.CONFIG                 OUTPUT {OUTPUT}.ppSub.mdc            TEXT            NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV             OUTPUT {OUTPUT}.inConv.fits          IMAGE           NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV.MASK        OUTPUT {OUTPUT}.inConv.mk.fits       MASK            NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV.VARIANCE    OUTPUT {OUTPUT}.inConv.wt.fits       VARIANCE        NONE       FPA        TRUE      NONE
+PPSUB.REF.CONV               OUTPUT {OUTPUT}.refConv.fits         IMAGE           NONE       FPA        TRUE      NONE
+PPSUB.REF.CONV.MASK          OUTPUT {OUTPUT}.refConv.mk.fits      MASK            NONE       FPA        TRUE      NONE
+PPSUB.REF.CONV.VARIANCE      OUTPUT {OUTPUT}.refConv.wt.fits      VARIANCE        NONE       FPA        TRUE      NONE
                                              
-PPSTAMP.OUTPUT          OUTPUT {OUTPUT}.fits         IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSTAMP.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits      MASK      COMP_MASK  FPA        TRUE      NONE
-PPSTAMP.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits      VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSTAMP.CHIP            OUTPUT {OUTPUT}.ch.fits      IMAGE     NONE       CHIP       FALSE     NONE
-                                                     
-PPSIM.OUTPUT            OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPSIM.FAKE.CHIP         OUTPUT {OUTPUT}.fake.fits    IMAGE     NONE       FPA        TRUE      SIMPLE
-PPSIM.FORCE.CHIP        OUTPUT {OUTPUT}.force.fits   IMAGE     NONE       FPA        TRUE      SIMPLE
-PPSIM.SOURCES           OUTPUT {OUTPUT}.cmf          CMF       NONE       FPA        TRUE      NONE
-PPSIM.FAKE.SOURCES      OUTPUT {OUTPUT}.fake.cmf     CMF       NONE       FPA        TRUE      NONE
-PPSIM.FORCE.SOURCES     OUTPUT {OUTPUT}.force.cmf    CMF       NONE       FPA        TRUE      NONE
-                                                     
-PPARITH.OUTPUT.IMAGE    OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
-PPARITH.OUTPUT.MASK     OUTPUT {OUTPUT}.fits         MASK      NONE       FPA        TRUE      SIMPLE
-
-PPSKYCELL.JPEG1    	OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg JPEG NONE    CHIP       TRUE      NONE
-PPSKYCELL.JPEG2    	OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg JPEG NONE    CHIP       TRUE      NONE
-
-LOG.IMFILE              OUTPUT {OUTPUT}.imfile.log   TEXT      NONE       FPA        TRUE      NONE
-LOG.EXP                 OUTPUT {OUTPUT}.exp.log      TEXT      NONE       FPA        TRUE      NONE
-
-TRACE.IMFILE            OUTPUT {OUTPUT}.imfile.trace TEXT      NONE       FPA        TRUE      NONE
-TRACE.EXP               OUTPUT {OUTPUT}.exp.trace    TEXT      NONE       FPA        TRUE      NONE
-
-PPNOISEMAP.OUTPUT       OUTPUT {OUTPUT}.{CHIP.NAME}.fits IMAGE NONE       CHIP       TRUE      NONE
-
-CENSOR.OUTPUT           OUTPUT {OUTPUT}.smf          CMF       NONE       FPA        TRUE      MEF
-
-MAGIC.ORIGINAL.PNG      OUTPUT {OUTPUT}_original.png             JPEG      NONE       FPA        TRUE      NONE
-MAGIC.RESIDUAL.PNG      OUTPUT {OUTPUT}_residual.png             JPEG      NONE       FPA        TRUE      NONE
-MAGIC.MASK.PNG          OUTPUT {OUTPUT}_mask.png                 JPEG      NONE       FPA        TRUE      NONE
-MAGIC.DUPLICATE.PNG     OUTPUT {OUTPUT}_duplicate.png            JPEG      NONE       FPA        TRUE      NONE
-
-PPSMOOTH.OUTPUT          OUTPUT {OUTPUT}.fits        IMAGE     NONE       FPA        TRUE      SIMPLE
-PPSMOOTH.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits     MASK      NONE       FPA        TRUE      SIMPLE
-PPSMOOTH.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits     VARIANCE  NONE       FPA        TRUE      SIMPLE
-
-PPBGRESTORE.OUTPUT      OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT               OUTPUT {OUTPUT}.fits                 IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSTACK.OUTPUT.MASK          OUTPUT {OUTPUT}.mask.fits            MASK            COMP_MASK  FPA        TRUE      NONE
+PPSTACK.OUTPUT.VARIANCE      OUTPUT {OUTPUT}.weight.fits          VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSTACK.OUTPUT.EXP           OUTPUT {OUTPUT}.exp.fits             IMAGE           EXP        FPA        TRUE      NONE
+PPSTACK.OUTPUT.EXPNUM        OUTPUT {OUTPUT}.num.fits             MASK            EXPNUM     FPA        TRUE      NONE
+PPSTACK.OUTPUT.EXPWT         OUTPUT {OUTPUT}.expwt.fits           VARIANCE        EXP        FPA        TRUE      NONE
+PPSTACK.UNCONV               OUTPUT {OUTPUT}.unconv.fits          IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSTACK.UNCONV.MASK          OUTPUT {OUTPUT}.unconv.mask.fits     MASK            COMP_MASK  FPA        TRUE      NONE
+PPSTACK.UNCONV.VARIANCE      OUTPUT {OUTPUT}.unconv.wt.fits       VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSTACK.UNCONV.EXP           OUTPUT {OUTPUT}.unconv.exp.fits      IMAGE           EXP        FPA        TRUE      NONE
+PPSTACK.UNCONV.EXPNUM        OUTPUT {OUTPUT}.unconv.num.fits      MASK            EXPNUM     FPA        TRUE      NONE
+PPSTACK.UNCONV.EXPWT         OUTPUT {OUTPUT}.unconv.expwt.fits    VARIANCE        EXP        FPA        TRUE      NONE
+PPSTACK.TARGET.PSF           OUTPUT {OUTPUT}.target.psf           PSF             NONE       CHIP       TRUE      NONE
+PPSTACK.CONV.KERNEL          OUTPUT {OUTPUT}.{FILE.INDEX}.kernel  SUBKERNEL       NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG1         OUTPUT {OUTPUT}.b1.jpg               JPEG            NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG2         OUTPUT {OUTPUT}.b2.jpg               JPEG            NONE       FPA        TRUE      NONE
+PPSTACK.CONFIG               OUTPUT {OUTPUT}.ppStack.mdc          TEXT            NONE       FPA        TRUE      NONE
+                                             
+PPSTAMP.OUTPUT               OUTPUT {OUTPUT}.fits                 IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSTAMP.OUTPUT.MASK          OUTPUT {OUTPUT}.mk.fits              MASK            COMP_MASK  FPA        TRUE      NONE
+PPSTAMP.OUTPUT.VARIANCE      OUTPUT {OUTPUT}.wt.fits              VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSTAMP.CHIP                 OUTPUT {OUTPUT}.ch.fits              IMAGE           NONE       CHIP       FALSE     NONE
+                                                     
+PPSIM.OUTPUT                 OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPSIM.FAKE.CHIP              OUTPUT {OUTPUT}.fake.fits            IMAGE           NONE       FPA        TRUE      SIMPLE
+PPSIM.FORCE.CHIP             OUTPUT {OUTPUT}.force.fits           IMAGE           NONE       FPA        TRUE      SIMPLE
+PPSIM.SOURCES                OUTPUT {OUTPUT}.cmf                  CMF             NONE       FPA        TRUE      NONE
+PPSIM.FAKE.SOURCES           OUTPUT {OUTPUT}.fake.cmf             CMF             NONE       FPA        TRUE      NONE
+PPSIM.FORCE.SOURCES          OUTPUT {OUTPUT}.force.cmf            CMF             NONE       FPA        TRUE      NONE
+                                                     
+PPARITH.OUTPUT.IMAGE         OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPARITH.OUTPUT.MASK          OUTPUT {OUTPUT}.fits                 MASK            NONE       FPA        TRUE      SIMPLE
+
+PPSKYCELL.JPEG1              OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg JPEG            NONE       CHIP       TRUE      NONE
+PPSKYCELL.JPEG2              OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg JPEG            NONE       CHIP       TRUE      NONE
+
+LOG.IMFILE                   OUTPUT {OUTPUT}.imfile.log           TEXT            NONE       FPA        TRUE      NONE
+LOG.EXP                      OUTPUT {OUTPUT}.exp.log              TEXT            NONE       FPA        TRUE      NONE
+
+TRACE.IMFILE                 OUTPUT {OUTPUT}.imfile.trace         TEXT            NONE       FPA        TRUE      NONE
+TRACE.EXP                    OUTPUT {OUTPUT}.exp.trace            TEXT            NONE       FPA        TRUE      NONE
+
+PPNOISEMAP.OUTPUT            OUTPUT {OUTPUT}.{CHIP.NAME}.fits     IMAGE           NONE       CHIP       TRUE      NONE
+
+CENSOR.OUTPUT                OUTPUT {OUTPUT}.smf                  CMF             NONE       FPA        TRUE      MEF
+
+MAGIC.ORIGINAL.PNG           OUTPUT {OUTPUT}_original.png         JPEG            NONE       FPA        TRUE      NONE
+MAGIC.RESIDUAL.PNG           OUTPUT {OUTPUT}_residual.png         JPEG            NONE       FPA        TRUE      NONE
+MAGIC.MASK.PNG               OUTPUT {OUTPUT}_mask.png             JPEG            NONE       FPA        TRUE      NONE
+MAGIC.DUPLICATE.PNG          OUTPUT {OUTPUT}_duplicate.png        JPEG            NONE       FPA        TRUE      NONE
+
+PPSMOOTH.OUTPUT              OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      SIMPLE
+PPSMOOTH.OUTPUT.MASK         OUTPUT {OUTPUT}.mk.fits              MASK            NONE       FPA        TRUE      SIMPLE
+PPSMOOTH.OUTPUT.VARIANCE     OUTPUT {OUTPUT}.wt.fits              VARIANCE        NONE       FPA        TRUE      SIMPLE
+
+PPBGRESTORE.OUTPUT           OUTPUT {OUTPUT}.fits                 IMAGE           NONE       FPA        TRUE      NONE
Index: /branches/pap/ippconfig/recipes/filerules-split.mdc
===================================================================
--- /branches/pap/ippconfig/recipes/filerules-split.mdc	(revision 28002)
+++ /branches/pap/ippconfig/recipes/filerules-split.mdc	(revision 28003)
@@ -21,283 +21,302 @@
 ### replace @DETDB with @FILES if you want to require it from the 
 ### command line, or with an explicit name to require a specific file
-TYPE                    INPUT    FILENAME.RULE DATA.LEVEL FILE.TYPE
+TYPE                      INPUT    FILENAME.RULE DATA.LEVEL FILE.TYPE
 
 ## files used by ppImage
-PPIMAGE.INPUT           INPUT    @FILES        CHIP       IMAGE
-PPIMAGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-PPIMAGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
-PPIMAGE.INPUT.PSF       INPUT    @FILES        CHIP       PSF
-PPIMAGE.INPUT.SRC       INPUT    @FILES        CHIP       CMF
-PPIMAGE.MASK            INPUT    @DETDB        CHIP       MASK
-PPIMAGE.BIAS            INPUT    @DETDB        CHIP       IMAGE
-PPIMAGE.NOISEMAP        INPUT    @DETDB        CHIP       IMAGE
-PPIMAGE.DARK            INPUT    @DETDB        CHIP       DARK
-PPIMAGE.FLAT            INPUT    @DETDB        CHIP       IMAGE
-PPIMAGE.FRINGE     	INPUT 	 @DETDB        CHIP       FRINGE
-PPIMAGE.SHUTTER         INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.INPUT             INPUT    @FILES        CHIP       IMAGE
+PPIMAGE.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+PPIMAGE.INPUT.VARIANCE    INPUT    @FILES        CHIP       VARIANCE
+PPIMAGE.INPUT.PSF         INPUT    @FILES        CHIP       PSF
+PPIMAGE.INPUT.SRC         INPUT    @FILES        CHIP       CMF
+PPIMAGE.MASK              INPUT    @DETDB        CHIP       MASK
+PPIMAGE.BIAS              INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.NOISEMAP          INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.DARK              INPUT    @DETDB        CHIP       DARK
+PPIMAGE.FLAT              INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.FRINGE            INPUT    @DETDB        CHIP       FRINGE
+PPIMAGE.SHUTTER           INPUT    @DETDB        CHIP       IMAGE
 
 ## Files used by ppMerge
-PPMERGE.INPUT           INPUT    @FILES        CHIP       IMAGE
-PPMERGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-PPMERGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+PPMERGE.INPUT             INPUT    @FILES        CHIP       IMAGE
+PPMERGE.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+PPMERGE.INPUT.VARIANCE    INPUT    @FILES        CHIP       VARIANCE
 
 ## files used to build and apply the flat-field correction images
-DVOCORR.INPUT      	INPUT 	 @FILES        CHIP       IMAGE
-DVOCORR.REFHEAD    	INPUT 	 @FILES        CHIP       HEADER
-DVOFLAT.INPUT      	INPUT 	 @FILES        CHIP       IMAGE
-DVOFLAT.CORR       	INPUT 	 @DETDB        CHIP       IMAGE
+DVOCORR.INPUT             INPUT    @FILES        CHIP       IMAGE
+DVOCORR.REFHEAD           INPUT    @FILES        CHIP       HEADER
+DVOFLAT.INPUT             INPUT    @FILES        CHIP       IMAGE
+DVOFLAT.CORR              INPUT    @DETDB        CHIP       IMAGE
 
 ## files used by psphot
-PSPHOT.LOAD             INPUT    @FILES        CHIP       IMAGE
-PSPHOT.INPUT            INPUT    @FILES        CHIP       IMAGE
-PSPHOT.MASK             INPUT    @FILES        CHIP       MASK     
-PSPHOT.VARIANCE         INPUT    @FILES        CHIP       VARIANCE     
-PSPHOT.PSF.LOAD         INPUT    @FILES        CHIP       PSF       
-PSPHOT.INPUT.CMF        INPUT    @FILES        CHIP       CMF       
-PSPHOT.INPUT.TEXT       INPUT    @FILES        CHIP       SRCTEXT       
+PSPHOT.LOAD               INPUT    @FILES        CHIP       IMAGE
+PSPHOT.INPUT              INPUT    @FILES        CHIP       IMAGE
+PSPHOT.MASK               INPUT    @FILES        CHIP       MASK     
+PSPHOT.VARIANCE           INPUT    @FILES        CHIP       VARIANCE     
+PSPHOT.PSF.LOAD           INPUT    @FILES        CHIP       PSF       
+PSPHOT.INPUT.CMF          INPUT    @FILES        CHIP       CMF       
+PSPHOT.INPUT.TEXT         INPUT    @FILES        CHIP       SRCTEXT       
+
+## files used by psphotStack
+PSPHOT.STACK.INPUT.RAW    INPUT    @FILES        CHIP       IMAGE
+PSPHOT.STACK.MASK.RAW     INPUT    @FILES        CHIP       MASK     
+PSPHOT.STACK.VARIANCE.RAW INPUT    @FILES        CHIP       VARIANCE     
+PSPHOT.STACK.PSF.RAW      INPUT    @FILES        CHIP       PSF       
+PSPHOT.STACK.INPUT.CNV    INPUT    @FILES        CHIP       IMAGE
+PSPHOT.STACK.MASK.CNV     INPUT    @FILES        CHIP       MASK     
+PSPHOT.STACK.VARIANCE.CNV INPUT    @FILES        CHIP       VARIANCE     
+PSPHOT.STACK.PSF.CNV      INPUT    @FILES        CHIP       PSF       
+PSPHOT.STACK.SOURCES      INPUT    @FILES        FPA        CMF
 
 ## files used by psastro 
-PSASTRO.INPUT.CMP       INPUT    @FILES        CHIP       CMP
-PSASTRO.INPUT.CMF       INPUT    @FILES        CHIP       CMF
-PSASTRO.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-PSASTRO.REFMASK         INPUT    @DETDB        CHIP       MASK
-PSASTRO.WCS             INPUT    @FILES        CHIP       WCS
-PSASTRO.MODEL           INPUT    @DETDB        FPA        ASTROM
-
-PSASTRO.EXTRACT.ASTROM  INPUT    @FILES        CHIP       CMF
-PSASTRO.EXTRACT.INPUT   INPUT    @FILES        CHIP       IMAGE
-
-## files used by pswarp
-PSWARP.INPUT            INPUT    @FILES        CHIP       IMAGE
-PSWARP.VARIANCE         INPUT    @FILES        CHIP       VARIANCE
-PSWARP.MASK             INPUT    @FILES        CHIP       MASK
-PSWARP.SKYCELL          INPUT    @FILES        FPA        IMAGE
-PSWARP.ASTROM           INPUT    @FILES        CHIP       CMF
-
-## files used by ppsub
-PPSUB.INPUT             INPUT    @FILES        FPA        IMAGE
-PPSUB.INPUT.MASK        INPUT    @FILES        FPA        MASK
-PPSUB.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
-PPSUB.INPUT.SOURCES    	INPUT 	 @FILES        FPA        CMF
-PPSUB.REF               INPUT    @FILES        FPA        IMAGE
-PPSUB.REF.MASK          INPUT    @FILES        FPA        MASK
-PPSUB.REF.VARIANCE      INPUT    @FILES        FPA        VARIANCE
-PPSUB.REF.SOURCES    	INPUT 	 @FILES        FPA        CMF
-PPSUB.INPUT.KERNEL      INPUT    @FILES        FPA        SUBKERNEL
-
-## files used by ppstack
-PPSTACK.INPUT           INPUT    @FILES        FPA        IMAGE
-PPSTACK.INPUT.MASK      INPUT    @FILES        FPA        MASK
-PPSTACK.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
-PPSTACK.INPUT.PSF  	INPUT 	 @FILES        CHIP       PSF
-PPSTACK.INPUT.SOURCES   INPUT    @FILES        FPA        CMF
-
-## files used by ppstamp
-PPSTAMP.INPUT           INPUT    @FILES        CHIP       IMAGE
-PPSTAMP.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-PPSTAMP.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
-
-# files used by pparith
-PPARITH.INPUT.IMAGE     INPUT    @FILES        CHIP       IMAGE
-PPARITH.INPUT.MASK      INPUT    @FILES        CHIP       MASK
-
-PPSKYCELL.IMAGE      	INPUT 	 @FILES        CHIP       IMAGE
-PPSKYCELL.MASK      	INPUT 	 @FILES        CHIP       MASK
-
-PPSIM.INPUT             INPUT    @FILES        CHIP       IMAGE     
-PPSIM.REAL.SOURCES      INPUT    @FILES        CHIP       CMF       
+PSASTRO.INPUT.CMP         INPUT    @FILES        CHIP       CMP
+PSASTRO.INPUT.CMF         INPUT    @FILES        CHIP       CMF
+PSASTRO.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+PSASTRO.REFMASK           INPUT    @DETDB        CHIP       MASK
+PSASTRO.WCS               INPUT    @FILES        CHIP       WCS
+PSASTRO.MODEL             INPUT    @DETDB        FPA        ASTROM
+                          
+PSASTRO.EXTRACT.ASTROM    INPUT    @FILES        CHIP       CMF
+PSASTRO.EXTRACT.INPUT     INPUT    @FILES        CHIP       IMAGE
+                          
+## files used by pswarp   
+PSWARP.INPUT              INPUT    @FILES        CHIP       IMAGE
+PSWARP.VARIANCE           INPUT    @FILES        CHIP       VARIANCE
+PSWARP.MASK               INPUT    @FILES        CHIP       MASK
+PSWARP.SKYCELL            INPUT    @FILES        FPA        IMAGE
+PSWARP.ASTROM             INPUT    @FILES        CHIP       CMF
+                          
+## files used by ppsub    
+PPSUB.INPUT               INPUT    @FILES        FPA        IMAGE
+PPSUB.INPUT.MASK          INPUT    @FILES        FPA        MASK
+PPSUB.INPUT.VARIANCE      INPUT    @FILES        FPA        VARIANCE
+PPSUB.INPUT.SOURCES       INPUT    @FILES        FPA        CMF
+PPSUB.INPUT.KERNEL        INPUT    @FILES        FPA        SUBKERNEL
+PPSUB.REF                 INPUT    @FILES        FPA        IMAGE
+PPSUB.REF.MASK            INPUT    @FILES        FPA        MASK
+PPSUB.REF.VARIANCE        INPUT    @FILES        FPA        VARIANCE
+PPSUB.REF.SOURCES         INPUT    @FILES        FPA        CMF
+                          
+## files used by ppstack  
+PPSTACK.INPUT             INPUT    @FILES        FPA        IMAGE
+PPSTACK.INPUT.MASK        INPUT    @FILES        FPA        MASK
+PPSTACK.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
+PPSTACK.INPUT.PSF         INPUT    @FILES        CHIP       PSF
+PPSTACK.INPUT.SOURCES     INPUT    @FILES        FPA        CMF
+                          
+## files used by ppstamp  
+PPSTAMP.INPUT             INPUT    @FILES        CHIP       IMAGE
+PPSTAMP.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+PPSTAMP.INPUT.VARIANCE    INPUT    @FILES        CHIP       VARIANCE
+                          
+# files used by pparith   
+PPARITH.INPUT.IMAGE       INPUT    @FILES        CHIP       IMAGE
+PPARITH.INPUT.MASK        INPUT    @FILES        CHIP       MASK
+                          
+PPSKYCELL.IMAGE           INPUT    @FILES        CHIP       IMAGE
+PPSKYCELL.MASK            INPUT    @FILES        CHIP       MASK
+                          
+PPSIM.INPUT               INPUT    @FILES        CHIP       IMAGE     
+PPSIM.REAL.SOURCES        INPUT    @FILES        CHIP       CMF       
+
+PPCOORD.ASTROM		  INPUT	   @FILES	 FPA	    WCS
+PPCOORD.RAW		  INPUT	   @FILES	 CHIP	    IMAGE
 
 ## files used by ppNoiseMap
-PPNOISEMAP.INPUT        INPUT    @FILES        CHIP       IMAGE
+PPNOISEMAP.INPUT          INPUT    @FILES        CHIP       IMAGE
 
 ## files used by censorObject 
-CENSOR.INPUT       	INPUT    @FILES        CHIP       CMF
-CENSOR.INPUT.MASK       INPUT    @FILES        CHIP       MASK
+CENSOR.INPUT              INPUT    @FILES        CHIP       CMF
+CENSOR.INPUT.MASK         INPUT    @FILES        CHIP       MASK
 
 ## Files used by ppSmooth
-PPSMOOTH.INPUT          INPUT    @FILES        CHIP       IMAGE
-PPSMOOTH.INPUT.MASK     INPUT    @FILES        CHIP       MASK
-PPSMOOTH.INPUT.VARIANCE INPUT    @FILES        CHIP       VARIANCE
+PPSMOOTH.INPUT            INPUT    @FILES        CHIP       IMAGE
+PPSMOOTH.INPUT.MASK       INPUT    @FILES        CHIP       MASK
+PPSMOOTH.INPUT.VARIANCE   INPUT    @FILES        CHIP       VARIANCE
 
 ## Files used by ppbgrestore
-PPBGRESTORE.INPUT       INPUT    @FILES        CHIP       IMAGE
-PPBGRESTORE.BACKMDL     INPUT    @FILES        CHIP       IMAGE
-
-PPVIZPATTERN.INPUT	INPUT	 @FILES	       CHIP	  PATTERN
+PPBGRESTORE.INPUT         INPUT    @FILES        CHIP       IMAGE
+PPBGRESTORE.BACKMDL       INPUT    @FILES        CHIP       IMAGE
+                          
+PPVIZPATTERN.INPUT        INPUT    @FILES        CHIP       PATTERN
 
 ### output file definitions
-TYPE                    OUTPUT FILENAME.RULE                     FILE.TYPE FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
-PPIMAGE.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     COMP_IMG   CHIP       TRUE      NONE
-PPIMAGE.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
-PPIMAGE.OUTPUT.VARIANCE OUTPUT {OUTPUT}.{CHIP.NAME}.wt.fits      VARIANCE  COMP_WT    CHIP       TRUE      NONE
-PPIMAGE.OUTPUT.DETMASK  OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     DET_MASK   CHIP       TRUE      NONE
-PPIMAGE.OUTPUT.DETREND  OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPIMAGE.OUTPUT.RESID    OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPIMAGE.CONFIG          OUTPUT {OUTPUT}.{CHIP.NAME}.ppImage.mdc  TEXT      NONE       CHIP       TRUE      NONE
-	        									        
-PPIMAGE.CHIP            OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     COMP_IMG   CHIP       TRUE      NONE
-PPIMAGE.CHIP.DETMASK    OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     NONE       CHIP       TRUE      NONE
-PPIMAGE.CHIP.MASK       OUTPUT {OUTPUT}.{CHIP.NAME}.ch.mk.fits   MASK      COMP_MASK  CHIP       TRUE      NONE
-PPIMAGE.CHIP.VARIANCE   OUTPUT {OUTPUT}.{CHIP.NAME}.ch.wt.fits   VARIANCE  COMP_WT    CHIP       TRUE      NONE
-PPIMAGE.CHIP.RESID      OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     NONE       CHIP       TRUE      NONE
-		        									        
-PPIMAGE.OUTPUT.FPA1     OUTPUT {OUTPUT}.b1.fits                  IMAGE     NONE       FPA        TRUE      NONE
-PPIMAGE.OUTPUT.FPA2     OUTPUT {OUTPUT}.b2.fits                  IMAGE     NONE       FPA        TRUE      NONE
-		        									        
-PPIMAGE.BIN1            OUTPUT {OUTPUT}.{CHIP.NAME}.b1.fits      IMAGE     NONE       CHIP       TRUE      NONE
-PPIMAGE.BIN2            OUTPUT {OUTPUT}.{CHIP.NAME}.b2.fits      IMAGE     NONE       CHIP       TRUE      NONE
-		        									        
-PPIMAGE.JPEG1           OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
-PPIMAGE.JPEG2           OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
-PPIMAGE.PATTERN		OUTPUT {OUTPUT}.{CHIP.NAME}.ptn		 PATTERN   NONE	      CHIP	 TRUE	   NONE
-PPIMAGE.STATS           OUTPUT {OUTPUT}.{CHIP.NAME}.stats        STATS     NONE       CHIP       TRUE      NONE
+TYPE                         OUTPUT FILENAME.RULE                     FILE.TYPE       FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
+PPIMAGE.OUTPUT               OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           COMP_IMG   CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.MASK          OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK            COMP_MASK  CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.VARIANCE      OUTPUT {OUTPUT}.{CHIP.NAME}.wt.fits      VARIANCE        COMP_WT    CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.DETMASK       OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           DET_MASK   CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.DETREND       OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.RESID         OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPIMAGE.CONFIG               OUTPUT {OUTPUT}.{CHIP.NAME}.ppImage.mdc  TEXT            NONE       CHIP       TRUE      NONE
+                                                                                                      
+PPIMAGE.CHIP                 OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE           COMP_IMG   CHIP       TRUE      NONE
+PPIMAGE.CHIP.DETMASK         OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE           NONE       CHIP       TRUE      NONE
+PPIMAGE.CHIP.MASK            OUTPUT {OUTPUT}.{CHIP.NAME}.ch.mk.fits   MASK            COMP_MASK  CHIP       TRUE      NONE
+PPIMAGE.CHIP.VARIANCE        OUTPUT {OUTPUT}.{CHIP.NAME}.ch.wt.fits   VARIANCE        COMP_WT    CHIP       TRUE      NONE
+PPIMAGE.CHIP.RESID           OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE           NONE       CHIP       TRUE      NONE
+                                                                                                              
+PPIMAGE.OUTPUT.FPA1          OUTPUT {OUTPUT}.b1.fits                  IMAGE           NONE       FPA        TRUE      NONE
+PPIMAGE.OUTPUT.FPA2          OUTPUT {OUTPUT}.b2.fits                  IMAGE           NONE       FPA        TRUE      NONE
+                                                                                                              
+PPIMAGE.BIN1                 OUTPUT {OUTPUT}.{CHIP.NAME}.b1.fits      IMAGE           NONE       CHIP       TRUE      NONE
+PPIMAGE.BIN2                 OUTPUT {OUTPUT}.{CHIP.NAME}.b2.fits      IMAGE           NONE       CHIP       TRUE      NONE
+                                                                                                              
+PPIMAGE.JPEG1                OUTPUT {OUTPUT}.b1.jpg                   JPEG            NONE       FPA        TRUE      NONE
+PPIMAGE.JPEG2                OUTPUT {OUTPUT}.b2.jpg                   JPEG            NONE       FPA        TRUE      NONE
+PPIMAGE.PATTERN              OUTPUT {OUTPUT}.{CHIP.NAME}.ptn          PATTERN         NONE       CHIP       TRUE      NONE
+PPIMAGE.STATS                OUTPUT {OUTPUT}.{CHIP.NAME}.stats        STATS           NONE       CHIP       TRUE      NONE
 
 ## note: these use the  same output naming convention since they are used for different ppMerge runs
-PPMERGE.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         MASK      DET_MASK   CHIP       TRUE      NONE
-PPMERGE.OUTPUT.BIAS     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPMERGE.OUTPUT.DARK     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         DARK      NONE       CHIP       TRUE      NONE
-PPMERGE.OUTPUT.SHUTTER  OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPMERGE.OUTPUT.FLAT     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPMERGE.OUTPUT.FRINGE   OUTPUT {OUTPUT}.{CHIP.NAME}.fits         FRINGE    NONE       CELL       TRUE      NONE
-PPMERGE.OUTPUT.SIGMA    OUTPUT {OUTPUT}.{CHIP.NAME}.sigma.fits   IMAGE     NONE       CELL       TRUE      NONE
-PPMERGE.OUTPUT.COUNT    OUTPUT {OUTPUT}.{CHIP.NAME}.count.fits   IMAGE     NONE       CELL       TRUE      NONE
-		        									        
-DVOCORR.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.fc.fits      IMAGE     NONE       CHIP       TRUE      NONE
-DVOFLAT.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.co.fits      IMAGE     NONE       CHIP       TRUE      NONE
-		        									        
-PSPHOT.RESID            OUTPUT {OUTPUT}.{CHIP.NAME}.res.fits     IMAGE     COMP_SUB   CHIP       TRUE      NONE
-PSPHOT.BACKGND          OUTPUT {OUTPUT}.{CHIP.NAME}.bck.fits     IMAGE     COMP_IMG   CHIP       TRUE      NONE
-PSPHOT.BACKSUB          OUTPUT {OUTPUT}.{CHIP.NAME}.sub.fits     IMAGE     COMP_SUB   CHIP       TRUE      NONE
-PSPHOT.BACKMDL          OUTPUT {OUTPUT}.{CHIP.NAME}.mdl.fits     IMAGE     NONE       CHIP       TRUE      NONE
-PSPHOT.BACKMDL.MEF      OUTPUT {OUTPUT}.mdl.fits                 IMAGE     NONE       CHIP       TRUE      NONE
-		        									        
-PSPHOT.OUTPUT.RAW       OUTPUT {OUTPUT}.{CHIP.NAME}              RAW       NONE       CHIP       TRUE      NONE
-PSPHOT.OUTPUT.SX        OUTPUT {OUTPUT}.{CHIP.NAME}.sx           SX        NONE       CHIP       TRUE      NONE
-PSPHOT.OUTPUT.OBJ       OUTPUT {OUTPUT}.{CHIP.NAME}.obj          OBJ       NONE       CHIP       TRUE      NONE
-PSPHOT.OUTPUT.CMP       OUTPUT {OUTPUT}.{CHIP.NAME}.cmp          CMP       NONE       CHIP       TRUE      NONE
-PSPHOT.OUT.CMF.SPL      OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF       NONE       CHIP       TRUE      NONE
-PSPHOT.OUT.CMF.MEF      OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      MEF
-PSPHOT.PSF.RAW.SAVE     OUTPUT {OUTPUT}.{CHIP.NAME}.psf          PSF       NONE       CHIP       TRUE      MEF
-PSPHOT.PSF.SKY.SAVE     OUTPUT {OUTPUT}.psf          		 PSF       NONE       FPA        TRUE      MEF
-		        									        
+PPMERGE.OUTPUT.MASK          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         MASK            DET_MASK   CHIP       TRUE      NONE
+PPMERGE.OUTPUT.BIAS          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.DARK          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         DARK            NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.SHUTTER       OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.FLAT          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.FRINGE        OUTPUT {OUTPUT}.{CHIP.NAME}.fits         FRINGE          NONE       CELL       TRUE      NONE
+PPMERGE.OUTPUT.SIGMA         OUTPUT {OUTPUT}.{CHIP.NAME}.sigma.fits   IMAGE           NONE       CELL       TRUE      NONE
+PPMERGE.OUTPUT.COUNT         OUTPUT {OUTPUT}.{CHIP.NAME}.count.fits   IMAGE           NONE       CELL       TRUE      NONE
+                                                                                                              
+DVOCORR.OUTPUT               OUTPUT {OUTPUT}.{CHIP.NAME}.fc.fits      IMAGE           NONE       CHIP       TRUE      NONE
+DVOFLAT.OUTPUT               OUTPUT {OUTPUT}.{CHIP.NAME}.co.fits      IMAGE           NONE       CHIP       TRUE      NONE
+                                                                                                              
+PSPHOT.RESID                 OUTPUT {OUTPUT}.{CHIP.NAME}.res.fits     IMAGE           COMP_SUB   CHIP       TRUE      NONE
+PSPHOT.BACKGND               OUTPUT {OUTPUT}.{CHIP.NAME}.bck.fits     IMAGE           COMP_IMG   CHIP       TRUE      NONE
+PSPHOT.BACKSUB               OUTPUT {OUTPUT}.{CHIP.NAME}.sub.fits     IMAGE           COMP_SUB   CHIP       TRUE      NONE
+PSPHOT.BACKMDL               OUTPUT {OUTPUT}.{CHIP.NAME}.mdl.fits     IMAGE           NONE       CHIP       TRUE      NONE
+PSPHOT.BACKMDL.MEF           OUTPUT {OUTPUT}.mdl.fits                 IMAGE           NONE       CHIP       TRUE      NONE
+                                                                                                              
+PSPHOT.OUTPUT.RAW            OUTPUT {OUTPUT}.{CHIP.NAME}              RAW             NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.SX             OUTPUT {OUTPUT}.{CHIP.NAME}.sx           SX              NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.OBJ            OUTPUT {OUTPUT}.{CHIP.NAME}.obj          OBJ             NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.CMP            OUTPUT {OUTPUT}.{CHIP.NAME}.cmp          CMP             NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.SPL           OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF             NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.MEF           OUTPUT {OUTPUT}.cmf                      CMF             NONE       FPA        TRUE      MEF
+PSPHOT.PSF.RAW.SAVE          OUTPUT {OUTPUT}.{CHIP.NAME}.psf          PSF             NONE       CHIP       TRUE      MEF
+PSPHOT.PSF.SKY.SAVE          OUTPUT {OUTPUT}.psf                      PSF             NONE       FPA        TRUE      MEF
+                                                                                                              
 # outputs for psphotStack:
-PSPHOT.CHISQ.IMAGE      OUTPUT {OUTPUT}.chisq.im.fits IMAGE    NONE       FPA        TRUE      SIMPLE
-PSPHOT.CHISQ.MASK       OUTPUT {OUTPUT}.chisq.mk.fits MASK     NONE       FPA        TRUE      SIMPLE
-PSPHOT.CHISQ.VARIANCE   OUTPUT {OUTPUT}.chisq.wt.fits VARIANCE NONE       FPA        TRUE      SIMPLE
-PSPHOT.STACK.OUTPUT     OUTPUT {OUTPUT}.{FILE.ID}.cmf CMF      NONE       FPA        TRUE      NONE
+PSPHOT.CHISQ.IMAGE           OUTPUT {OUTPUT}.chisq.im.fits            IMAGE           NONE       FPA        TRUE      NONE
+PSPHOT.CHISQ.MASK            OUTPUT {OUTPUT}.chisq.mk.fits            MASK            NONE       FPA        TRUE      NONE
+PSPHOT.CHISQ.VARIANCE        OUTPUT {OUTPUT}.chisq.wt.fits            VARIANCE        NONE       FPA        TRUE      NONE
+PSPHOT.STACK.OUTPUT.IMAGE    OUTPUT {OUTPUT}.{FILE.ID}.im.fits        IMAGE           NONE       FPA        TRUE      NONE
+PSPHOT.STACK.OUTPUT.MASK     OUTPUT {OUTPUT}.{FILE.ID}.mk.fits        MASK            NONE       FPA        TRUE      NONE
+PSPHOT.STACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.{FILE.ID}.wt.fits        VARIANCE        NONE       FPA        TRUE      NONE
+PSPHOT.STACK.OUTPUT          OUTPUT {OUTPUT}.{FILE.ID}.cmf            CMF             NONE       FPA        TRUE      NONE
                                                      
-SOURCE.PLOT.RAW.MOMENTS  OUTPUT {OUTPUT}.{CHIP.NAME}.mnt.png      KAPA      NONE       CHIP       TRUE      NONE
-SOURCE.PLOT.RAW.PSFMODEL OUTPUT {OUTPUT}.{CHIP.NAME}.psf.png      KAPA      NONE       CHIP       TRUE      NONE
-SOURCE.PLOT.RAW.APRESID  OUTPUT {OUTPUT}.{CHIP.NAME}.dap.png      KAPA      NONE       CHIP       TRUE      NONE
-		        									        
-SOURCE.PLOT.SKY.MOMENTS  OUTPUT {OUTPUT}.mnt.png      KAPA      NONE       CHIP       TRUE      NONE
-SOURCE.PLOT.SKY.PSFMODEL OUTPUT {OUTPUT}.psf.png      KAPA      NONE       CHIP       TRUE      NONE
-SOURCE.PLOT.SKY.APRESID  OUTPUT {OUTPUT}.dap.png      KAPA      NONE       CHIP       TRUE      NONE
-
-# PSASTRO.OUTPUT.CMP      OUTPUT {OUTPUT}.{CHIP.NAME}.smp          CMP       NONE       CHIP       TRUE      NONE
-# PSASTRO.OUT.CMF.SPL     OUTPUT {OUTPUT}.{CHIP.NAME}.smf          CMF       NONE       CHIP       TRUE      NONE
-# PSASTRO.OUT.CMF.MEF     OUTPUT {OUTPUT}.smf                      CMF       NONE       FPA        TRUE      MEF
-PSASTRO.OUT.MODEL       OUTPUT {OUTPUT}.asm               ASTROM.MODEL     NONE       FPA        TRUE      NONE
-PSASTRO.OUT.REFSTARS    OUTPUT {OUTPUT}.aref.fits         ASTROM.REFSTARS  NONE       FPA        TRUE      NONE
-PSASTRO.OUTPUT          OUTPUT {OUTPUT}.smf                      CMF       NONE       FPA        TRUE      MEF
-PSASTRO.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      NONE
-PSASTRO.CONFIG          OUTPUT {OUTPUT}.psastro.mdc              TEXT      NONE       FPA        TRUE      NONE
-PSASTRO.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
-		        									        
-PSWARP.OUTPUT           OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
-PSWARP.OUTPUT.MASK      OUTPUT {OUTPUT}.mask.fits                MASK      COMP_MASK  FPA        TRUE      NONE
-PSWARP.OUTPUT.VARIANCE  OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
-PSWARP.OUTPUT.SOURCES   OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
-PSWARP.BIN1             OUTPUT {OUTPUT}.b1.fits                  IMAGE     NONE       FPA        TRUE      NONE
-PSWARP.BIN2             OUTPUT {OUTPUT}.b2.fits                  IMAGE     NONE       FPA        TRUE      NONE
-PSWARP.CONFIG           OUTPUT {OUTPUT}.pswarp.mdc               TEXT      NONE       FPA        TRUE      NONE
-		        									        
-SKYCELL.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      NONE
-SKYCELL.TEMPLATE        OUTPUT {OUTPUT}.skycell                  SKYCELL   NONE       FPA        TRUE      NONE
-		        									        
-PPSUB.OUTPUT            OUTPUT {OUTPUT}.fits                     IMAGE     COMP_SUB   FPA        TRUE      NONE
-PPSUB.OUTPUT.MASK       OUTPUT {OUTPUT}.mask.fits                MASK      COMP_MASK  FPA        TRUE      NONE
-PPSUB.OUTPUT.VARIANCE   OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSUB.OUTPUT.SOURCES    OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.KERNELS    OUTPUT {OUTPUT}.subkernel                SUBKERNEL NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.JPEG1      OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.JPEG2      OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
-PPSUB.OUTPUT.RESID.JPEG OUTPUT {OUTPUT}.res.jpg                  JPEG      NONE       FPA        TRUE      NONE
-PPSUB.INVERSE           OUTPUT {OUTPUT}.inv.fits                 IMAGE     COMP_SUB   FPA        TRUE      NONE
-PPSUB.INVERSE.MASK      OUTPUT {OUTPUT}.inv.mask.fits            MASK      COMP_MASK  FPA        TRUE      NONE
-PPSUB.INVERSE.VARIANCE  OUTPUT {OUTPUT}.inv.wt.fits              VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSUB.INVERSE.SOURCES   OUTPUT {OUTPUT}.inv.cmf                  CMF       NONE       FPA        TRUE      NONE
-PPSUB.CONFIG            OUTPUT {OUTPUT}.ppSub.mdc                TEXT      NONE       FPA        TRUE      NONE
-PPSUB.INPUT.CONV        OUTPUT {OUTPUT}.inConv.fits              IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSUB.INPUT.CONV.MASK   OUTPUT {OUTPUT}.inConv.mk.fits           MASK      COMP_MASK  FPA        TRUE      NONE
-PPSUB.INPUT.CONV.VARIANCE OUTPUT {OUTPUT}.inConv.wt.fits         VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSUB.REF.CONV          OUTPUT {OUTPUT}.refConv.fits             IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSUB.REF.CONV.MASK     OUTPUT {OUTPUT}.refConv.mk.fits          MASK      COMP_MASK  FPA        TRUE      NONE
-PPSUB.REF.CONV.VARIANCE OUTPUT {OUTPUT}.refConv.wt.fits          VARIANCE  COMP_WT    FPA        TRUE      NONE
-											        
-PPSTACK.OUTPUT          OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSTACK.OUTPUT.MASK     OUTPUT {OUTPUT}.mask.fits                MASK      COMP_MASK  FPA        TRUE      NONE
-PPSTACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSTACK.OUTPUT.EXP	OUTPUT {OUTPUT}.exp.fits     		 IMAGE     EXP	      FPA	 TRUE      NONE
-PPSTACK.OUTPUT.EXPNUM	OUTPUT {OUTPUT}.num.fits     		 MASK      EXPNUM     FPA	 TRUE      NONE
-PPSTACK.OUTPUT.EXPWT	OUTPUT {OUTPUT}.expwt.fits               VARIANCE  EXP	      FPA	 TRUE      NONE
-PPSTACK.UNCONV          OUTPUT {OUTPUT}.unconv.fits              IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSTACK.UNCONV.MASK     OUTPUT {OUTPUT}.unconv.mask.fits         MASK      COMP_MASK  FPA        TRUE      NONE
-PPSTACK.UNCONV.VARIANCE OUTPUT {OUTPUT}.unconv.wt.fits           VARIANCE  COMP_WT    FPA        TRUE      NONE
-PPSTACK.UNCONV.EXP	OUTPUT {OUTPUT}.unconv.exp.fits 	 IMAGE     EXP	      FPA	 TRUE      NONE
-PPSTACK.UNCONV.EXPNUM	OUTPUT {OUTPUT}.unconv.num.fits 	 MASK  	   EXPNUM     FPA	 TRUE      NONE
-PPSTACK.UNCONV.EXPWT	OUTPUT {OUTPUT}.unconv.expwt.fits        VARIANCE  EXP	      FPA	 TRUE      NONE
-PPSTACK.TARGET.PSF      OUTPUT {OUTPUT}.target.psf               PSF       NONE       CHIP       TRUE      NONE
-PPSTACK.CONV.KERNEL     OUTPUT {OUTPUT}.{FILE.INDEX}.kernel      SUBKERNEL NONE       FPA        TRUE      NONE
-PPSTACK.OUTPUT.JPEG1	OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
-PPSTACK.OUTPUT.JPEG2	OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
-PPSTACK.CONFIG          OUTPUT {OUTPUT}.ppStack.mdc              TEXT      NONE       FPA        TRUE      NONE
-
-PPSTAMP.OUTPUT          OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
-PPSTAMP.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  FPA        TRUE      NONE
-PPSTAMP.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+SOURCE.PLOT.RAW.MOMENTS      OUTPUT {OUTPUT}.{CHIP.NAME}.mnt.png      KAPA            NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.RAW.PSFMODEL     OUTPUT {OUTPUT}.{CHIP.NAME}.psf.png      KAPA            NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.RAW.APRESID      OUTPUT {OUTPUT}.{CHIP.NAME}.dap.png      KAPA            NONE       CHIP       TRUE      NONE
+                                                                                                              
+SOURCE.PLOT.SKY.MOMENTS      OUTPUT {OUTPUT}.mnt.png                  KAPA            NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.SKY.PSFMODEL     OUTPUT {OUTPUT}.psf.png                  KAPA            NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.SKY.APRESID      OUTPUT {OUTPUT}.dap.png                  KAPA            NONE       CHIP       TRUE      NONE
+
+# PSASTRO.OUTPUT.CMP         OUTPUT {OUTPUT}.{CHIP.NAME}.smp          CMP             NONE       CHIP       TRUE      NONE
+# PSASTRO.OUT.CMF.SPL        OUTPUT {OUTPUT}.{CHIP.NAME}.smf          CMF             NONE       CHIP       TRUE      NONE
+# PSASTRO.OUT.CMF.MEF        OUTPUT {OUTPUT}.smf                      CMF             NONE       FPA        TRUE      MEF
+PSASTRO.OUT.MODEL            OUTPUT {OUTPUT}.asm                      ASTROM.MODEL    NONE       FPA        TRUE      NONE
+PSASTRO.OUT.REFSTARS         OUTPUT {OUTPUT}.aref.fits                ASTROM.REFSTARS NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT               OUTPUT {OUTPUT}.smf                      CMF             NONE       FPA        TRUE      MEF
+PSASTRO.STATS                OUTPUT {OUTPUT}.stats                    STATS           NONE       FPA        TRUE      NONE
+PSASTRO.CONFIG               OUTPUT {OUTPUT}.psastro.mdc              TEXT            NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.MASK          OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK            COMP_MASK  CHIP       TRUE      NONE
+                                                                                                              
+PSWARP.OUTPUT                OUTPUT {OUTPUT}.fits                     IMAGE           COMP_IMG   FPA        TRUE      NONE
+PSWARP.OUTPUT.MASK           OUTPUT {OUTPUT}.mask.fits                MASK            COMP_MASK  FPA        TRUE      NONE
+PSWARP.OUTPUT.VARIANCE       OUTPUT {OUTPUT}.wt.fits                  VARIANCE        COMP_WT    FPA        TRUE      NONE
+PSWARP.OUTPUT.SOURCES        OUTPUT {OUTPUT}.cmf                      CMF             NONE       FPA        TRUE      NONE
+PSWARP.BIN1                  OUTPUT {OUTPUT}.b1.fits                  IMAGE           NONE       FPA        TRUE      NONE
+PSWARP.BIN2                  OUTPUT {OUTPUT}.b2.fits                  IMAGE           NONE       FPA        TRUE      NONE
+PSWARP.CONFIG                OUTPUT {OUTPUT}.pswarp.mdc               TEXT            NONE       FPA        TRUE      NONE
+                                                                                                              
+SKYCELL.STATS                OUTPUT {OUTPUT}.stats                    STATS           NONE       FPA        TRUE      NONE
+SKYCELL.TEMPLATE             OUTPUT {OUTPUT}.skycell                  SKYCELL         NONE       FPA        TRUE      NONE
+                                                                                                              
+PPSUB.OUTPUT                 OUTPUT {OUTPUT}.fits                     IMAGE           COMP_SUB   FPA        TRUE      NONE
+PPSUB.OUTPUT.MASK            OUTPUT {OUTPUT}.mask.fits                MASK            COMP_MASK  FPA        TRUE      NONE
+PPSUB.OUTPUT.VARIANCE        OUTPUT {OUTPUT}.wt.fits                  VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSUB.OUTPUT.SOURCES         OUTPUT {OUTPUT}.cmf                      CMF             NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.KERNELS         OUTPUT {OUTPUT}.subkernel                SUBKERNEL       NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG1           OUTPUT {OUTPUT}.b1.jpg                   JPEG            NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG2           OUTPUT {OUTPUT}.b2.jpg                   JPEG            NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.RESID.JPEG      OUTPUT {OUTPUT}.res.jpg                  JPEG            NONE       FPA        TRUE      NONE
+PPSUB.INVERSE                OUTPUT {OUTPUT}.inv.fits                 IMAGE           COMP_SUB   FPA        TRUE      NONE
+PPSUB.INVERSE.MASK           OUTPUT {OUTPUT}.inv.mask.fits            MASK            COMP_MASK  FPA        TRUE      NONE
+PPSUB.INVERSE.VARIANCE       OUTPUT {OUTPUT}.inv.wt.fits              VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSUB.INVERSE.SOURCES        OUTPUT {OUTPUT}.inv.cmf                  CMF             NONE       FPA        TRUE      NONE
+PPSUB.CONFIG                 OUTPUT {OUTPUT}.ppSub.mdc                TEXT            NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV             OUTPUT {OUTPUT}.inConv.fits              IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSUB.INPUT.CONV.MASK        OUTPUT {OUTPUT}.inConv.mk.fits           MASK            COMP_MASK  FPA        TRUE      NONE
+PPSUB.INPUT.CONV.VARIANCE    OUTPUT {OUTPUT}.inConv.wt.fits           VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSUB.REF.CONV               OUTPUT {OUTPUT}.refConv.fits             IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSUB.REF.CONV.MASK          OUTPUT {OUTPUT}.refConv.mk.fits          MASK            COMP_MASK  FPA        TRUE      NONE
+PPSUB.REF.CONV.VARIANCE      OUTPUT {OUTPUT}.refConv.wt.fits          VARIANCE        COMP_WT    FPA        TRUE      NONE
+                                                                                                      
+PPSTACK.OUTPUT               OUTPUT {OUTPUT}.fits                     IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSTACK.OUTPUT.MASK          OUTPUT {OUTPUT}.mask.fits                MASK            COMP_MASK  FPA        TRUE      NONE
+PPSTACK.OUTPUT.VARIANCE      OUTPUT {OUTPUT}.wt.fits                  VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSTACK.OUTPUT.EXP           OUTPUT {OUTPUT}.exp.fits                 IMAGE           EXP        FPA        TRUE      NONE
+PPSTACK.OUTPUT.EXPNUM        OUTPUT {OUTPUT}.num.fits                 MASK            EXPNUM     FPA        TRUE      NONE
+PPSTACK.OUTPUT.EXPWT         OUTPUT {OUTPUT}.expwt.fits               VARIANCE        EXP        FPA        TRUE      NONE
+PPSTACK.UNCONV               OUTPUT {OUTPUT}.unconv.fits              IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSTACK.UNCONV.MASK          OUTPUT {OUTPUT}.unconv.mask.fits         MASK            COMP_MASK  FPA        TRUE      NONE
+PPSTACK.UNCONV.VARIANCE      OUTPUT {OUTPUT}.unconv.wt.fits           VARIANCE        COMP_WT    FPA        TRUE      NONE
+PPSTACK.UNCONV.EXP           OUTPUT {OUTPUT}.unconv.exp.fits          IMAGE           EXP        FPA        TRUE      NONE
+PPSTACK.UNCONV.EXPNUM        OUTPUT {OUTPUT}.unconv.num.fits          MASK            EXPNUM     FPA        TRUE      NONE
+PPSTACK.UNCONV.EXPWT         OUTPUT {OUTPUT}.unconv.expwt.fits        VARIANCE        EXP        FPA        TRUE      NONE
+PPSTACK.TARGET.PSF           OUTPUT {OUTPUT}.target.psf               PSF             NONE       CHIP       TRUE      NONE
+PPSTACK.CONV.KERNEL          OUTPUT {OUTPUT}.{FILE.INDEX}.kernel      SUBKERNEL       NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG1         OUTPUT {OUTPUT}.b1.jpg                   JPEG            NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG2         OUTPUT {OUTPUT}.b2.jpg                   JPEG            NONE       FPA        TRUE      NONE
+PPSTACK.CONFIG               OUTPUT {OUTPUT}.ppStack.mdc              TEXT            NONE       FPA        TRUE      NONE
+
+PPSTAMP.OUTPUT               OUTPUT {OUTPUT}.fits                     IMAGE           COMP_IMG   FPA        TRUE      NONE
+PPSTAMP.OUTPUT.MASK          OUTPUT {OUTPUT}.mk.fits                  MASK            COMP_MASK  FPA        TRUE      NONE
+PPSTAMP.OUTPUT.VARIANCE      OUTPUT {OUTPUT}.wt.fits                  VARIANCE        COMP_WT    FPA        TRUE      NONE
 # mosaic image used for making stamps of raw images. Not saved.
-PPSTAMP.CHIP            OUTPUT {OUTPUT}.ch.fits                  IMAGE     NONE       CHIP       FALSE     MEF
-PPSTAMP.OUTPUT.JPEG1    OUTPUT {OUTPUT}.jpg                      JPEG      NONE       FPA        TRUE      NONE
-		        									        
-PPSIM.OUTPUT            OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      SPLIT
-PPSIM.FAKE.CHIP        	OUTPUT {OUTPUT}.{CHIP.NAME}.fake.fits    IMAGE     NONE       CHIP       TRUE      NONE
-PPSIM.FORCE.CHIP       	OUTPUT {OUTPUT}.{CHIP.NAME}.force.fits   IMAGE     NONE       CHIP       TRUE      NONE
-PPSIM.SOURCES           OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF       NONE       CHIP       TRUE      NONE
-PPSIM.FAKE.SOURCES     	OUTPUT {OUTPUT}.{CHIP.NAME}.fake.cmf     CMF       NONE       CHIP       TRUE      NONE
-PPSIM.FORCE.SOURCES    	OUTPUT {OUTPUT}.{CHIP.NAME}.force.cmf    CMF       NONE       CHIP       TRUE      NONE
-
-PPARITH.OUTPUT.IMAGE   	OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   CHIP       TRUE      NONE
-PPARITH.OUTPUT.MASK    	OUTPUT {OUTPUT}.fits                     MASK      COMP_MASK  CHIP       TRUE      NONE
-		       										        
-PPSKYCELL.JPEG1    	OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg     JPEG      NONE       CHIP       TRUE      NONE
-PPSKYCELL.JPEG2    	OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg     JPEG      NONE       CHIP       TRUE      NONE
-
-LOG.IMFILE             	OUTPUT {OUTPUT}.{CHIP.NAME}.log          TEXT      NONE       CHIP       TRUE      NONE
-LOG.EXP                	OUTPUT {OUTPUT}.log                      TEXT      NONE       FPA        TRUE      NONE
-		       										        
-TRACE.IMFILE           	OUTPUT {OUTPUT}.{CHIP.NAME}.trace        TEXT      NONE       CHIP       TRUE      NONE
-TRACE.EXP              	OUTPUT {OUTPUT}.trace                    TEXT      NONE       FPA        TRUE      NONE
-
-PPNOISEMAP.OUTPUT       OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-
-CENSOR.OUTPUT           OUTPUT {OUTPUT}.smf                      CMF       NONE       FPA        TRUE      MEF
-
-MAGIC.ORIGINAL.PNG      OUTPUT {OUTPUT}_original.png             JPEG      NONE       FPA        TRUE      NONE
-MAGIC.RESIDUAL.PNG      OUTPUT {OUTPUT}_residual.png             JPEG      NONE       FPA        TRUE      NONE
-MAGIC.MASK.PNG          OUTPUT {OUTPUT}_mask.png                 JPEG      NONE       FPA        TRUE      NONE
-MAGIC.DUPLICATE.PNG     OUTPUT {OUTPUT}_duplicate.png            JPEG      NONE       FPA        TRUE      NONE
-
-PPSMOOTH.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.fits        IMAGE     NONE       CHIP       TRUE      MEF
-PPSMOOTH.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits     MASK      NONE       CHIP       TRUE      MEF
-PPSMOOTH.OUTPUT.VARIANCE OUTPUT {OUTPUT}.{CHIP.NAME}.wt.fits     VARIANCE  NONE       CHIP       TRUE      MEF
-
-PPBGRESTORE.OUTPUT      OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPBGRESTORE.BACKGROUND  OUTPUT {OUTPUT}.{CHIP.NAME}.bg.fits      IMAGE     NONE       CHIP       FALSE      NONE
-
-PPVIZPSF.OUTPUT		OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
-PPVIZPATTERN.OUTPUT	OUTPUT {OUTPUT}.{CHIP.NAME}.fits	 IMAGE	   NONE	      CHIP	 TRUE	   NONE
-PPVIZPATTERN.CHIP	OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits	 IMAGE	   NONE	      CHIP	 TRUE	   NONE
-
+PPSTAMP.CHIP                 OUTPUT {OUTPUT}.ch.fits                  IMAGE           NONE       CHIP       FALSE     MEF
+PPSTAMP.OUTPUT.JPEG1         OUTPUT {OUTPUT}.jpg                      JPEG            NONE       FPA        TRUE      NONE
+                                                                                                              
+PPSIM.OUTPUT                 OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      SPLIT
+PPSIM.FAKE.CHIP              OUTPUT {OUTPUT}.{CHIP.NAME}.fake.fits    IMAGE           NONE       CHIP       TRUE      NONE
+PPSIM.FORCE.CHIP             OUTPUT {OUTPUT}.{CHIP.NAME}.force.fits   IMAGE           NONE       CHIP       TRUE      NONE
+PPSIM.SOURCES                OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF             NONE       CHIP       TRUE      NONE
+PPSIM.FAKE.SOURCES           OUTPUT {OUTPUT}.{CHIP.NAME}.fake.cmf     CMF             NONE       CHIP       TRUE      NONE
+PPSIM.FORCE.SOURCES          OUTPUT {OUTPUT}.{CHIP.NAME}.force.cmf    CMF             NONE       CHIP       TRUE      NONE
+
+PPARITH.OUTPUT.IMAGE         OUTPUT {OUTPUT}.fits                     IMAGE           COMP_IMG   CHIP       TRUE      NONE
+PPARITH.OUTPUT.MASK          OUTPUT {OUTPUT}.fits                     MASK            COMP_MASK  CHIP       TRUE      NONE
+                                                                                                        
+PPSKYCELL.JPEG1              OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg     JPEG            NONE       CHIP       TRUE      NONE
+PPSKYCELL.JPEG2              OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg     JPEG            NONE       CHIP       TRUE      NONE
+
+LOG.IMFILE                   OUTPUT {OUTPUT}.{CHIP.NAME}.log          TEXT            NONE       CHIP       TRUE      NONE
+LOG.EXP                      OUTPUT {OUTPUT}.log                      TEXT            NONE       FPA        TRUE      NONE
+                                                                                                              
+TRACE.IMFILE                 OUTPUT {OUTPUT}.{CHIP.NAME}.trace        TEXT            NONE       CHIP       TRUE      NONE
+TRACE.EXP                    OUTPUT {OUTPUT}.trace                    TEXT            NONE       FPA        TRUE      NONE
+
+PPNOISEMAP.OUTPUT            OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+
+CENSOR.OUTPUT                OUTPUT {OUTPUT}.smf                      CMF             NONE       FPA        TRUE      MEF
+
+MAGIC.ORIGINAL.PNG           OUTPUT {OUTPUT}_original.png             JPEG            NONE       FPA        TRUE      NONE
+MAGIC.RESIDUAL.PNG           OUTPUT {OUTPUT}_residual.png             JPEG            NONE       FPA        TRUE      NONE
+MAGIC.MASK.PNG               OUTPUT {OUTPUT}_mask.png                 JPEG            NONE       FPA        TRUE      NONE
+MAGIC.DUPLICATE.PNG          OUTPUT {OUTPUT}_duplicate.png            JPEG            NONE       FPA        TRUE      NONE
+
+PPSMOOTH.OUTPUT              OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      MEF
+PPSMOOTH.OUTPUT.MASK         OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK            NONE       CHIP       TRUE      MEF
+PPSMOOTH.OUTPUT.VARIANCE     OUTPUT {OUTPUT}.{CHIP.NAME}.wt.fits      VARIANCE        NONE       CHIP       TRUE      MEF
+
+PPBGRESTORE.OUTPUT           OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPBGRESTORE.BACKGROUND       OUTPUT {OUTPUT}.{CHIP.NAME}.bg.fits      IMAGE           NONE       CHIP       FALSE     NONE
+
+PPVIZPSF.OUTPUT              OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPVIZPATTERN.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE           NONE       CHIP       TRUE      NONE
+PPVIZPATTERN.CHIP            OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE           NONE       CHIP       TRUE      NONE
+
+
+# FILERULE naming operators:
 # {FPA.OBS}
 # {FPA.NAME}
Index: /branches/pap/ippconfig/recipes/nightly_science.config
===================================================================
--- /branches/pap/ippconfig/recipes/nightly_science.config	(revision 28002)
+++ /branches/pap/ippconfig/recipes/nightly_science.config	(revision 28003)
@@ -1,3 +1,20 @@
 RETENTION_TIME   U16	9000
+
+CLEAN_MODES MULTI
+CLEAN_MODES METADATA
+  MODE STR CHIP
+  COMMAND STR chiptool
+  RETENTION_TIME U16 30
+END
+CLEAN_MODES METADATA
+  MODE STR WARP
+  COMMAND STR warptool
+  RETENTION_TIME U16 7
+END
+CLEAN_MODES METADATA
+  MODE STR DIFF
+  COMMAND STR difftool
+  RETENTION_TIME U16 30
+END
 
 FILTERS MULTI
@@ -111,4 +128,5 @@
 # OBJECT STR SS
   STACKABLE BOOL FALSE
+  NOCLEAN BOOL TRUE
 END
 TARGETS METADATA
@@ -132,5 +150,5 @@
   OBJECT STR MD01%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -147,5 +165,5 @@
   OBJECT STR MD02%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -162,5 +180,5 @@
   OBJECT STR MD03%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -177,5 +195,5 @@
   OBJECT STR MD04%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -192,5 +210,5 @@
   OBJECT STR MD05%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -207,5 +225,5 @@
   OBJECT STR MD06%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -222,5 +240,5 @@
   OBJECT STR MD07%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -237,5 +255,5 @@
   OBJECT STR MD08%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -252,5 +270,5 @@
   OBJECT STR MD09%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
+  REDUCTION STR MICROTEST_NOPATTERN
   STACKABLE BOOL TRUE
 END
@@ -267,5 +285,5 @@
   OBJECT STR MD10%
   COMMENT STR Microtest Obs%
-  REDUCTION STR STDSCIENCE.V0
-  STACKABLE BOOL TRUE
-END
+  REDUCTION STR MICROTEST_NOPATTERN
+  STACKABLE BOOL TRUE
+END
Index: /branches/pap/ippconfig/recipes/ppSim.config
===================================================================
--- /branches/pap/ippconfig/recipes/ppSim.config	(revision 28002)
+++ /branches/pap/ippconfig/recipes/ppSim.config	(revision 28003)
@@ -53,5 +53,5 @@
 STARS.MAG	F32	15.5		# Brightest magnitude for fake stars (choose based on real catalog limit)
 STARS.DENSITY	F32      1.0		# Stellar density (per square degree) at the brightest magnitude
-STARS.SIGMA.LIM F32      0.1            # significance of faintest sources
+STARS.SIGMA.LIM F32      1.0            # significance of faintest sources
 
 STARS.FLAT.LUM  BOOL    FALSE           # use a (non-physical) constant number of stars per mag bin?
Index: /branches/pap/ippconfig/recipes/ppStack.config
===================================================================
--- /branches/pap/ippconfig/recipes/ppStack.config	(revision 28002)
+++ /branches/pap/ippconfig/recipes/ppStack.config	(revision 28003)
@@ -61,4 +61,5 @@
 	z	F32	0.0
 	y	F32	0.0
+	w	F32	0.0
 END
 ZP.TARGET	METADATA		# Target zero point by filter
@@ -68,4 +69,5 @@
 	z	F32	25.0
 	y	F32	25.0
+	w	F32	25.0
 END
 
Index: /branches/pap/ippconfig/recipes/ppStats.config
===================================================================
--- /branches/pap/ippconfig/recipes/ppStats.config	(revision 28002)
+++ /branches/pap/ippconfig/recipes/ppStats.config	(revision 28003)
@@ -1,3 +1,8 @@
 ### Default ppStats recipe
+
+## XXX Additional notes:
+## 1) diff_skycell.pl and stack_skycell.pl currently both use the WARPSTATS recipe below
+## 2) ppSub (at least) supplements the stats file explicitly with several items that are not
+## written to headers (see ppSubReadoutStats.c)
 
 # Options governing statistics
Index: /branches/pap/ippconfig/recipes/psphot.config
===================================================================
--- /branches/pap/ippconfig/recipes/psphot.config	(revision 28002)
+++ /branches/pap/ippconfig/recipes/psphot.config	(revision 28003)
@@ -151,4 +151,5 @@
 EXTENDED_SOURCE_ANALYSIS            BOOL  FALSE  # perform any of the aperture-like measurements?
 EXTENDED_SOURCE_SN_LIM              F32   20.0
+EXTENDED_SOURCE_RAW_RADIUS          BOOL  FALSE
 EXTENDED_SOURCE_PETROSIAN           BOOL  FALSE
 EXTENDED_SOURCE_ISOPHOTAL           BOOL  FALSE
@@ -174,6 +175,10 @@
 
 # define the annuli (in pixels) for surface brightness measurements
-@RADIAL.ANNULAR.BINS.LOWER           F32     0.0   5.0  10.0  20.0  40.0  80.0
-@RADIAL.ANNULAR.BINS.UPPER           F32     5.0  10.0  20.0  40.0  80.0 160.0
+# @RADIAL.ANNULAR.BINS.LOWER           F32     0.0   5.0  10.0  20.0  40.0  80.0
+# @RADIAL.ANNULAR.BINS.UPPER           F32     5.0  10.0  20.0  40.0  80.0 160.0
+
+# SDSS values:
+@RADIAL.ANNULAR.BINS.LOWER           F32     0.00 0.56 1.69 2.59 4.41  7.51 11.58 18.58 28.55 45.50  70.51 110.53 172.49 269.52 420.51
+@RADIAL.ANNULAR.BINS.UPPER           F32     0.56 1.69 2.59 4.41 7.51 11.58 18.58 28.55 45.50 70.51 110.53 172.49 269.52 420.51 652.50
 
 # Extended source fit parameters
@@ -279,5 +284,41 @@
 
 # stack photometry parameters
-PSPHOT.STACK.MATCH.RADIUS           F32   1.0 # join detections from different images with this correlation radius (pixels)
+PSPHOT.STACK.MATCH.RADIUS           F32   1.0  # join detections from different images with this correlation radius (pixels)
+PSPHOT.STACK.MATCH.PSF              BOOL  T    # convolved input images to common target PSF
+PSPHOT.STACK.MATCH.PSF.SOURCE       STR   AUTO # which inputs to convolve? (RAW, CNV, AUTO)
+PSPHOT.STACK.TARGET.PSF.AUTO        BOOL  T    # automatically determine target PSF size?
+PSPHOT.STACK.TARGET.PSF.FWHM        F32   5.0  # FWHM of target PSF (if NOT AUTO sized; pixels)
+
+RADIAL_APERTURES                    BOOL  F    # calculate flux in circular radial apertures?
+RADIAL_APERTURES_SN_LIM             F32   0.0  # S/N limit for radial aperture calculation
+
+# Extended source fit parameters
+STACKPHOT_TEST                       METADATA
+  EXTENDED_SOURCE_ANALYSIS            BOOL  TRUE  # perform any of the aperture-like measurements?
+  EXTENDED_SOURCE_SN_LIM              F32   20.0
+  EXTENDED_SOURCE_PETROSIAN           BOOL  TRUE
+  EXTENDED_SOURCE_ISOPHOTAL           BOOL  FALSE
+  EXTENDED_SOURCE_ANNULI              BOOL  TRUE
+  EXTENDED_SOURCE_KRON                BOOL  FALSE
+  PSPHOT.STACK.MATCH.PSF.SOURCE       STR   AUTO # which inputs to convolve? (RAW, CNV, AUTO)
+  PSPHOT.STACK.TARGET.PSF.AUTO        BOOL  F    # automatically determine target PSF size?
+  PSPHOT.STACK.TARGET.PSF.FWHM        F32   4.5  # FWHM of target PSF (if NOT AUTO sized; pixels)
+END
+
+# Extended source fit parameters
+STACKPHOT                             METADATA
+  EXTENDED_SOURCE_ANALYSIS            BOOL  TRUE  # perform any of the aperture-like measurements?
+  EXTENDED_SOURCE_SN_LIM              F32   20.0
+  EXTENDED_SOURCE_PETROSIAN           BOOL  TRUE
+  EXTENDED_SOURCE_ISOPHOTAL           BOOL  FALSE
+  EXTENDED_SOURCE_ANNULI              BOOL  TRUE
+  EXTENDED_SOURCE_KRON                BOOL  FALSE
+  PSPHOT.STACK.MATCH.PSF.SOURCE       STR   AUTO # which inputs to convolve? (RAW, CNV, AUTO)
+  PSPHOT.STACK.TARGET.PSF.AUTO        BOOL  F    # automatically determine target PSF size?
+  PSPHOT.STACK.TARGET.PSF.FWHM        F32   7.5  # FWHM of target PSF (if NOT AUTO sized; pixels)
+  RADIAL_APERTURES                    BOOL  T    # calculate flux in circular radial apertures?
+  RADIAL_APERTURES_SN_LIM             F32   0.0  # S/N limit for radial aperture calculation
+  OUTPUT.FORMAT                       STR   PS1_SV1
+END
 
 # Recipe overrides for CHIP
Index: /branches/pap/ippconfig/recipes/reductionClasses.mdc
===================================================================
--- /branches/pap/ippconfig/recipes/reductionClasses.mdc	(revision 28002)
+++ /branches/pap/ippconfig/recipes/reductionClasses.mdc	(revision 28003)
@@ -157,4 +157,5 @@
 	ADDSTAR		STR	ADDSTAR
 	PSASTRO		STR	DEFAULT_RECIPE
+	STACKPHOT       STR     STACKPHOT
 END
 
@@ -178,4 +179,21 @@
 # basic science analysis
 MAGICTEST.V0		METADATA
+	CHIP_PPIMAGE	STR	CHIP_NOPATTERN
+	CHIP_PSPHOT	STR	CHIP
+	WARP_PSWARP	STR	WARP
+	STACK_PPSTACK	STR	STACK
+	STACK_PPSUB	STR	STACK
+	STACK_PSPHOT	STR	STACK
+	DIFF_PPSUB	STR	DIFF
+	DIFF_PSPHOT	STR	DIFF
+	JPEG_BIN1	STR	PPIMAGE_J1
+	JPEG_BIN2	STR	PPIMAGE_J2
+	FAKEPHOT	STR	FAKEPHOT
+	ADDSTAR		STR	ADDSTAR
+	PSASTRO		STR	DEFAULT_RECIPE
+END
+
+# microtest no pattern reduction class
+MICROTEST_NOPATTERN		METADATA
 	CHIP_PPIMAGE	STR	CHIP_NOPATTERN
 	CHIP_PSPHOT	STR	CHIP
Index: /branches/pap/ippconfig/sdssmosaic/psphot.config
===================================================================
--- /branches/pap/ippconfig/sdssmosaic/psphot.config	(revision 28002)
+++ /branches/pap/ippconfig/sdssmosaic/psphot.config	(revision 28003)
@@ -5,5 +5,5 @@
 # what is the 2D variation of the SDSS PSF?
 PSF_CLUMP_NX        S32   3               # subdivide image in to NX x NY regions for 
-PSF_CLUMP_NY        S32   3               # selecting PSF stars
+PSF_CLUMP_NY        S32   2               # selecting PSF stars
 
 # test this:
@@ -11,10 +11,11 @@
 
 # PSF model parameters : choose the PSF model desired
-PSF_MODEL           STR  PS_MODEL_PS1_V1
+# PSF_MODEL           STR  PS_MODEL_PS1_V1
+PSF_MODEL           STR  PS_MODEL_QGAUSS
 
 # Use same default setting as in 2.6.1 (MAP is now global default)
-PSF.TREND.MODE                      STR POLY_ORD         
-PSF.TREND.NX                        S32   0 
-PSF.TREND.NY                        S32   0
+PSF.TREND.MODE                      STR   MAP
+PSF.TREND.NX                        S32   3 
+PSF.TREND.NY                        S32   2
 
 # match the SDSS radius:
Index: /branches/pap/ippconfig/simmosaic/filerules-mef.mdc
===================================================================
--- /branches/pap/ippconfig/simmosaic/filerules-mef.mdc	(revision 28003)
+++ /branches/pap/ippconfig/simmosaic/filerules-mef.mdc	(revision 28003)
@@ -0,0 +1,277 @@
+### File rules for PHU=FPA, EXT=CHIP (eg, Megacam)
+### this file specifies compression types for various output files
+### The image types are defined in fitstypes.mdc
+### The default type of NONE means no compression
+
+### Redirections (MEF)
+PPIMAGE.OUTPUT        STR PPIMAGE.OUTPUT.MEF
+PPIMAGE.OUTPUT.MASK   STR PPIMAGE.OUT.MK.MEF
+PPIMAGE.OUTPUT.VARIANCE STR PPIMAGE.OUT.WT.MEF
+
+PPIMAGE.CHIP          STR PPIMAGE.CHIP.MEF
+PPIMAGE.CHIP.MASK     STR PPIMAGE.CHIP.MK.MEF
+PPIMAGE.CHIP.VARIANCE STR PPIMAGE.CHIP.WT.MEF
+
+PPIMAGE.BIN1          STR PPIMAGE.BIN1.MEF
+PPIMAGE.BIN2          STR PPIMAGE.BIN2.MEF
+
+PSASTRO.OUTPUT        STR PSASTRO.OUT.CMF.MEF
+PSPHOT.OUTPUT         STR PSPHOT.OUT.CMF.MEF
+PSPHOT.PSF.SAVE       STR PSPHOT.PSF.RAW.SAVE
+
+### Redirections (SPL)
+# PPIMAGE.OUTPUT        STR PPIMAGE.OUTPUT.SPL
+# PPIMAGE.OUTPUT.MASK   STR PPIMAGE.OUT.MK.SPL
+# PPIMAGE.OUTPUT.VARIANCE STR PPIMAGE.OUT.WT.SPL
+# 
+# PPIMAGE.CHIP          STR PPIMAGE.CHIP.SPL
+# PPIMAGE.CHIP.MASK     STR PPIMAGE.CHIP.MK.SPL
+# PPIMAGE.CHIP.VARIANCE STR PPIMAGE.CHIP.WT.SPL
+# 
+# PPIMAGE.BIN1          STR PPIMAGE.BIN1.SPL
+# PPIMAGE.BIN2          STR PPIMAGE.BIN2.SPL
+# 
+# PSASTRO.OUTPUT        STR PSASTRO.OUT.CMF.SPL
+# PSPHOT.OUTPUT         STR PSPHOT.OUT.CMF.SPL
+
+### Redirections (common)
+
+PPIMAGE.OUTPUT.FPA1   STR PPIMAGE.OUTPUT.FPA1.MEF
+PPIMAGE.OUTPUT.FPA2   STR PPIMAGE.OUTPUT.FPA2.MEF
+PPSTAMP.CHIP          STR PPSTAMP.CHIP.MEF
+PSASTRO.INPUT         STR PSASTRO.INPUT.CMF
+PSASTRO.OUTPUT.MEF    STR PSASTRO.OUT.CMF.MEF
+DVOCORR.OUTPUT        STR DVOCORR.MEF.OUTPUT
+DVOFLAT.OUTPUT        STR DVOFLAT.MEF.OUTPUT
+
+### input file definitions
+### use @DETDB entries to get the detrend images from the database
+### replace @DETDB with @FILES if you want to require it from the 
+### command line, or with an explicit name to require a specific file
+TYPE                    INPUT    FILENAME.RULE DATA.LEVEL FILE.TYPE
+
+## files used by ppImage
+PPIMAGE.INPUT           INPUT    @FILES        CHIP       IMAGE
+PPIMAGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PPIMAGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+PPIMAGE.INPUT.PSF       INPUT    @FILES        CHIP       PSF
+PPIMAGE.INPUT.SRC       INPUT    @FILES        CHIP       CMF
+PPIMAGE.MASK            INPUT    @DETDB        CHIP       MASK
+PPIMAGE.BIAS            INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.DARK            INPUT    @DETDB        CHIP       DARK
+PPIMAGE.FLAT            INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.FRINGE          INPUT    @DETDB        CHIP       FRINGE
+PPIMAGE.SHUTTER         INPUT    @DETDB        CHIP       IMAGE     
+
+## Files used by ppMerge
+PPMERGE.INPUT           INPUT    @FILES        CHIP       IMAGE
+PPMERGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PPMERGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+
+## files used to build and apply the flat-field correction images
+DVOCORR.INPUT           INPUT    @FILES        CHIP       IMAGE
+DVOCORR.REFHEAD         INPUT    @FILES        CHIP       HEADER
+DVOFLAT.INPUT           INPUT    @FILES        CHIP       IMAGE
+DVOFLAT.CORR            INPUT    @DETDB        CHIP       IMAGE
+
+## files used by psphot 
+PSPHOT.LOAD             INPUT    @FILES        CHIP       IMAGE
+PSPHOT.INPUT            INPUT    @FILES        CHIP       IMAGE
+PSPHOT.MASK             INPUT    @FILES        CHIP       MASK     
+PSPHOT.VARIANCE         INPUT    @FILES        CHIP       VARIANCE   
+PSPHOT.PSF.LOAD         INPUT    @FILES        CHIP       PSF       
+PSPHOT.INPUT.CMF        INPUT    @FILES        CHIP       CMF       
+
+## files used by psastro 
+PSASTRO.INPUT.CMP       INPUT    @FILES        CHIP       CMP
+PSASTRO.INPUT.CMF       INPUT    @FILES        CHIP       CMF
+PSASTRO.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PSASTRO.REFMASK         INPUT    @DETDB        CHIP       MASK
+PSASTRO.WCS             INPUT    @FILES        CHIP       CMF
+PSASTRO.MODEL           INPUT    @DETDB        FPA        ASTROM
+
+PSASTRO.EXTRACT.ASTROM  INPUT    @FILES        CHIP       CMF
+PSASTRO.EXTRACT.INPUT   INPUT    @FILES        CHIP       IMAGE
+
+## files used by pswarp
+PSWARP.INPUT            INPUT    @FILES        CHIP       IMAGE
+PSWARP.VARIANCE         INPUT    @FILES        CHIP       VARIANCE
+PSWARP.MASK             INPUT    @FILES        CHIP       MASK
+PSWARP.SKYCELL          INPUT    @FILES        CHIP       IMAGE
+PSWARP.ASTROM           INPUT    @FILES        CHIP       CMF
+
+## files used by ppsub
+PPSUB.INPUT             INPUT    @FILES        FPA        IMAGE
+PPSUB.INPUT.MASK        INPUT    @FILES        FPA        MASK
+PPSUB.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
+PPSUB.INPUT.SOURCES     INPUT    @FILES        FPA        CMF
+PPSUB.REF               INPUT    @FILES        FPA        IMAGE
+PPSUB.REF.MASK          INPUT    @FILES        FPA        MASK
+PPSUB.REF.VARIANCE      INPUT    @FILES        FPA        VARIANCE
+PPSUB.REF.SOURCES       INPUT    @FILES        FPA        CMF
+
+## files used by ppstack
+PPSTACK.INPUT           INPUT    @FILES        FPA        IMAGE
+PPSTACK.INPUT.MASK      INPUT    @FILES        FPA        MASK
+PPSTACK.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
+PPSTACK.INPUT.PSF       INPUT    @FILES        CHIP       PSF
+PPSTACK.INPUT.SOURCES   INPUT    @FILES        FPA        CMF
+
+## files used by ppstamp
+PPSTAMP.INPUT           INPUT 	 @FILES        CHIP       IMAGE
+PPSTAMP.INPUT.MASK      INPUT 	 @FILES        CHIP       MASK
+PPSTAMP.INPUT.VARIANCE  INPUT 	 @FILES        CHIP       VARIANCE
+
+# files used by pparith
+PPARITH.INPUT.IMAGE     INPUT    @FILES        CHIP       IMAGE
+PPARITH.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+
+PPSKYCELL.IMAGE      	INPUT 	 @FILES        CHIP       IMAGE
+PPSKYCELL.MASK      	INPUT 	 @FILES        CHIP       MASK
+
+PPSIM.INPUT             INPUT    @FILES        FPA        IMAGE     
+PPSIM.REAL.SOURCES      INPUT    @FILES        CHIP       CMF       
+
+### output file definitions
+TYPE                    OUTPUT FILENAME.RULE                     FILE.TYPE FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
+PPIMAGE.OUTPUT.MEF      OUTPUT {OUTPUT}.b0.fits                  IMAGE     COMP_IMG   CHIP       TRUE      MEF
+PPIMAGE.OUT.MK.MEF      OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  CHIP       TRUE      MEF
+PPIMAGE.OUT.WT.MEF      OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    CHIP       TRUE      MEF
+PPIMAGE.OUTPUT.SPL      OUTPUT {OUTPUT}.{CHIP.NAME}.b0.fits      IMAGE     NONE       CHIP       TRUE      SPLIT
+PPIMAGE.OUT.MK.SPL      OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK      NONE       CHIP       TRUE      SPLIT
+PPIMAGE.OUT.WT.SPL      OUTPUT {OUTPUT}.{CHIP.NAME}.wt.fits      VARIANCE  NONE       CHIP       TRUE      SPLIT
+PPIMAGE.OUTPUT.DETMASK  OUTPUT {OUTPUT}.fits                     IMAGE     MASK       CHIP       TRUE      MEF
+PPIMAGE.OUTPUT.DETREND  OUTPUT {OUTPUT}.fits                     IMAGE     COMP_DET   CHIP       TRUE      MEF
+PPIMAGE.OUTPUT.RESID    OUTPUT {OUTPUT}.b0.fits                  IMAGE     COMP_SUB   CHIP       TRUE      MEF
+PPIMAGE.CONFIG          OUTPUT {OUTPUT}.{CHIP.NAME}.ppImage.mdc  TEXT      NONE       CHIP       TRUE      NONE
+                                                                                             
+PPIMAGE.CHIP.MEF        OUTPUT {OUTPUT}.ch.fits                  IMAGE     COMP_IMG   CHIP       TRUE      MEF
+PPIMAGE.CHIP.MK.MEF     OUTPUT {OUTPUT}.ch.mk.fits               MASK      COMP_MASK  CHIP       TRUE      MEF
+PPIMAGE.CHIP.WT.MEF     OUTPUT {OUTPUT}.ch.wt.fits               VARIANCE  COMP_WT    CHIP       TRUE      MEF
+PPIMAGE.CHIP.SPL        OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     NONE       CHIP       TRUE      SPLIT
+PPIMAGE.CHIP.MK.SPL     OUTPUT {OUTPUT}.{CHIP.NAME}.ch.mk.fits   MASK      NONE       CHIP       TRUE      SPLIT
+PPIMAGE.CHIP.WT.SPL     OUTPUT {OUTPUT}.{CHIP.NAME}.ch.wt.fits   VARIANCE  NONE       CHIP       TRUE      SPLIT
+                                                                                     
+PPIMAGE.OUTPUT.FPA1.MEF OUTPUT {OUTPUT}.b1.fits                  IMAGE     COMP_IMG   FPA        TRUE      MEF
+PPIMAGE.OUTPUT.FPA2.MEF OUTPUT {OUTPUT}.b2.fits                  IMAGE     COMP_IMG   FPA        TRUE      MEF
+PPIMAGE.OUTPUT.FPA1.SPL OUTPUT {OUTPUT}.{CHIP.NAME}.b1.fits      IMAGE     NONE       CHIP       TRUE      SPLIT
+PPIMAGE.OUTPUT.FPA2.SPL OUTPUT {OUTPUT}.{CHIP.NAME}.b2.fits      IMAGE     NONE       CHIP       TRUE      SPLIT
+                                                                                     
+PPIMAGE.BIN1.MEF        OUTPUT {OUTPUT}.b1c.fits                 IMAGE     COMP_IMG   CHIP       TRUE      MEF
+PPIMAGE.BIN2.MEF        OUTPUT {OUTPUT}.b2c.fits                 IMAGE     COMP_IMG   CHIP       TRUE      MEF
+PPIMAGE.BIN1.SPL        OUTPUT {OUTPUT}.{CHIP.NAME}.b1.fits      IMAGE     COMP_IMG   CHIP       TRUE      SPLIT
+PPIMAGE.BIN2.SPL        OUTPUT {OUTPUT}.{CHIP.NAME}.b2.fits      IMAGE     COMP_IMG   CHIP       TRUE      SPLIT
+                                                                                     
+PPIMAGE.JPEG1           OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPIMAGE.JPEG2           OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
+                                                                                     
+PPIMAGE.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      MEF
+
+
+## note: these use the same output naming convention since they are used for different ppMerge runs
+PPMERGE.OUTPUT.MASK     OUTPUT {OUTPUT}.fits                     MASK      NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.BIAS     OUTPUT {OUTPUT}.fits                     IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.DARK     OUTPUT {OUTPUT}.fits                     DARK      NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.SHUTTER  OUTPUT {OUTPUT}.fits                     IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.FLAT     OUTPUT {OUTPUT}.fits                     IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.FRINGE   OUTPUT {OUTPUT}.fits                     FRINGE    NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.SIGMA    OUTPUT {OUTPUT}.sigma.fits               IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.COUNT    OUTPUT {OUTPUT}.count.fits               IMAGE     NONE       CHIP       TRUE      NONE
+                                                                                     
+DVOCORR.MEF.OUTPUT      OUTPUT {OUTPUT}.fc.fits                  IMAGE     NONE       CHIP       TRUE      MEF
+DVOCORR.SPL.OUTPUT      OUTPUT {OUTPUT}.{CHIP.NAME}.fc.fits      IMAGE     NONE       CHIP       TRUE      SPLIT
+DVOFLAT.MEF.OUTPUT      OUTPUT {OUTPUT}.co.fits                  IMAGE     NONE       CHIP       TRUE      MEF
+DVOFLAT.SPL.OUTPUT      OUTPUT {OUTPUT}.{CHIP.NAME}.co.fits      IMAGE     NONE       CHIP       TRUE      SPLIT
+                                                                                     
+PSPHOT.RESID            OUTPUT {OUTPUT}.res.fits                 IMAGE     NONE       CHIP       FALSE     MEF
+PSPHOT.BACKGND          OUTPUT {OUTPUT}.bck.fits                 IMAGE     NONE       CHIP       FALSE     MEF
+PSPHOT.BACKSUB          OUTPUT {OUTPUT}.sub.fits                 IMAGE     NONE       CHIP       FALSE     MEF
+PSPHOT.BACKMDL          OUTPUT {OUTPUT}.mdl.fits                 IMAGE     NONE       CHIP       FALSE     MEF
+PSPHOT.BACKMDL.MEF      OUTPUT {OUTPUT}.mdl.fits                 IMAGE     NONE       CHIP       FALSE     MEF
+                                                                                     
+PSPHOT.OUTPUT.RAW       OUTPUT {OUTPUT}.{CHIP.NAME}              RAW       NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.SX        OUTPUT {OUTPUT}.{CHIP.NAME}.sx           SX        NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.OBJ       OUTPUT {OUTPUT}.{CHIP.NAME}.obj          OBJ       NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.CMP       OUTPUT {OUTPUT}.{CHIP.NAME}.cmp          CMP       NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.SPL      OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF       NONE       CHIP       TRUE      SPLIT
+PSPHOT.OUT.CMF.MEF      OUTPUT {OUTPUT}.cmf                      CMF       NONE       CHIP       TRUE      MEF
+PSPHOT.PSF.RAW.SAVE     OUTPUT {OUTPUT}.psf                      PSF       NONE       CHIP       TRUE      MEF
+PSPHOT.PSF.SKY.SAVE     OUTPUT {OUTPUT}.psf                      PSF       NONE       CHIP       TRUE      MEF
+                                                                                     
+SOURCE.PLOT.MOMENTS     OUTPUT {OUTPUT}.mnt.png                  KAPA      NONE       FPA        TRUE      NONE
+SOURCE.PLOT.PSFMODEL    OUTPUT {OUTPUT}.psf.png                  KAPA      NONE       FPA        TRUE      NONE
+SOURCE.PLOT.APRESID     OUTPUT {OUTPUT}.dap.png                  KAPA      NONE       FPA        TRUE      NONE
+                                                                                     
+PSASTRO.OUTPUT.CMP      OUTPUT {OUTPUT}.{CHIP.NAME}.smp          CMP       NONE       CHIP       TRUE      NONE
+PSASTRO.OUT.CMF.SPL     OUTPUT {OUTPUT}.{CHIP.NAME}.smf          CMF       NONE       CHIP       TRUE      SPLIT
+PSASTRO.OUT.CMF.MEF     OUTPUT {OUTPUT}.smf                      CMF       NONE       FPA        TRUE      MEF
+PSASTRO.OUT.MODEL       OUTPUT {OUTPUT}.asm                ASTROM.MODEL    NONE       FPA        TRUE      NONE
+PSASTRO.OUT.REFSTARS    OUTPUT {OUTPUT}.aref.fits          ASTROM.REFSTARS NONE       FPA        TRUE      NONE
+PSASTRO.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      NONE
+PSASTRO.CONFIG          OUTPUT {OUTPUT}.psastro.mdc              TEXT      NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
+                                                                                     
+PSWARP.OUTPUT           OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PSWARP.OUTPUT.MASK      OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  FPA        TRUE      NONE
+PSWARP.OUTPUT.VARIANCE  OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PSWARP.OUTPUT.SOURCES   OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
+PSWARP.BIN1             OUTPUT {OUTPUT}.b1.fits                  IMAGE     COMP_IMG   FPA        TRUE      NONE
+PSWARP.BIN2             OUTPUT {OUTPUT}.b2.fits                  IMAGE     COMP_IMG   FPA        TRUE      NONE
+PSWARP.CONFIG           OUTPUT {OUTPUT}.pswarp.mdc               TEXT      NONE       FPA        TRUE      NONE
+                                                                                     
+SKYCELL.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      NONE
+SKYCELL.TEMPLATE        OUTPUT {OUTPUT}.skycell                  SKYCELL   NONE       FPA        TRUE      NONE
+                                                                                     
+PPSUB.OUTPUT            OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PPSUB.OUTPUT.MASK       OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.OUTPUT.VARIANCE   OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSUB.OUTPUT.SOURCES    OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.KERNELS    OUTPUT {OUTPUT}.subkernel                SUBKERNEL NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG1      OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG2      OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSUB.INVERSE           OUTPUT {OUTPUT}.inv.fits                 IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.INVERSE.MASK      OUTPUT {OUTPUT}.inv.mask.fits            MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.INVERSE.VARIANCE  OUTPUT {OUTPUT}.inv.wt.fits              VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSUB.INVERSE.SOURCES   OUTPUT {OUTPUT}.inv.cmf                  CMF       NONE       FPA        TRUE      NONE
+PPSUB.CONFIG            OUTPUT {OUTPUT}.ppSub.mdc                TEXT      NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV        OUTPUT {OUTPUT}.inConv.fits              IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.INPUT.CONV.MASK   OUTPUT {OUTPUT}.inConv.mk.fits           MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.INPUT.CONV.VARIANCE OUTPUT {OUTPUT}.inConv.wt.fits         VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSUB.REF.CONV        	OUTPUT {OUTPUT}.refConv.fits             IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.REF.CONV.MASK   	OUTPUT {OUTPUT}.refConv.mk.fits          MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.REF.CONV.VARIANCE	OUTPUT {OUTPUT}.refConv.wt.fits          VARIANCE  COMP_WT    FPA        TRUE      NONE
+		      						       		     
+                                                                                     
+PPSTACK.OUTPUT          OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PPSTACK.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  FPA        TRUE      NONE
+PPSTACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSTACK.TARGET.PSF      OUTPUT {OUTPUT}.target.psf               PSF       NONE       CHIP       TRUE      NONE
+PPSTACK.CONV.KERNEL     OUTPUT {OUTPUT}.{FILE.INDEX}.kernel      SUBKERNEL NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG1    OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG2    OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSTACK.CONFIG          OUTPUT {OUTPUT}.ppStack.mdc              TEXT      NONE       FPA        TRUE      NONE
+                                                                                     
+PPSTAMP.OUTPUT          OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PPSTAMP.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  FPA        TRUE      NONE
+PPSTAMP.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSTAMP.CHIP.MEF        OUTPUT {OUTPUT}.ch.fits                  IMAGE     NONE       CHIP       FALSE     MEF
+                                                                                     
+PPSIM.OUTPUT.MEF        OUTPUT {OUTPUT}.fits                     IMAGE     NONE       CHIP       TRUE      SPLIT
+PPSIM.OUTPUT.SPL        OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      SPLIT
+PPSIM.FAKE.CHIP         OUTPUT {OUTPUT}.fake.fits                IMAGE     NONE       FPA        TRUE      NONE
+PPSIM.FORCE.CHIP        OUTPUT {OUTPUT}.force.fits               IMAGE     NONE       FPA        TRUE      NONE
+PPSIM.SOURCES           OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
+PPSIM.FAKE.SOURCES      OUTPUT {OUTPUT}.fake.cmf                 CMF       NONE       FPA        TRUE      NONE
+PPSIM.FORCE.SOURCES     OUTPUT {OUTPUT}.force.cmf                CMF       NONE       FPA        TRUE      NONE
+                                                                                     
+PPARITH.OUTPUT.IMAGE    OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   CHIP       TRUE      NONE
+PPARITH.OUTPUT.MASK     OUTPUT {OUTPUT}.fits                     MASK      COMP_MASK  CHIP       TRUE      NONE
+                                                                                     
+PPSKYCELL.JPEG1    	OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg     JPEG      NONE       CHIP       TRUE      NONE
+PPSKYCELL.JPEG2    	OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg     JPEG      NONE       CHIP       TRUE      NONE
+
+LOG.IMFILE              OUTPUT {OUTPUT}.{CHIP.NAME}.log          TEXT      NONE       CHIP       TRUE      NONE
+LOG.EXP                 OUTPUT {OUTPUT}.log                      TEXT      NONE       FPA        TRUE      NONE
+                                                                                     
+TRACE.IMFILE            OUTPUT {OUTPUT}.{CHIP.NAME}.trace        TEXT      NONE       CHIP       TRUE      NONE
+TRACE.EXP               OUTPUT {OUTPUT}.trace                    TEXT      NONE       FPA        TRUE      NONE
Index: /branches/pap/ippconfig/simmosaic/filerules-simple.mdc
===================================================================
--- /branches/pap/ippconfig/simmosaic/filerules-simple.mdc	(revision 28003)
+++ /branches/pap/ippconfig/simmosaic/filerules-simple.mdc	(revision 28003)
@@ -0,0 +1,225 @@
+### File rules for PHU=FPA, EXT=NONE
+### The default type of NONE means no compression
+
+
+PSASTRO.INPUT      STR PSASTRO.INPUT.CMF
+PSASTRO.OUTPUT     STR PSASTRO.OUTPUT.CMF
+PSPHOT.OUTPUT      STR PSPHOT.OUTPUT.CMF
+PSPHOT.PSF.SAVE    STR PSPHOT.PSF.RAW.SAVE
+
+### input file definitions
+### use @DETDB entries to get the detrend images from the database
+### replace @DETDB with @FILES if you want to require it from the 
+### command line, or with an explicit name to require a specific file
+TYPE                    INPUT    FILENAME.RULE DATA.LEVEL FILE.TYPE
+
+## files used by ppImage
+PPIMAGE.INPUT           INPUT    @FILES        FPA        IMAGE     
+PPIMAGE.INPUT.MASK      INPUT    @FILES        FPA        MASK      
+PPIMAGE.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE  
+PPIMAGE.INPUT.PSF       INPUT    @FILES        READOUT    PSF       
+PPIMAGE.INPUT.SRC       INPUT    @FILES        READOUT    CMF       
+PPIMAGE.MASK            INPUT    @DETDB        CHIP       MASK
+PPIMAGE.BIAS            INPUT    @DETDB        CHIP       IMAGE     
+PPIMAGE.DARK            INPUT    @DETDB        CHIP       DARK     
+PPIMAGE.FLAT            INPUT    @DETDB        CHIP       IMAGE     
+PPIMAGE.FRINGE          INPUT    @DETDB        CHIP       FRINGE
+PPIMAGE.SHUTTER         INPUT    @DETDB        CHIP       IMAGE     
+
+## Files used by ppMerge
+PPMERGE.INPUT           INPUT    @FILES        CHIP       IMAGE
+PPMERGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PPMERGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+
+## files used to build and apply the flat-field correction images
+DVOCORR.INPUT           INPUT    @FILES        CHIP       IMAGE
+DVOCORR.REFHEAD         INPUT    @FILES        CHIP       HEADER
+DVOFLAT.INPUT           INPUT    @FILES        CHIP       IMAGE
+DVOFLAT.CORR            INPUT    @DETDB        CHIP       IMAGE
+
+## files used by psphot 
+PSPHOT.LOAD             INPUT    @FILES        CHIP       IMAGE
+PSPHOT.INPUT            INPUT    @FILES        CHIP       IMAGE     
+PSPHOT.MASK             INPUT    @FILES        CHIP       MASK     
+PSPHOT.VARIANCE         INPUT    @FILES        CHIP       VARIANCE   
+PSPHOT.PSF.LOAD         INPUT    @FILES        CHIP       PSF       
+PSPHOT.INPUT.CMF        INPUT    @FILES        CHIP       CMF       
+
+## files used by psastro 
+PSASTRO.INPUT.CMP       INPUT    @FILES        CHIP       CMP       
+PSASTRO.INPUT.CMF       INPUT    @FILES        CHIP       CMF       
+PSASTRO.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PSASTRO.REFMASK         INPUT    @DETDB        CHIP       MASK
+PSASTRO.WCS             INPUT    @FILES        CHIP       CMF
+PSASTRO.MODEL           INPUT    @DETDB        FPA        ASTROM
+
+PSASTRO.EXTRACT.ASTROM  INPUT    @FILES        CHIP       CMF
+PSASTRO.EXTRACT.INPUT   INPUT    @FILES        CHIP       IMAGE
+
+## files used by pswarp
+PSWARP.INPUT            INPUT    @FILES        FPA        IMAGE     
+PSWARP.VARIANCE         INPUT    @FILES        FPA        VARIANCE
+PSWARP.MASK             INPUT    @FILES        FPA        MASK
+PSWARP.SKYCELL          INPUT    @FILES        FPA        IMAGE     
+PSWARP.ASTROM           INPUT    @FILES        FPA        CMF
+
+## files used by ppsub
+PPSUB.INPUT             INPUT    @FILES        FPA        IMAGE
+PPSUB.INPUT.MASK        INPUT    @FILES        FPA        MASK
+PPSUB.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
+PPSUB.INPUT.SOURCES     INPUT    @FILES        FPA        CMF
+PPSUB.REF               INPUT    @FILES        FPA        IMAGE
+PPSUB.REF.MASK          INPUT    @FILES        FPA        MASK
+PPSUB.REF.VARIANCE      INPUT    @FILES        FPA        VARIANCE
+PPSUB.REF.SOURCES       INPUT    @FILES        FPA        CMF
+
+## files used by ppstack
+PPSTACK.INPUT           INPUT    @FILES        FPA        IMAGE
+PPSTACK.INPUT.MASK      INPUT    @FILES        FPA        MASK
+PPSTACK.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
+PPSTACK.INPUT.PSF       INPUT    @FILES        CHIP       PSF
+PPSTACK.INPUT.SOURCES   INPUT    @FILES        FPA        CMF
+
+## files used by ppstamp
+PPSTAMP.INPUT           INPUT    @FILES        FPA        IMAGE
+PPSTAMP.INPUT.MASK      INPUT    @FILES        FPA        MASK
+PPSTAMP.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
+
+# files used by pparith
+PPARITH.INPUT.IMAGE     INPUT    @FILES        CHIP       IMAGE
+PPARITH.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+
+PPSKYCELL.IMAGE      	INPUT 	 @FILES        CHIP       IMAGE
+PPSKYCELL.MASK      	INPUT 	 @FILES        CHIP       MASK
+
+PPSIM.INPUT             INPUT    @FILES        FPA        IMAGE     
+PPSIM.REAL.SOURCES      INPUT    @FILES        CHIP       CMF       
+
+### output file definitions
+TYPE                    OUTPUT FILENAME.RULE         FILE.TYPE FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
+PPIMAGE.OUTPUT          OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits      MASK      NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits      VARIANCE  NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.DETMASK  OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.DETREND  OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.RESID    OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CONFIG          OUTPUT {OUTPUT}.ppImage.mdc  TEXT      NONE       FPA        TRUE      NONE
+                                                     
+PPIMAGE.CHIP            OUTPUT {OUTPUT}.ch.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CHIP.MASK       OUTPUT {OUTPUT}.ch.mk.fits   MASK      NONE       FPA        TRUE      SIMPLE
+PPIMAGE.CHIP.VARIANCE   OUTPUT {OUTPUT}.ch.wt.fits   VARIANCE  NONE       FPA        TRUE      SIMPLE
+                                                     
+PPIMAGE.OUTPUT.FPA1     OUTPUT {OUTPUT}.b1.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.OUTPUT.FPA2     OUTPUT {OUTPUT}.b2.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+                                                     
+PPIMAGE.BIN1            OUTPUT {OUTPUT}.b1.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+PPIMAGE.BIN2            OUTPUT {OUTPUT}.b2.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+                                                     
+PPIMAGE.JPEG1           OUTPUT {OUTPUT}.b1.jpg       JPEG      NONE       FPA        TRUE      NONE
+PPIMAGE.JPEG2           OUTPUT {OUTPUT}.b2.jpg       JPEG      NONE       FPA        TRUE      NONE
+                                                     
+PPIMAGE.STATS           OUTPUT {OUTPUT}.stats        STATS     NONE       FPA        TRUE      NONE
+
+
+## note: these use the  same output naming convention since they are used for different ppMerge runs
+PPMERGE.OUTPUT.MASK     OUTPUT {OUTPUT}.fits         MASK      NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.BIAS     OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.DARK     OUTPUT {OUTPUT}.fits         DARK      NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.SHUTTER  OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.FLAT     OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.FRINGE   OUTPUT {OUTPUT}.fits         FRINGE    NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.SIGMA    OUTPUT {OUTPUT}.sigma.fits   IMAGE     NONE       FPA        TRUE      SIMPLE
+PPMERGE.OUTPUT.COUNT    OUTPUT {OUTPUT}.count.fits   IMAGE     NONE       FPA        TRUE      SIMPLE
+                                                     
+DVOCORR.OUTPUT          OUTPUT {OUTPUT}.fc.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+DVOFLAT.OUTPUT          OUTPUT {OUTPUT}.co.fits      IMAGE     NONE       FPA        TRUE      SIMPLE
+                                                     
+PSPHOT.RESID            OUTPUT {OUTPUT}.res.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKGND          OUTPUT {OUTPUT}.bck.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKSUB          OUTPUT {OUTPUT}.sub.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKMDL          OUTPUT {OUTPUT}.mdl.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
+PSPHOT.BACKMDL.MEF      OUTPUT {OUTPUT}.mdl.fits     IMAGE     NONE       FPA        TRUE      SIMPLE
+                                                     
+PSPHOT.OUTPUT.RAW       OUTPUT {OUTPUT}              RAW       NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.SX        OUTPUT {OUTPUT}.sx           SX        NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.OBJ       OUTPUT {OUTPUT}.obj          OBJ       NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.CMP       OUTPUT {OUTPUT}.cmp          CMP       NONE       FPA        TRUE      NONE
+PSPHOT.OUTPUT.CMF       OUTPUT {OUTPUT}.cmf          CMF       NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.MEF      OUTPUT {OUTPUT}.cmf          CMF       NONE       CHIP       TRUE      NONE
+PSPHOT.PSF.RAW.SAVE     OUTPUT {OUTPUT}.psf          PSF       NONE       FPA        TRUE      NONE
+PSPHOT.PSF.SKY.SAVE     OUTPUT {OUTPUT}.psf          PSF       NONE       FPA        TRUE      NONE
+                                                     
+SOURCE.PLOT.MOMENTS     OUTPUT {OUTPUT}.mnt.png      KAPA      NONE       FPA        TRUE      NONE
+SOURCE.PLOT.PSFMODEL    OUTPUT {OUTPUT}.psf.png      KAPA      NONE       FPA        TRUE      NONE
+SOURCE.PLOT.APRESID     OUTPUT {OUTPUT}.dap.png      KAPA      NONE       FPA        TRUE      NONE
+                                                     
+PSASTRO.OUTPUT.CMP      OUTPUT {OUTPUT}.smp          CMP       NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.CMF      OUTPUT {OUTPUT}.smf          CMF       NONE       FPA        TRUE      NONE
+PSASTRO.OUT.MODEL       OUTPUT {OUTPUT}.asm          ASTROM.MODEL    NONE FPA        TRUE      NONE
+PSASTRO.OUT.REFSTARS    OUTPUT {OUTPUT}.aref.fits    ASTROM.REFSTARS NONE FPA        TRUE      NONE
+PSASTRO.STATS           OUTPUT {OUTPUT}.stats        STATS     NONE       FPA        TRUE      NONE
+PSASTRO.CONFIG          OUTPUT {OUTPUT}.psastro.mdc  TEXT      NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
+                                                     
+PSWARP.OUTPUT           OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      NONE
+PSWARP.OUTPUT.MASK      OUTPUT {OUTPUT}.mask.fits    MASK      NONE       FPA        TRUE      NONE
+PSWARP.OUTPUT.VARIANCE  OUTPUT {OUTPUT}.wt.fits      VARIANCE  NONE       FPA        TRUE      NONE
+PSWARP.OUTPUT.SOURCES   OUTPUT {OUTPUT}.cmf          CMF       NONE       FPA        TRUE      NONE
+PSWARP.BIN1             OUTPUT {OUTPUT}.b1.fits      IMAGE     NONE       FPA        TRUE      NONE
+PSWARP.BIN2             OUTPUT {OUTPUT}.b2.fits      IMAGE     NONE       FPA        TRUE      NONE
+PSWARP.CONFIG           OUTPUT {OUTPUT}.pswarp.mdc   TEXT      NONE       FPA        TRUE      NONE
+                                                     
+SKYCELL.STATS           OUTPUT {OUTPUT}.stats        STATS     NONE       FPA        TRUE      NONE
+SKYCELL.TEMPLATE        OUTPUT {OUTPUT}.skycell      SKYCELL   NONE       FPA        TRUE      NONE
+                                                     
+PPSUB.OUTPUT            OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.MASK       OUTPUT {OUTPUT}.mask.fits    MASK      NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.VARIANCE   OUTPUT {OUTPUT}.wt.fits      VARIANCE  NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.SOURCES    OUTPUT {OUTPUT}.cmf          CMF       NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.KERNELS    OUTPUT {OUTPUT}.subkernel    SUBKERNEL NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG1      OUTPUT {OUTPUT}.b1.jpg       JPEG      NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG2      OUTPUT {OUTPUT}.b2.jpg       JPEG      NONE       FPA        TRUE      NONE
+PPSUB.INVERSE           OUTPUT {OUTPUT}.inv.fits     IMAGE     NONE       FPA        TRUE      NONE
+PPSUB.INVERSE.MASK      OUTPUT {OUTPUT}.inv.mask.fits MASK     NONE       FPA        TRUE      NONE
+PPSUB.INVERSE.VARIANCE  OUTPUT {OUTPUT}.inv.wt.fits  VARIANCE  NONE       FPA        TRUE      NONE
+PPSUB.INVERSE.SOURCES   OUTPUT {OUTPUT}.inv.cmf      CMF       NONE       FPA        TRUE      NONE
+PPSUB.CONFIG            OUTPUT {OUTPUT}.ppSub.mdc    TEXT      NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV        OUTPUT {OUTPUT}.inConv.fits     IMAGE  COMP_SUB   FPA        TRUE      NONE
+PPSUB.INPUT.CONV.MASK   OUTPUT {OUTPUT}.inConv.mk.fits  MASK   COMP_MASK  FPA        TRUE      NONE
+PPSUB.INPUT.CONV.VARIANCE OUTPUT {OUTPUT}.inConv.wt.fits VARIANCE COMP_WT FPA        TRUE      NONE
+PPSUB.REF.CONV        	OUTPUT {OUTPUT}.refConv.fits    IMAGE  COMP_SUB   FPA        TRUE      NONE
+PPSUB.REF.CONV.MASK   	OUTPUT {OUTPUT}.refConv.mk.fits MASK   COMP_MASK  FPA        TRUE      NONE
+PPSUB.REF.CONV.VARIANCE OUTPUT {OUTPUT}.refConv.wt.fits VARIANCE COMP_WT  FPA        TRUE      NONE
+					     
+PPSTACK.OUTPUT          OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.MASK     OUTPUT {OUTPUT}.mask.fits    MASK      NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.weight.fits  VARIANCE  NONE       FPA        TRUE      NONE
+PPSTACK.TARGET.PSF      OUTPUT {OUTPUT}.target.psf   PSF       NONE       CHIP       TRUE      NONE
+PPSTACK.CONV.KERNEL     OUTPUT {OUTPUT}.{FILE.INDEX}.kernel SUBKERNEL NONE FPA       TRUE      NONE
+PPSTACK.OUTPUT.JPEG1    OUTPUT {OUTPUT}.b1.jpg       JPEG      NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG2    OUTPUT {OUTPUT}.b2.jpg       JPEG      NONE       FPA        TRUE      NONE
+PPSTACK.CONFIG          OUTPUT {OUTPUT}.ppStack.mdc  TEXT      NONE       FPA        TRUE      NONE
+                                             
+PPSTAMP.OUTPUT          OUTPUT {OUTPUT}.fits         IMAGE     COMP_IMG   FPA        TRUE      NONE
+PPSTAMP.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits      MASK      COMP_MASK  FPA        TRUE      NONE
+PPSTAMP.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits      VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSTAMP.CHIP            OUTPUT {OUTPUT}.ch.fits      IMAGE     NONE       CHIP       FALSE     NONE
+                                                     
+PPSIM.OUTPUT            OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SPLIT
+PPSIM.FAKE.CHIP         OUTPUT {OUTPUT}.fake.fits    IMAGE     NONE       FPA        TRUE      SIMPLE
+PPSIM.FORCE.CHIP        OUTPUT {OUTPUT}.force.fits   IMAGE     NONE       FPA        TRUE      SIMPLE
+PPSIM.SOURCES           OUTPUT {OUTPUT}.cmf          CMF       NONE       FPA        TRUE      NONE
+PPSIM.FAKE.SOURCES      OUTPUT {OUTPUT}.fake.cmf     CMF       NONE       FPA        TRUE      NONE
+PPSIM.FORCE.SOURCES     OUTPUT {OUTPUT}.force.cmf    CMF       NONE       FPA        TRUE      NONE
+                                                     
+PPARITH.OUTPUT.IMAGE    OUTPUT {OUTPUT}.fits         IMAGE     NONE       FPA        TRUE      SIMPLE
+PPARITH.OUTPUT.MASK     OUTPUT {OUTPUT}.fits         MASK      NONE       FPA        TRUE      SIMPLE
+
+PPSKYCELL.JPEG1    	OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg JPEG NONE    CHIP       TRUE      NONE
+PPSKYCELL.JPEG2    	OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg JPEG NONE    CHIP       TRUE      NONE
+
+LOG.IMFILE              OUTPUT {OUTPUT}.imfile.log   TEXT      NONE       FPA        TRUE      NONE
+LOG.EXP                 OUTPUT {OUTPUT}.exp.log      TEXT      NONE       FPA        TRUE      NONE
+
+TRACE.IMFILE            OUTPUT {OUTPUT}.imfile.trace TEXT      NONE       FPA        TRUE      NONE
+TRACE.EXP               OUTPUT {OUTPUT}.exp.trace    TEXT      NONE       FPA        TRUE      NONE
Index: /branches/pap/ippconfig/simmosaic/filerules-split.mdc
===================================================================
--- /branches/pap/ippconfig/simmosaic/filerules-split.mdc	(revision 28003)
+++ /branches/pap/ippconfig/simmosaic/filerules-split.mdc	(revision 28003)
@@ -0,0 +1,259 @@
+### File rules for PHU=CHIP, EXT=CELL (eg, GPC1)
+### this file specifies compression types for various output files
+### The default type of NONE means no compression
+
+# for basic chip analysis, psphot should produce SPLIT output
+# for basic camera analysis, psastro should produce MEF output
+PSPHOT.OUTPUT        STR PSPHOT.OUT.CMF.SPL
+PSASTRO.INPUT        STR PSASTRO.INPUT.CMF
+PSPHOT.PSF.SAVE      STR PSPHOT.PSF.RAW.SAVE
+
+SOURCE.PLOT.MOMENTS  STR SOURCE.PLOT.RAW.MOMENTS
+SOURCE.PLOT.PSFMODEL STR SOURCE.PLOT.RAW.PSFMODEL
+SOURCE.PLOT.APRESID  STR SOURCE.PLOT.RAW.APRESID
+
+# PSASTRO.OUTPUT     STR PSASTRO.OUT.CMF.MEF
+# PSASTRO.OUTPUT.SPL STR PSASTRO.OUT.CMF.SPL
+# PSASTRO.OUTPUT.MEF STR PSASTRO.OUT.CMF.MEF
+
+### input file definitions
+### use @DETDB entries to get the detrend images from the database
+### replace @DETDB with @FILES if you want to require it from the 
+### command line, or with an explicit name to require a specific file
+TYPE                    INPUT    FILENAME.RULE DATA.LEVEL FILE.TYPE
+
+## files used by ppImage
+PPIMAGE.INPUT           INPUT    @FILES        CHIP       IMAGE
+PPIMAGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PPIMAGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+PPIMAGE.INPUT.PSF       INPUT    @FILES        CHIP       PSF
+PPIMAGE.INPUT.SRC       INPUT    @FILES        CHIP       CMF
+PPIMAGE.MASK            INPUT    @DETDB        CHIP       MASK
+PPIMAGE.BIAS            INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.DARK            INPUT    @DETDB        CHIP       DARK
+PPIMAGE.FLAT            INPUT    @DETDB        CHIP       IMAGE
+PPIMAGE.FRINGE     	INPUT 	 @DETDB        CHIP       FRINGE
+PPIMAGE.SHUTTER         INPUT    @DETDB        CHIP       IMAGE
+
+## Files used by ppMerge
+PPMERGE.INPUT           INPUT    @FILES        CHIP       IMAGE
+PPMERGE.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PPMERGE.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+
+## files used to build and apply the flat-field correction images
+DVOCORR.INPUT      	INPUT 	 @FILES        CHIP       IMAGE
+DVOCORR.REFHEAD    	INPUT 	 @FILES        CHIP       HEADER
+DVOFLAT.INPUT      	INPUT 	 @FILES        CHIP       IMAGE
+DVOFLAT.CORR       	INPUT 	 @DETDB        CHIP       IMAGE
+
+## files used by psphot
+PSPHOT.LOAD             INPUT    @FILES        CHIP       IMAGE
+PSPHOT.INPUT            INPUT    @FILES        CHIP       IMAGE
+PSPHOT.MASK             INPUT    @FILES        CHIP       MASK     
+PSPHOT.VARIANCE         INPUT    @FILES        CHIP       VARIANCE     
+PSPHOT.PSF.LOAD         INPUT    @FILES        CHIP       PSF       
+PSPHOT.INPUT.CMF        INPUT    @FILES        CHIP       CMF       
+
+## files used by psastro 
+PSASTRO.INPUT.CMP       INPUT    @FILES        CHIP       CMP
+PSASTRO.INPUT.CMF       INPUT    @FILES        CHIP       CMF
+PSASTRO.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PSASTRO.REFMASK         INPUT    @DETDB        CHIP       MASK
+PSASTRO.WCS             INPUT    @FILES        CHIP       WCS
+PSASTRO.MODEL           INPUT    @DETDB        FPA        ASTROM
+
+PSASTRO.EXTRACT.ASTROM  INPUT    @FILES        CHIP       CMF
+PSASTRO.EXTRACT.INPUT   INPUT    @FILES        CHIP       IMAGE
+
+## files used by pswarp
+PSWARP.INPUT            INPUT    @FILES        CHIP       IMAGE
+PSWARP.VARIANCE         INPUT    @FILES        CHIP       VARIANCE
+PSWARP.MASK             INPUT    @FILES        CHIP       MASK
+PSWARP.SKYCELL          INPUT    @FILES        FPA        IMAGE
+PSWARP.ASTROM           INPUT    @FILES        CHIP       CMF
+
+## files used by ppsub
+PPSUB.INPUT             INPUT    @FILES        FPA        IMAGE
+PPSUB.INPUT.MASK        INPUT    @FILES        FPA        MASK
+PPSUB.INPUT.VARIANCE    INPUT    @FILES        FPA        VARIANCE
+PPSUB.INPUT.SOURCES    	INPUT 	 @FILES        FPA        CMF
+PPSUB.REF               INPUT    @FILES        FPA        IMAGE
+PPSUB.REF.MASK          INPUT    @FILES        FPA        MASK
+PPSUB.REF.VARIANCE      INPUT    @FILES        FPA        VARIANCE
+PPSUB.REF.SOURCES    	INPUT 	 @FILES        FPA        CMF
+
+## files used by ppstack
+PPSTACK.INPUT           INPUT    @FILES        FPA        IMAGE
+PPSTACK.INPUT.MASK      INPUT    @FILES        FPA        MASK
+PPSTACK.INPUT.VARIANCE  INPUT    @FILES        FPA        VARIANCE
+PPSTACK.INPUT.PSF  	INPUT 	 @FILES        CHIP       PSF
+PPSTACK.INPUT.SOURCES   INPUT    @FILES        FPA        CMF
+
+## files used by ppstamp
+PPSTAMP.INPUT           INPUT    @FILES        CHIP       IMAGE
+PPSTAMP.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+PPSTAMP.INPUT.VARIANCE  INPUT    @FILES        CHIP       VARIANCE
+
+# files used by pparith
+PPARITH.INPUT.IMAGE     INPUT    @FILES        CHIP       IMAGE
+PPARITH.INPUT.MASK      INPUT    @FILES        CHIP       MASK
+
+PPSKYCELL.IMAGE      	INPUT 	 @FILES        CHIP       IMAGE
+PPSKYCELL.MASK      	INPUT 	 @FILES        CHIP       MASK
+
+PPSIM.INPUT             INPUT    @FILES        CHIP       IMAGE     
+PPSIM.REAL.SOURCES      INPUT    @FILES        CHIP       CMF       
+
+### output file definitions
+TYPE                    OUTPUT FILENAME.RULE                     FILE.TYPE FITS.TYPE  DATA.LEVEL FILE.SAVE FILE.FORMAT
+PPIMAGE.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     COMP_IMG   CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.VARIANCE OUTPUT {OUTPUT}.{CHIP.NAME}.wt.fits      VARIANCE  COMP_WT    CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.DETMASK  OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     DET_MASK   CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.DETREND  OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     COMP_DET   CHIP       TRUE      NONE
+PPIMAGE.OUTPUT.RESID    OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     COMP_SUB   CHIP       TRUE      NONE
+PPIMAGE.CONFIG          OUTPUT {OUTPUT}.{CHIP.NAME}.ppImage.mdc  TEXT      NONE       CHIP       TRUE      NONE
+	        									        
+PPIMAGE.CHIP            OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     COMP_IMG   CHIP       TRUE      NONE
+PPIMAGE.CHIP.DETMASK    OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     NONE       CHIP       TRUE      NONE
+PPIMAGE.CHIP.MASK       OUTPUT {OUTPUT}.{CHIP.NAME}.ch.mk.fits   MASK      COMP_MASK  CHIP       TRUE      NONE
+PPIMAGE.CHIP.VARIANCE   OUTPUT {OUTPUT}.{CHIP.NAME}.ch.wt.fits   VARIANCE  COMP_WT    CHIP       TRUE      NONE
+PPIMAGE.CHIP.RESID      OUTPUT {OUTPUT}.{CHIP.NAME}.ch.fits      IMAGE     COMP_SUB   CHIP       TRUE      NONE
+		        									        
+PPIMAGE.OUTPUT.FPA1     OUTPUT {OUTPUT}.b1.fits                  IMAGE     NONE       FPA        TRUE      NONE
+PPIMAGE.OUTPUT.FPA2     OUTPUT {OUTPUT}.b2.fits                  IMAGE     NONE       FPA        TRUE      NONE
+		        									        
+PPIMAGE.BIN1            OUTPUT {OUTPUT}.{CHIP.NAME}.b1.fits      IMAGE     NONE       CHIP       TRUE      NONE
+PPIMAGE.BIN2            OUTPUT {OUTPUT}.{CHIP.NAME}.b2.fits      IMAGE     NONE       CHIP       TRUE      NONE
+		        									        
+PPIMAGE.JPEG1           OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPIMAGE.JPEG2           OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
+
+PPIMAGE.STATS           OUTPUT {OUTPUT}.{CHIP.NAME}.stats        STATS     NONE       CHIP       TRUE      NONE
+
+## note: these use the  same output naming convention since they are used for different ppMerge runs
+PPMERGE.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         MASK      DET_MASK   CHIP       TRUE      NONE
+PPMERGE.OUTPUT.BIAS     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.DARK     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         DARK      NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.SHUTTER  OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.FLAT     OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.FRINGE   OUTPUT {OUTPUT}.{CHIP.NAME}.fits         FRINGE    NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.SIGMA    OUTPUT {OUTPUT}.{CHIP.NAME}.sigma.fits   IMAGE     NONE       CHIP       TRUE      NONE
+PPMERGE.OUTPUT.COUNT    OUTPUT {OUTPUT}.{CHIP.NAME}.count.fits   IMAGE     NONE       CHIP       TRUE      NONE
+		        									        
+DVOCORR.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.fc.fits      IMAGE     NONE       CHIP       TRUE      NONE
+DVOFLAT.OUTPUT          OUTPUT {OUTPUT}.{CHIP.NAME}.co.fits      IMAGE     NONE       CHIP       TRUE      NONE
+		        									        
+PSPHOT.RESID            OUTPUT {OUTPUT}.{CHIP.NAME}.res.fits     IMAGE     COMP_SUB   CHIP       TRUE      NONE
+PSPHOT.BACKGND          OUTPUT {OUTPUT}.{CHIP.NAME}.bck.fits     IMAGE     COMP_IMG   CHIP       TRUE      NONE
+PSPHOT.BACKSUB          OUTPUT {OUTPUT}.{CHIP.NAME}.sub.fits     IMAGE     COMP_SUB   CHIP       TRUE      NONE
+PSPHOT.BACKMDL          OUTPUT {OUTPUT}.{CHIP.NAME}.mdl.fits     IMAGE     COMP_IMG   CHIP       TRUE      NONE
+PSPHOT.BACKMDL.MEF      OUTPUT {OUTPUT}.mdl.fits                 IMAGE     COMP_IMG   CHIP       TRUE      NONE
+		        									        
+PSPHOT.OUTPUT.RAW       OUTPUT {OUTPUT}.{CHIP.NAME}              RAW       NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.SX        OUTPUT {OUTPUT}.{CHIP.NAME}.sx           SX        NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.OBJ       OUTPUT {OUTPUT}.{CHIP.NAME}.obj          OBJ       NONE       CHIP       TRUE      NONE
+PSPHOT.OUTPUT.CMP       OUTPUT {OUTPUT}.{CHIP.NAME}.cmp          CMP       NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.SPL      OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF       NONE       CHIP       TRUE      NONE
+PSPHOT.OUT.CMF.MEF      OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      MEF
+PSPHOT.PSF.RAW.SAVE     OUTPUT {OUTPUT}.{CHIP.NAME}.psf          PSF       NONE       CHIP       TRUE      MEF
+PSPHOT.PSF.SKY.SAVE     OUTPUT {OUTPUT}.psf          		 PSF       NONE       FPA        TRUE      MEF
+		        									        
+SOURCE.PLOT.RAW.MOMENTS  OUTPUT {OUTPUT}.{CHIP.NAME}.mnt.png      KAPA      NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.RAW.PSFMODEL OUTPUT {OUTPUT}.{CHIP.NAME}.psf.png      KAPA      NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.RAW.APRESID  OUTPUT {OUTPUT}.{CHIP.NAME}.dap.png      KAPA      NONE       CHIP       TRUE      NONE
+		        									        
+SOURCE.PLOT.SKY.MOMENTS  OUTPUT {OUTPUT}.mnt.png      KAPA      NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.SKY.PSFMODEL OUTPUT {OUTPUT}.psf.png      KAPA      NONE       CHIP       TRUE      NONE
+SOURCE.PLOT.SKY.APRESID  OUTPUT {OUTPUT}.dap.png      KAPA      NONE       CHIP       TRUE      NONE
+
+# PSASTRO.OUTPUT.CMP      OUTPUT {OUTPUT}.{CHIP.NAME}.smp          CMP       NONE       CHIP       TRUE      NONE
+# PSASTRO.OUT.CMF.SPL     OUTPUT {OUTPUT}.{CHIP.NAME}.smf          CMF       NONE       CHIP       TRUE      NONE
+# PSASTRO.OUT.CMF.MEF     OUTPUT {OUTPUT}.smf                      CMF       NONE       FPA        TRUE      MEF
+PSASTRO.OUT.MODEL       OUTPUT {OUTPUT}.asm               ASTROM.MODEL     NONE       FPA        TRUE      NONE
+PSASTRO.OUT.REFSTARS    OUTPUT {OUTPUT}.aref.fits         ASTROM.REFSTARS  NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT          OUTPUT {OUTPUT}.smf                      CMF       NONE       FPA        TRUE      MEF
+PSASTRO.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      NONE
+PSASTRO.CONFIG          OUTPUT {OUTPUT}.psastro.mdc              TEXT      NONE       FPA        TRUE      NONE
+PSASTRO.OUTPUT.MASK     OUTPUT {OUTPUT}.{CHIP.NAME}.mk.fits      MASK      COMP_MASK  CHIP       TRUE      NONE
+		        									        
+PSWARP.OUTPUT           OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PSWARP.OUTPUT.MASK      OUTPUT {OUTPUT}.mask.fits                MASK      COMP_MASK  FPA        TRUE      NONE
+PSWARP.OUTPUT.VARIANCE  OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PSWARP.OUTPUT.SOURCES   OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
+PSWARP.BIN1             OUTPUT {OUTPUT}.b1.fits                  IMAGE     NONE       FPA        TRUE      NONE
+PSWARP.BIN2             OUTPUT {OUTPUT}.b2.fits                  IMAGE     NONE       FPA        TRUE      NONE
+PSWARP.CONFIG           OUTPUT {OUTPUT}.pswarp.mdc               TEXT      NONE       FPA        TRUE      NONE
+		        									        
+SKYCELL.STATS           OUTPUT {OUTPUT}.stats                    STATS     NONE       FPA        TRUE      NONE
+SKYCELL.TEMPLATE        OUTPUT {OUTPUT}.skycell                  SKYCELL   NONE       FPA        TRUE      NONE
+		        									        
+PPSUB.OUTPUT            OUTPUT {OUTPUT}.fits                     IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.OUTPUT.MASK       OUTPUT {OUTPUT}.mask.fits                MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.OUTPUT.VARIANCE   OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSUB.OUTPUT.SOURCES    OUTPUT {OUTPUT}.cmf                      CMF       NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.KERNELS    OUTPUT {OUTPUT}.subkernel                SUBKERNEL NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG1      OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSUB.OUTPUT.JPEG2      OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSUB.INVERSE           OUTPUT {OUTPUT}.inv.fits                 IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.INVERSE.MASK      OUTPUT {OUTPUT}.inv.mask.fits            MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.INVERSE.VARIANCE  OUTPUT {OUTPUT}.inv.wt.fits              VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSUB.INVERSE.SOURCES   OUTPUT {OUTPUT}.inv.cmf                  CMF       NONE       FPA        TRUE      NONE
+PPSUB.CONFIG            OUTPUT {OUTPUT}.ppSub.mdc                TEXT      NONE       FPA        TRUE      NONE
+PPSUB.INPUT.CONV        OUTPUT {OUTPUT}.inConv.fits              IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.INPUT.CONV.MASK   OUTPUT {OUTPUT}.inConv.mk.fits           MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.INPUT.CONV.VARIANCE OUTPUT {OUTPUT}.inConv.wt.fits         VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSUB.REF.CONV          OUTPUT {OUTPUT}.refConv.fits             IMAGE     COMP_SUB   FPA        TRUE      NONE
+PPSUB.REF.CONV.MASK     OUTPUT {OUTPUT}.refConv.mk.fits          MASK      COMP_MASK  FPA        TRUE      NONE
+PPSUB.REF.CONV.VARIANCE OUTPUT {OUTPUT}.refConv.wt.fits          VARIANCE  COMP_WT    FPA        TRUE      NONE
+											        
+PPSTACK.OUTPUT          OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PPSTACK.OUTPUT.MASK     OUTPUT {OUTPUT}.mask.fits                MASK      COMP_MASK  FPA        TRUE      NONE
+PPSTACK.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSTACK.TARGET.PSF      OUTPUT {OUTPUT}.target.psf               PSF       NONE       CHIP       TRUE      NONE
+PPSTACK.CONV.KERNEL     OUTPUT {OUTPUT}.{FILE.INDEX}.kernel      SUBKERNEL NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG1	OUTPUT {OUTPUT}.b1.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSTACK.OUTPUT.JPEG2	OUTPUT {OUTPUT}.b2.jpg                   JPEG      NONE       FPA        TRUE      NONE
+PPSTACK.CONFIG          OUTPUT {OUTPUT}.ppStack.mdc              TEXT      NONE       FPA        TRUE      NONE
+
+PPSTAMP.OUTPUT          OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   FPA        TRUE      NONE
+PPSTAMP.OUTPUT.MASK     OUTPUT {OUTPUT}.mk.fits                  MASK      COMP_MASK  FPA        TRUE      NONE
+PPSTAMP.OUTPUT.VARIANCE OUTPUT {OUTPUT}.wt.fits                  VARIANCE  COMP_WT    FPA        TRUE      NONE
+PPSTAMP.CHIP            OUTPUT {OUTPUT}.ch.fits                  IMAGE     NONE       CHIP       FALSE     MEF
+		        									        
+PPSIM.OUTPUT            OUTPUT {OUTPUT}.{CHIP.NAME}.fits         IMAGE     NONE       CHIP       TRUE      SPLIT
+PPSIM.FAKE.CHIP        	OUTPUT {OUTPUT}.{CHIP.NAME}.fake.fits    IMAGE     NONE       CHIP       TRUE      NONE
+PPSIM.FORCE.CHIP       	OUTPUT {OUTPUT}.{CHIP.NAME}.force.fits   IMAGE     NONE       CHIP       TRUE      NONE
+PPSIM.SOURCES           OUTPUT {OUTPUT}.{CHIP.NAME}.cmf          CMF       NONE       CHIP       TRUE      NONE
+PPSIM.FAKE.SOURCES     	OUTPUT {OUTPUT}.{CHIP.NAME}.fake.cmf     CMF       NONE       CHIP       TRUE      NONE
+PPSIM.FORCE.SOURCES    	OUTPUT {OUTPUT}.{CHIP.NAME}.force.cmf    CMF       NONE       CHIP       TRUE      NONE
+
+PPARITH.OUTPUT.IMAGE   	OUTPUT {OUTPUT}.fits                     IMAGE     COMP_IMG   CHIP       TRUE      NONE
+PPARITH.OUTPUT.MASK    	OUTPUT {OUTPUT}.fits                     MASK      COMP_MASK  CHIP       TRUE      NONE
+		       										        
+PPSKYCELL.JPEG1    	OUTPUT {OUTPUT}.{FILE.INDEX}.b1.jpeg     JPEG      NONE       CHIP       TRUE      NONE
+PPSKYCELL.JPEG2    	OUTPUT {OUTPUT}.{FILE.INDEX}.b2.jpeg     JPEG      NONE       CHIP       TRUE      NONE
+
+LOG.IMFILE             	OUTPUT {OUTPUT}.{CHIP.NAME}.log          TEXT      NONE       CHIP       TRUE      NONE
+LOG.EXP                	OUTPUT {OUTPUT}.log                      TEXT      NONE       FPA        TRUE      NONE
+		       										        
+TRACE.IMFILE           	OUTPUT {OUTPUT}.{CHIP.NAME}.trace        TEXT      NONE       CHIP       TRUE      NONE
+TRACE.EXP              	OUTPUT {OUTPUT}.trace                    TEXT      NONE       FPA        TRUE      NONE
+
+
+# {FPA.OBS}
+# {FPA.NAME}
+# {CHIP.NAME}
+# {CHIP.ID}
+# {CHIP.N}
+# {CHIP.NUM}
+# {CELL.NAME}
+# {CELL.N}
+# {CELL.NUM}
+# {EXTNAME}
+# {FILTER}
+# {FILTER.ID}
+# {CAMERA}
+# {INSTRUMENT}
+# {DETECTOR}
+# {TELESCOPE}
Index: /branches/pap/ippconfig/simmosaic/format_split.config
===================================================================
--- /branches/pap/ippconfig/simmosaic/format_split.config	(revision 28002)
+++ /branches/pap/ippconfig/simmosaic/format_split.config	(revision 28003)
@@ -59,12 +59,14 @@
 	FPA.DEC		STR	DEC
 	FPA.OBJECT	STR	OBJECT
-	FPA.TIME	STR	MJD-OBS
+	FPA.TIME	STR	DATE-OBS UTC-OBS
 	FPA.EXPOSURE	STR	EXPTIME
 	CELL.EXPOSURE	STR	EXPTIME
 	CELL.DARKTIME	STR	DARKTIME
-	CELL.TIME	STR	MJD-OBS
+	CELL.TIME	STR	DATE-OBS UTC-OBS
 	CELL.XBIN	STR	XBIN
 	CELL.YBIN	STR	YBIN
 END
+#FPA.TIME	STR	MJD-OBS
+#CELL.TIME	STR	MJD-OBS
 
 # Default PS concepts that may be specified by value
@@ -120,5 +122,7 @@
 	FPA.RA		STR	HOURS
 	FPA.DEC		STR	DEGREES
-	FPA.TIME	STR	MJD
-	CELL.TIME	STR	MJD
+	FPA.TIME	STR	SEPARATE,YEAR.FIRST
+	CELL.TIME	STR	SEPARATE,YEAR.FIRST
 END
+#FPA.TIME	STR	MJD
+#CELL.TIME	STR	MJD
Index: /branches/pap/ippconfig/simmosaic/format_together.config
===================================================================
--- /branches/pap/ippconfig/simmosaic/format_together.config	(revision 28002)
+++ /branches/pap/ippconfig/simmosaic/format_together.config	(revision 28003)
@@ -54,12 +54,14 @@
 	FPA.DEC		STR	DEC
 	FPA.OBJECT	STR	OBJECT
-	FPA.TIME	STR	MJD-OBS
+	FPA.TIME	STR	DATE-OBS UTC-OBS
 	FPA.EXPOSURE	STR	EXPTIME
 	CELL.EXPOSURE	STR	EXPTIME
 	CELL.DARKTIME	STR	DARKTIME
-	CELL.TIME	STR	MJD-OBS
+	CELL.TIME	STR	DATE-OBS UTC-OBS
 	CELL.XBIN	STR	XBIN
 	CELL.YBIN	STR	YBIN
 END
+#FPA.TIME	STR	MJD-OBS
+#CELL.TIME	STR	MJD-OBS
 
 # Default PS concepts that may be specified by value
@@ -115,5 +117,7 @@
 	FPA.RA		STR	HOURS
 	FPA.DEC		STR	DEGREES
-	FPA.TIME	STR	MJD
-	CELL.TIME	STR	MJD
+	FPA.TIME	STR	SEPARATE,YEAR.FIRST
+	CELL.TIME	STR	SEPARATE,YEAR.FIRST
 END
+#FPA.TIME	STR	MJD
+#CELL.TIME	STR	MJD
Index: /branches/pap/ippconfig/simmosaic/notes-8.17.09.txt
===================================================================
--- /branches/pap/ippconfig/simmosaic/notes-8.17.09.txt	(revision 28003)
+++ /branches/pap/ippconfig/simmosaic/notes-8.17.09.txt	(revision 28003)
@@ -0,0 +1,93 @@
+Simmosaic Simtest Notes
+
+setup:
+------------------
+in pantasks:
+$SIMTEST_CAMERA = SIMMOSAIC
+
+image injection error:
+-------------------
+edit ippconfig/simmosaic/ppImage.config
+->remove line APPLY.TILTYSTREAK
+
+TIME errors reported during image injection
+------------------
+edit ippconfig/simmosaic/format_split.config
+edit ippconfig/simmosaic/format_together.config
+->in ~/simmosaic/fix-files
+
+output format error:
+-------------------
+edit ippconfig/simmosaic/filerules-*
+->in ~/simmosaic/fix-files/filerules
+
+ppImage error in detrend_resid_exp.pl:
+-------------------
+"failed to find class ID fpa in normalization table"
+edit ippconfig/simmosaic/ppImage.config
+NORM.CLASS              STR     CHIP             # How to find the per-class normalizations
+edit line 13
+-> in fix-files/ppImage.config
+
+edit ippconfig/simmosaic/ppImage.config
+MASK             BOOL    FALSE	# Mask bad pixels
+->in ~/simmosaic/fix-files
+
+ppImage seg fault:
+---------------------
+ipp/psModules/src/detrend/pmShutterCorrection.c
+breaks in pmShutterCorrectionGuess at line:
+    // fit a line and extrapolate the fit to counts = A (1 + dTk/dTo) : exptime = dTo
+    if (!psVectorFitPolynomial1D (line, NULL, 0, tmpY, NULL, tmpX)) {
+        printf("Unable to fit for the reference offset.\n");
+        printf("tmpX0: %f, tmpX1: %f, tmpY0: %f, tmpY1: %f\n", tmpX->data.F32[0], tmpX->data.F32[1], tmpY->data.F32[0], tmpY->data.F32[1]);
+        goto GUESS_ERROR;
+    }
+see ~/simmosaic/baz.Chip10.log generated by 
+detrend_stack.pl --threads @MAX_THREADS@ --det_id 3 --iteration 0 --class_id Chip10 --det_type SHUTTER --camera SIMMOSAIC --outroot file:///netdisks/panstarrs/giebink/simmosaic/baz --redirect-output --dbname simtest_mosaic --verbose --save-temps
+
+/netdisks/panstarrs/giebink/psconfig/default.lin64/bin/ppMerge .toad.Chip10.list file:///netdisks/panstarrs/giebink/simmosaic/toad -recipe PPMERGE PPMERGE_SHUTTER -type SHUTTER -stats file:///netdisks/panstarrs/giebink/simmosaic/toad.Chip10.stats -recipe PPSTATS DARKSTATS -tracedest file:///netdisks/panstarrs/giebink/simmosaic/toad.Chip10.trace -log file:///netdisks/panstarrs/giebink/simmosaic/toad.Chip10.log -dbname simtest_mosaic -threads @MAX_THREADS@
+
+Unable to fit for the reference offset.
+tmpX0: 0.977549, tmpX1: 0.977389, tmpY0: 10.000000, tmpY1: 20.000000
+
+added workaround to: 
+ipp/psModules/src/detrend/pmShutterCorrection.c
+line 195:
+//    psFree(corr);
+//    return NULL;
+    corr->scale = 0.5;
+    corr->offset = 0.5;
+    corr->offref = 0.5;
+
+psastro error in camera_exp.pl:
+--------------------
+photcode r not found in photcode table
+cp simtest/psastro.config simmosaic/psastro.config
+->Had to remove:
+PSASTRO.GRID.OFFSET    F32    500.
+PSASTRO.GRID.SCALE     F32     50.
+->in ~/simmosaic/fix-files
+->not sure how much has be put in the file
+
+addstar error in cam_exp.pl:
+--------------------
+missing MJD Keyword MJD-OBS
+->cp simtest/dvo.config simmosaic/dvo.config
+
+psastro error:
+---------------------
+ipp/psModules/src/astrom/pmAstrometryObjects.c
+programming error for: camera_exp.pl --exp_tag simtest.005.001.Chip00.74 --cam_id 16 --camera SIMMOSAIC --outroot /data/ipp002.0/simmosaic/cam/cam --redirect-output --run-state new --dvodb /data/ipp002.0/simmosaic/DVO --dbname simtest_mosaic --verbose
+edit pantasks/modules/simtest.basic.config
+to set all object exposures to 240s
+also, edit simmosaic/psastro.config
+PSASTRO.PIXEL.SCALE    F32  1.0
+->in ~/simmosaic/file-fix
+
+psastro/ppStack error:
+--------------------
+ipp/psLib/src/fits/psFits.c
+ -> p_psFitsError (psFits.c:74): I/O error
+      Could not find HDU with EXTNAME = 'MATCHED_REFS'
+According to Paul, this should be ignored.
Index: /branches/pap/ippconfig/simmosaic/ppImage.config
===================================================================
--- /branches/pap/ippconfig/simmosaic/ppImage.config	(revision 28002)
+++ /branches/pap/ippconfig/simmosaic/ppImage.config	(revision 28003)
@@ -1,127 +1,104 @@
-### ppImage recipe configuration file for simulated test camera
-
-# List of tasks to perform
-
-BASE.FITS       BOOL    FALSE           # Save base detrended image?
-CHIP.FITS       BOOL    TRUE            # Save chip-mosaicked image?
-BIN1.FITS       BOOL    TRUE            # Save 1st binned chip image?
-BIN2.FITS       BOOL    TRUE            # Save 2nd binned chip image?
 
 # binned output image options
-BIN1.XBIN               S32     8
-BIN1.YBIN               S32     8
-BIN2.XBIN               S32     64
-BIN2.YBIN               S32     64
-
-# Overscan subtraction
-OVERSCAN.SINGLE         BOOL    FALSE           # Reduce overscan to a single value?
-OVERSCAN.FIT            STR     POLYNOMIAL      # NONE | POLYNOMIAL | SPLINE
-OVERSCAN.ORDER          S32     7               # Order of polynomial fit
-OVERSCAN.STAT           STR     MEAN            # MEAN | MEDIAN
-
-# How to select the appropriate detrend image
+BIN1.XBIN               S32      16
+BIN1.YBIN               S32      16
+BIN2.XBIN               S32     150
+BIN2.YBIN               S32     150
+
+OVERSCAN.SINGLE         BOOL    FALSE            # Reduce overscan to a single value?
+OVERSCAN.STAT           STR     MEDIAN
+OVERSCAN.BOXCAR         S32     3
+
+# Normalization class
+NORM.CLASS              STR     CHIP             # How to find the per-class normalizations
+
+OLDDARK                 BOOL    FALSE
+
+# use the deburned image instead of the raw, if it exists
+USE.DEBURNED.IMAGE      BOOL    TRUE           # use burntool-repaired image?
+
+# crosstalk measurements : only valid for GPC1 for now
+CROSSTALK.MEASURE  BOOL    FALSE          # Subtract model background?
+CROSSTALK.CORRECT  BOOL    FALSE           # Subtract model background?
+
+## XXX use these local variations until we are building real detrend images
+
 DETREND.CONSTRAINTS  METADATA
   BIAS METADATA
   END
+  DARK METADATA
+    EXPTIME STR FPA.EXPOSURE
+  END
+  FLAT METADATA
+    FILTER  STR FPA.FILTERID
+  END
+  FLATCORR METADATA
+    FILTER   STR FPA.FILTERID
+  END
+  FRINGE METADATA
+    FILTER   STR FPA.FILTERID
+  END
+  SHUTTER METADATA
+  END
   MASK METADATA
-  END
-  DARK METADATA
-  END
-  FLAT METADATA
-    FILTER  STR FPA.FILTER
-  END
-  FRINGE METADATA
-    FILTER   STR FPA.FILTER
-  END
-  SHUTTER METADATA
-  END   
-END
-
-########################################################################################
-# Need the following in order to turn off overscan and shutter for the site-level recipe
-########################################################################################
+  END	
+  ASTROM METADATA
+  END	
+END
+
 
 # Standard chip processing
-CHIP   METADATA
+CHIP               METADATA
   BASE.FITS        BOOL    FALSE           # Save base detrended image?
   BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
   BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
   CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    TRUE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    TRUE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    TRUE            # Shutter correction
-  FLAT            BOOL    TRUE            # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    TRUE            # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Overscan subtraction only
-PPIMAGE_O         METADATA
-  BASE.FITS        BOOL    TRUE            # Save base detrended image?
-  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
-  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
-  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    FALSE           # Bias subtraction
-  DARK            BOOL    FALSE           # Dark subtraction
-  SHUTTER         BOOL    FALSE           # Shutter correction
-  FLAT            BOOL    FALSE           # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Dark subtraction only
-PPIMAGE_D         METADATA
-  BASE.FITS        BOOL    TRUE            # Save base detrended image?
-  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
-  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
-  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    FALSE           # Overscan subtraction
-  BIAS            BOOL    FALSE           # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    FALSE           # Shutter correction
-  FLAT            BOOL    FALSE           # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Shutter correction only
-PPIMAGE_S         METADATA
-  BASE.FITS        BOOL    TRUE            # Save base detrended image?
-  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
-  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
-  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    FALSE           # Overscan subtraction
-  BIAS            BOOL    FALSE           # Bias subtraction
-  DARK            BOOL    FALSE           # Dark subtraction
-  SHUTTER         BOOL    FALSE           # Shutter correction
-  FLAT            BOOL    FALSE           # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Overscan, bias, dark
-PPIMAGE_OBD      METADATA
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  REMNANCE         BOOL    FALSE           # Remnance masking
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BACKGROUND       BOOL    TRUE            # Subtract background?
+  CROSSTALK.MEASURE  BOOL  TRUE            # Subtract model background?
+END
+
+# Standard chip processing for areas with high stellar density
+# Turn remnance masking off --- it kills all the detector
+CHIP_DENSE_STARS	METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  REMNANCE         BOOL    FALSE           # Remnance masking
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BACKGROUND       BOOL    TRUE            # Subtract background?
+END
+
+
+# Overscan, bias
+PPIMAGE_OB         METADATA
   BASE.FITS        BOOL    TRUE            # Save base detrended image?
   BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
@@ -130,18 +107,122 @@
   CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
   CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    FALSE           # Shutter correction
-  FLAT            BOOL    FALSE           # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    FALSE           # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+END
+
+# Overscan, bias, dark
+PPIMAGE_OBD        METADATA
+  BASE.FITS        BOOL    TRUE            # Save base detrended image?
+  BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL  TRUE            # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL  FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+END
+
+# Overscan, bias, dark -- search for DARK_PREMASK
+PPIMAGE_DARKMASK_PROCESS METADATA
+  BASE.FITS        BOOL    TRUE            # Save base detrended image?
+  BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL  TRUE            # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL  FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+
+  DETREND.CONSTRAINTS  METADATA
+    DARK METADATA
+      DETTYPE STR DARK_PREMASK
+      EXPTIME STR FPA.EXPOSURE
+    END
+  END   
 END
 
 # Overscan, bias, dark, shutter
-PPIMAGE_OBDS      METADATA
+PPIMAGE_OBDS       METADATA
+  BASE.FITS          BOOL    TRUE            # Save base detrended image?
+  BASE.MASK.FITS     BOOL    TRUE            # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    TRUE            # Save base detrended image?
+  CHIP.FITS          BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS     BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN           BOOL    TRUE            # Overscan subtraction
+  BIAS               BOOL    FALSE           # Bias subtraction
+  DARK               BOOL    TRUE            # Dark subtraction
+  SHUTTER            BOOL    FALSE           # Shutter correction
+  FLAT               BOOL    FALSE           # Flat-field normalisation
+  MASK               BOOL    FALSE           # Mask bad pixels
+  FRINGE             BOOL    FALSE           # Fringe subtraction
+  PHOTOM             BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP        BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC      BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS          BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS          BOOL    TRUE            # Save 2nd binned chip image?
+END
+
+# Overscan, bias, dark, shutter
+PPIMAGE_FLATPROC_PREMASK       METADATA
+  BASE.FITS          BOOL    TRUE            # Save base detrended image?
+  BASE.MASK.FITS     BOOL    TRUE            # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    TRUE            # Save base detrended image?
+  CHIP.FITS          BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS     BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN           BOOL    TRUE            # Overscan subtraction
+  BIAS               BOOL    FALSE           # Bias subtraction
+  DARK               BOOL    TRUE            # Dark subtraction
+  SHUTTER            BOOL    FALSE           # Shutter correction
+  FLAT               BOOL    FALSE           # Flat-field normalisation
+  MASK               BOOL    FALSE           # Mask bad pixels
+  FRINGE             BOOL    FALSE           # Fringe subtraction
+  PHOTOM             BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP        BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC      BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS          BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS          BOOL    TRUE            # Save 2nd binned chip image?
+
+  DETREND.CONSTRAINTS  METADATA
+    DARK METADATA
+      DETTYPE STR DARK_PREMASK
+      EXPTIME STR FPA.EXPOSURE
+    END
+  END   
+END
+
+# Overscan, bias, dark, shutter
+PPIMAGE_OBDSF      METADATA
   BASE.FITS        BOOL    TRUE            # Save base detrended image?
   BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
@@ -150,18 +231,77 @@
   CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
   CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    TRUE            # Shutter correction
-  FLAT            BOOL    FALSE           # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Overscan, bias, dark, shutter, flat-field
-PPIMAGE_OBDSF     METADATA
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+END
+
+# Overscan, bias, dark, shutter, flat-field -- use FLAT_PREMASK
+PPIMAGE_FLATMASK_PROCESS      METADATA
+  BASE.FITS        BOOL    TRUE            # Save base detrended image?
+  BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL  TRUE            # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL  FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+
+  DETREND.CONSTRAINTS  METADATA
+    DARK METADATA
+      DETTYPE STR DARK_PREMASK
+      EXPTIME STR FPA.EXPOSURE
+    END
+    FLAT METADATA
+      DETTYPE STR FLAT_PREMASK
+      FILTER  STR FPA.FILTERID
+    END
+  END   
+END
+
+# Overscan, bias, dark, shutter, flat-field, fringe, photom, astrom
+PPIMAGE_DET_ONLY   METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  FPA1.FITS        BOOL    TRUE            # Save 1st binned fpa image? 
+  FPA2.FITS        BOOL    TRUE            # Save 2nd binned fpa image? 
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+END
+
+# Overscan, bias, dark, shutter, flat-field, fringe
+PPIMAGE_OBDSFR     METADATA
   BASE.FITS        BOOL    TRUE            # Save base detrended image?
   BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
@@ -170,73 +310,355 @@
   CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
   CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    TRUE            # Shutter correction
-  FLAT            BOOL    TRUE            # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Overscan, bias, dark, shutter, flat-field, fringe
-PPIMAGE_OBDSFR    METADATA
-  BASE.FITS        BOOL    TRUE            # Save base detrended image?
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  BACKGROUND       BOOL    TRUE            # Subtract background?
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+END
+
+# Overscan, bias, dark, shutter, flat-field, fringe, photom, astrom
+PPIMAGE_OBDSFRP    METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  BACKGROUND       BOOL    TRUE            # Subtract background?
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+END
+
+# Overscan, bias, dark, shutter, flat-field, fringe, photom, astrom
+PPIMAGE_OBDSFRA    METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  BACKGROUND       BOOL    TRUE            # Subtract background?
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+END
+
+# Overscan, bias, dark, shutter, flat-field, fringe, photom
+PPIMAGE_FLATCORR    METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+
+  DETREND.CONSTRAINTS  METADATA
+    BIAS METADATA
+    END
+    DARK METADATA
+      DETTYPE STR DARK_PREMASK
+      EXPTIME STR FPA.EXPOSURE
+    END
+    FLAT METADATA
+      DETTYPE STR FLAT_PREMASK
+      FILTER  STR FPA.FILTERID
+    END
+    FLATCORR METADATA
+      FILTER  STR FPA.FILTERID
+    END
+    FRINGE METADATA
+      FILTER   STR FPA.FILTERID
+    END
+    SHUTTER METADATA
+    END
+    MASK METADATA
+    END	
+    ASTROM METADATA
+    END	
+  END
+END
+
+# Overscan, bias, dark, shutter, flat-field, fringe, photom
+PPIMAGE_FLATTEST    METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    TRUE            # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    TRUE            # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE	# Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+
+  DETREND.CONSTRAINTS  METADATA
+    BIAS METADATA
+    END
+    DARK METADATA
+      EXPTIME STR FPA.EXPOSURE
+    END
+    FLAT METADATA
+      DETTYPE STR FLATTEST
+      FILTER  STR FPA.FILTERID
+    END
+    FRINGE METADATA
+      FILTER   STR FPA.FILTERID
+    END
+    SHUTTER METADATA
+    END
+    MASK METADATA
+    END	
+    ASTROM METADATA
+    END	
+  END
+END
+
+# Photometry and astrometry only (for pre-reduced data)
+PPIMAGE_PA         METADATA
+  BASE.FITS        BOOL    FALSE           # Save base detrended image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    FALSE           # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    FALSE           # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  BIN1.JPEG        BOOL    TRUE            # Save 1st binned jpeg?
+  BIN2.JPEG        BOOL    TRUE            # Save 2nd binned jpeg?
+  PHOTOM           BOOL    TRUE            # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+END
+
+# JPEG images for different types of residual images
+# Save JPEG from BIN1 for bias
+PPIMAGE_J1_RESID_B      METADATA
+  OVERSCAN         BOOL    FALSE           # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    FALSE           # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BASE.FITS        BOOL    FALSE           # Save base image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  BIN1.FITS        BOOL    FALSE           # Save 1st binned chip image?
+  BIN2.FITS        BOOL    FALSE           # Save 2nd binned chip image?
+  BIN1.JPEG        BOOL    TRUE            # Save 1st binned jpeg?
+  BIN2.JPEG        BOOL    FALSE           # Save 2nd binned jpeg?
+  BIN1.XBIN        S32     1               # Image is already binned
+  BIN1.YBIN        S32     1               # Image is already binned
+  BIN2.XBIN        S32     1               # Image is already binned
+  BIN2.YBIN        S32     1               # Image is already binned
+
+  # GPC1 has significant dark structures: use a wide greyscale range
+  PPIMAGE.JPEG1    METADATA
+    COLORMAP       STR     -greyscale
+    SCALE.MODE     STR     VALUE
+    SCALE.MIN      F32     -50.0
+    SCALE.MAX      F32     +50.0
+  END
+END
+
+# Save JPEG from BIN2 for bias
+PPIMAGE_J2_RESID_B        METADATA
+  OVERSCAN         BOOL    FALSE           # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    FALSE           # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BASE.FITS        BOOL    FALSE           # Save base image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  BIN1.FITS        BOOL    FALSE           # Save 1st binned chip image?
+  BIN2.FITS        BOOL    FALSE           # Save 2nd binned chip image?
+  BIN1.JPEG        BOOL    FALSE           # Save 1st binned jpeg?
+  BIN2.JPEG        BOOL    TRUE            # Save 2nd binned jpeg?
+  BIN1.XBIN        S32     1               # Image is already binned
+  BIN1.YBIN        S32     1               # Image is already binned
+  BIN2.XBIN        S32     1               # Image is already binned
+  BIN2.YBIN        S32     1               # Image is already binned
+
+  # GPC1 has significant dark structures: use a wide greyscale range
+  PPIMAGE.JPEG2    METADATA
+    COLORMAP       STR     -greyscale
+    SCALE.MODE     STR     VALUE
+    SCALE.MIN      F32     -50.0
+    SCALE.MAX      F32     +50.0
+  END
+END
+
+# Save JPEG from BIN1 for flat
+PPIMAGE_J1_RESID_F      METADATA
+  OVERSCAN         BOOL    FALSE           # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    FALSE           # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BASE.FITS        BOOL    FALSE           # Save base image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  BIN1.FITS        BOOL    FALSE           # Save 1st binned chip image?
+  BIN2.FITS        BOOL    FALSE           # Save 2nd binned chip image?
+  BIN1.JPEG        BOOL    TRUE            # Save 1st binned jpeg?
+  BIN2.JPEG        BOOL    FALSE           # Save 2nd binned jpeg?
+  BIN1.XBIN        S32     1               # Image is already binned
+  BIN1.YBIN        S32     1               # Image is already binned
+  BIN2.XBIN        S32     1               # Image is already binned
+  BIN2.YBIN        S32     1               # Image is already binned
+
+  PPIMAGE.JPEG1    METADATA
+    COLORMAP       STR     -greyscale
+    SCALE.MODE     STR     FRACTION
+    SCALE.MIN      F32     0.98
+    SCALE.MAX      F32     1.02
+  END
+END
+
+# Save JPEG from BIN2 for flat
+PPIMAGE_J2_RESID_F        METADATA
+  OVERSCAN         BOOL    FALSE           # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    FALSE           # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    FALSE           # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BASE.FITS        BOOL    FALSE           # Save base image?
+  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
+  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
+  BIN1.FITS        BOOL    FALSE           # Save 1st binned chip image?
+  BIN2.FITS        BOOL    FALSE           # Save 2nd binned chip image?
+  BIN1.JPEG        BOOL    FALSE           # Save 1st binned jpeg?
+  BIN2.JPEG        BOOL    TRUE            # Save 2nd binned jpeg?
+  BIN1.XBIN        S32     1               # Image is already binned
+  BIN1.YBIN        S32     1               # Image is already binned
+  BIN2.XBIN        S32     1               # Image is already binned
+  BIN2.YBIN        S32     1               # Image is already binned
+		   
+  PPIMAGE.JPEG2    METADATA
+    COLORMAP       STR     -greyscale
+    SCALE.MODE     STR     FRACTION
+    SCALE.MIN      F32     0.98
+    SCALE.MAX      F32     1.02
+  END
+END
+
+# generate CTE map image
+PPIMAGE_CTEMAP     METADATA
+  BASE.FITS        BOOL    TRUE            # Save base image?
   BASE.MASK.FITS   BOOL    TRUE            # Save base detrended image?
-  BASE.VARIANCE.FITS BOOL    TRUE            # Save base detrended image?
-  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    FALSE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    TRUE            # Shutter correction
-  FLAT            BOOL    TRUE            # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    FALSE           # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Overscan, bias, dark, shutter, flat-field, fringe, photom
-PPIMAGE_OBDSFRP   METADATA
-  BASE.FITS        BOOL    FALSE           # Save base detrended image?
-  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
-  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
-  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    TRUE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    TRUE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    TRUE            # Shutter correction
-  FLAT            BOOL    TRUE            # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    TRUE            # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
-
-# Overscan, bias, dark, shutter, flat-field, fringe, photom, astrom
-PPIMAGE_OBDSFRA   METADATA
-  BASE.FITS        BOOL    FALSE           # Save base detrended image?
-  BASE.MASK.FITS   BOOL    FALSE           # Save base detrended image?
-  BASE.VARIANCE.FITS BOOL    FALSE           # Save base detrended image?
-  CHIP.FITS        BOOL    TRUE            # Save chip-mosaic-ed image? 
-  CHIP.MASK.FITS   BOOL    TRUE           # Save chip-mosaic-ed image? 
-  CHIP.VARIANCE.FITS BOOL    TRUE           # Save chip-mosaic-ed image? 
-  OVERSCAN        BOOL    TRUE            # Overscan subtraction
-  BIAS            BOOL    TRUE            # Bias subtraction
-  DARK            BOOL    TRUE            # Dark subtraction
-  SHUTTER         BOOL    TRUE            # Shutter correction
-  FLAT            BOOL    TRUE            # Flat-field normalisation
-  MASK            BOOL    FALSE           # Mask bad pixels
-  FRINGE          BOOL    FALSE           # Fringe subtraction
-  PHOTOM          BOOL    TRUE            # Source identification and photometry
-  ASTROM.CHIP     BOOL    FALSE           # Astrometry per chip?
-  ASTROM.MOSAIC   BOOL    FALSE           # Astrometry for mosaic?
-END
+  BASE.VARIANCE.FITS BOOL  TRUE            # Save base detrended image?
+  CHIP.FITS        BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.MASK.FITS   BOOL    FALSE           # Save chip-mosaic-ed image? 
+  CHIP.VARIANCE.FITS BOOL  FALSE           # Save chip-mosaic-ed image? 
+  OVERSCAN         BOOL    FALSE           # Overscan subtraction
+  OVERSCAN         BOOL    TRUE            # Overscan subtraction
+  BIAS             BOOL    FALSE           # Bias subtraction
+  DARK             BOOL    TRUE            # Dark subtraction
+  SHUTTER          BOOL    FALSE           # Shutter correction
+  FLAT             BOOL    TRUE            # Flat-field normalisation
+  MASK             BOOL    FALSE           # Mask bad pixels
+  FRINGE           BOOL    FALSE           # Fringe subtraction
+  PHOTOM           BOOL    FALSE           # Source identification and photometry
+  ASTROM.CHIP      BOOL    FALSE           # Astrometry per chip?
+  ASTROM.MOSAIC    BOOL    FALSE           # Astrometry for mosaic?
+  BIN1.FITS        BOOL    TRUE            # Save 1st binned chip image?
+  BIN2.FITS        BOOL    TRUE            # Save 2nd binned chip image?
+  CHECK.CTE        BOOL    TRUE            # measure CTE errors?
+
+  DETREND.CONSTRAINTS  METADATA
+    DARK METADATA
+      DETTYPE STR DARK_PREMASK
+      EXPTIME STR FPA.EXPOSURE
+    END
+    FLAT METADATA
+      DETTYPE STR FLAT_PREMASK
+      FILTER  STR FPA.FILTERID
+    END
+  END   
+END
+
Index: /branches/pap/ippconfig/simmosaic/psastro.config
===================================================================
--- /branches/pap/ippconfig/simmosaic/psastro.config	(revision 28002)
+++ /branches/pap/ippconfig/simmosaic/psastro.config	(revision 28003)
@@ -1,3 +1,31 @@
+PSASTRO.PIXEL.SCALE    F32  1.0
+
+PSASTRO.IGNORE         STR    CRLIMIT,SATURATED,DEFECT,BLEND
+
 PSASTRO.CATDIR		STR	SYNTH.SIMTEST
 DVO.GETSTAR.PHOTCODE	STR	r
 PSASTRO.MAX.NSTAR	S32	50	# max stars accepted for fitting
+DVO.GETSTAR.MAX.RHO     F32    10000.0
+DVO.GETSTAR.MIN.MAG     F32      10.0
+
+PHOTCODE.DATA MULTI
+PHOTCODE.DATA METADATA
+  FILTER   STR g
+  ZEROPT   F32 24.0
+  PHOTCODE STR g_SYNTH
+END
+PHOTCODE.DATA METADATA
+  FILTER   STR r
+  ZEROPT   F32  25.15
+  PHOTCODE STR r_SYNTH
+END
+PHOTCODE.DATA METADATA
+  FILTER   STR i
+  ZEROPT   F32  25.00
+  PHOTCODE STR i_SYNTH
+END
+PHOTCODE.DATA METADATA
+  FILTER   STR z
+  ZEROPT   F32  24.50
+  PHOTCODE STR z_SYNTH
+END
Index: /branches/pap/ippconfig/simtest/ppSim.config
===================================================================
--- /branches/pap/ippconfig/simtest/ppSim.config	(revision 28002)
+++ /branches/pap/ippconfig/simtest/ppSim.config	(revision 28003)
@@ -15,5 +15,5 @@
  STARS.MAG	 F32	 10.0		# Brightest magnitude for fake stars
  STARS.DENSITY	 F32     100.0		# Stellar density (per square degree) at the brightest magnitude
- STARS.SIGMA.LIM F32     1.0            # significance of faintest sources
+ STARS.SIGMA.LIM F32     2.0            # significance of faintest sources
  STARS.LUM	 F32	 0.35		# Stellar luminosity function slope (magnitude slope)
 END
Index: /branches/pap/magic/remove/src/streaksastrom.c
===================================================================
--- /branches/pap/magic/remove/src/streaksastrom.c	(revision 28002)
+++ /branches/pap/magic/remove/src/streaksastrom.c	(revision 28003)
@@ -375,11 +375,62 @@
 }
 
+static void chipToSky(pmAstromObj *pt, pmFPA *fpa, pmChip *chip)
+{
+    // chip to FP
+    psPlaneTransformApply(pt->FP, chip->toFPA, pt->chip);
+    // FP to TP to sky
+    psPlaneTransformApply(pt->TP, fpa->toTPA, pt->FP);
+    psDeproject(pt->sky, pt->TP, fpa->toSky);
+}
+
+
 bool
 linearizeTransforms(strkAstrom *astrom)
 {
-    if (!pmAstromLinearizeTransforms((pmFPA *) astrom->fpa, (pmChip *) astrom->chip, NULL, NULL, NULL, 0, 0)) {
-        psErrorStackPrint(stderr, "linear fit to astrometry failed. ignoring\n");
+    pmFPA  *inFPA  = (pmFPA *) astrom->fpa;
+    pmChip *inChip = (pmChip *) astrom->chip;
+
+    // compute ra and dec of chip center
+    pmAstromObj *center = pmAstromObjAlloc();
+    center->chip->x = (double) astrom->numCols / 2.;
+    center->chip->xErr = 0;
+    center->chip->y = (double) astrom->numRows / 2.;
+    center->chip->yErr = 0;
+
+    chipToSky(center, inFPA, inChip);
+
+    psRegion bounds = {0, astrom->numCols - 1, 0, astrom->numRows - 1 };
+
+    // create skeleton containers for the linearized transforms;
+    pmFPA  outFPA;
+    pmChip outChip;
+
+    memset(&outFPA, 0, sizeof(outFPA));
+    memset(&outChip, 0, sizeof(outChip));
+
+    outFPA.toSky = psProjectionAlloc (center->sky->r, center->sky->d, inFPA->toSky->Xs, inFPA->toSky->Ys, PS_PROJ_TAN);
+
+    psFree(center);
+
+    if (!pmAstromLinearizeToSky(inFPA, inChip, &outFPA, &outChip, &bounds)) {
+        psError(PS_ERR_UNKNOWN, false, "Failed to linearize astrometry\n");
         return false;
     }
-    return true;
-}
+
+    psFree(inFPA->toSky);
+    inFPA->toSky = outFPA.toSky;
+
+    psFree(inFPA->toTPA);
+    inFPA->toTPA = outFPA.toTPA;
+
+    psFree(inFPA->fromTPA);
+    inFPA->fromTPA = outFPA.fromTPA;
+
+    psFree(inChip->toFPA)
+    inChip->toFPA = outChip.toFPA;
+
+    psFree(inChip->fromFPA);
+    inChip->fromFPA = outChip.fromFPA;
+
+    return true;
+}
Index: /branches/pap/magic/remove/src/streaksremove.h
===================================================================
--- /branches/pap/magic/remove/src/streaksremove.h	(revision 28002)
+++ /branches/pap/magic/remove/src/streaksremove.h	(revision 28003)
@@ -38,13 +38,4 @@
 // used for error messages
 extern char * streaksProgram;
-
-typedef enum {
-    IPP_STAGE_NONE = 0,
-    IPP_STAGE_RAW,
-    IPP_STAGE_CHIP,
-    IPP_STAGE_WARP,
-    IPP_STAGE_DIFF
-} ippStage;
-
 
 typedef struct {
Index: /branches/pap/ppImage/src/ppImageMosaic.c
===================================================================
--- /branches/pap/ppImage/src/ppImageMosaic.c	(revision 28002)
+++ /branches/pap/ppImage/src/ppImageMosaic.c	(revision 28003)
@@ -25,6 +25,5 @@
     pmChip *inChip = pmFPAviewThisChip(view, in->fpa);
     if (!outChip->hdu && !outChip->parent->hdu) {
-        const char *name = psMetadataLookupStr(&status, in->fpa->concepts, "FPA.OBS"); // Name of FPA
-        pmFPAAddSourceFromView(out->fpa, name, view, out->format);
+        pmFPAAddSourceFromView(out->fpa, view, out->format);
     }
 
@@ -66,8 +65,6 @@
     #endif
 
-    const char *name = psMetadataLookupStr(&status, in->fpa->concepts, "FPA.OBS"); // Name of FPA
-
     pmFPAview *view = pmFPAviewAlloc(0);
-    pmFPAAddSourceFromView(out->fpa, name, view, out->format);
+    pmFPAAddSourceFromView(out->fpa, view, out->format);
     psFree(view);
 
Index: /branches/pap/ppMerge/src/ppMergeCamera.c
===================================================================
--- /branches/pap/ppMerge/src/ppMergeCamera.c	(revision 28002)
+++ /branches/pap/ppMerge/src/ppMergeCamera.c	(revision 28003)
@@ -19,5 +19,4 @@
                 const char *name,       ///< Name of output file
                 pmFPAfileType type,     ///< Type of file
-                const char *description, ///< Description of file
                 psMetadata *format,     ///< Camera format
                 pmFPAview *view         ///< View for PHU
@@ -84,5 +83,5 @@
     output->save = true;
 
-    if (!pmFPAAddSourceFromView(fpa, description, view, format)) {
+    if (!pmFPAAddSourceFromView(fpa, view, format)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to generate output FPA.");
         return false;
@@ -337,10 +336,10 @@
       case PPMERGE_TYPE_FRINGE:
         fileType = PM_FPA_FILE_FRINGE;
-	break;
+        break;
       default:
         psAbort("Unknown frame type: %x", type);
     }
 
-    if (!outputFile(config, outName, fileType, "Merged detrend", format, phuView)) {
+    if (!outputFile(config, outName, fileType, format, phuView)) {
         psFree(outName);
         psFree(phuView);
@@ -349,10 +348,10 @@
     psFree(outName);
 
-    if (!outputFile(config, "PPMERGE.OUTPUT.SIGMA", PM_FPA_FILE_IMAGE, "Merge sigma", format, phuView)) {
+    if (!outputFile(config, "PPMERGE.OUTPUT.SIGMA", PM_FPA_FILE_IMAGE, format, phuView)) {
         psFree(phuView);
         return false;
     }
 
-    if (!outputFile(config, "PPMERGE.OUTPUT.COUNT", PM_FPA_FILE_IMAGE, "Merged count", format, phuView)) {
+    if (!outputFile(config, "PPMERGE.OUTPUT.COUNT", PM_FPA_FILE_IMAGE, format, phuView)) {
         psFree(phuView);
         return false;
Index: /branches/pap/ppSim/src/ppSimCreate.c
===================================================================
--- /branches/pap/ppSim/src/ppSimCreate.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimCreate.c	(revision 28003)
@@ -198,5 +198,5 @@
 
     if (phuLevel == PM_FPA_LEVEL_FPA) {
-        if (!pmFPAAddSourceFromView(fpa, "Simulation", view, output->format)) {
+        if (!pmFPAAddSourceFromView(fpa, view, output->format)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
             psFree(fpa);
@@ -209,5 +209,5 @@
     while ((chip = pmFPAviewNextChip(view, fpa, 1))) {
         if (phuLevel == PM_FPA_LEVEL_CHIP) {
-            if (!pmFPAAddSourceFromView(fpa, "Simulation", view, output->format)) {
+            if (!pmFPAAddSourceFromView(fpa, view, output->format)) {
                 psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
                 psFree(fpa);
@@ -220,5 +220,5 @@
         while ((cell = pmFPAviewNextCell(view, fpa, 1))) {
             if (phuLevel == PM_FPA_LEVEL_CELL) {
-                if (!pmFPAAddSourceFromView(fpa, "Simulation", view, output->format)) {
+                if (!pmFPAAddSourceFromView(fpa, view, output->format)) {
                     psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
                     psFree(fpa);
Index: /branches/pap/ppSim/src/ppSimMosaicChip.c
===================================================================
--- /branches/pap/ppSim/src/ppSimMosaicChip.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimMosaicChip.c	(revision 28003)
@@ -22,6 +22,5 @@
     pmChip *inChip = pmFPAviewThisChip(view, in->fpa);
     if (!outChip->hdu && !outChip->parent->hdu) {
-        const char *name = psMetadataLookupStr(&status, in->fpa->concepts, "FPA.OBS"); // Name of FPA
-        pmFPAAddSourceFromView(out->fpa, name, view, out->format);
+        pmFPAAddSourceFromView(out->fpa, view, out->format);
     }
 
Index: /branches/pap/ppSim/src/ppSimSequence.c
===================================================================
--- /branches/pap/ppSim/src/ppSimSequence.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimSequence.c	(revision 28003)
@@ -1,6 +1,4 @@
 # include "ppSimSequence.h"
 # include <sys/stat.h>
-
-// XXX Memory leaks in string variables
 
 int main (int argc, char **argv) {
@@ -135,20 +133,62 @@
     psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);
 
-    psMetadataItem *item = psMetadataLookup (config, "SEQUENCE");
-    if (item == NULL) {
-        psLogMsg ("ppSimSequence", PS_LOG_WARN, "missing SEQUENCE description");
-        exit (PS_EXIT_CONFIG_ERROR);
-    }
-
+    // global camera option (if not set, we look in each sequence)
+    if (camera == NULL) {
+	camera = psMetadataLookupStr (&status, config, "CAMERA");
+    }
+
+    psArray *files = NULL;
     psArray *sequences = NULL;
-    if (item->type == PS_DATA_METADATA) {
-        sequences = psArrayAlloc(1);
-        sequences->data[0] = psMemIncrRefCounter (item->data.V);
-    } else {
-        if (item->type != PS_DATA_METADATA_MULTI)  {
-            psLogMsg ("ppSimSequence", PS_LOG_WARN, "SEQUENCE is not MULTI or METADATA");
-            exit (1);
-        }
-        sequences = psListToArray (item->data.list);
+
+    { // find the FILERULE (if it exists) to set the file extension (.fits is default)
+	psMetadataItem *filerule = psMetadataLookup (config, "FILERULE");
+	if (filerule == NULL) {
+	    psLogMsg ("ppSimSequence", PS_LOG_INFO, "no FILERULE, assuming .fits ending");
+	    files = psArrayAlloc(1);
+	    files->data[0] = psStringCopy("fits");
+	    goto sequence;
+	} 
+	if (filerule->type == PS_DATA_METADATA_MULTI) {
+	    psArray *rules = psListToArray (filerule->data.list);
+	    psAssert (rules, "failed to get array from list?");
+	    psAssert (rules->n > 1, "supposed to be multiple entries in the list?");
+	    files = psArrayAllocEmpty(rules->n);
+	    for (int i = 0; i < rules->n; i++) {
+		psMetadataItem *item = rules->data[i];
+		if (item->type != PS_DATA_STRING) {
+		    psLogMsg ("ppSimSequence", PS_LOG_WARN, "invalid FILERULE type");
+		    exit (PS_EXIT_CONFIG_ERROR);
+		}
+		psArrayAdd (files, 16, item->data.str);
+	    }
+	    goto sequence;
+	}
+	if (filerule->type == PS_DATA_STRING) {
+	    files = psArrayAlloc(1);
+	    files->data[0] = psStringCopy(filerule->data.str);
+	    goto sequence;
+	}
+	psLogMsg ("ppSimSequence", PS_LOG_WARN, "invalid FILERULE type");
+	exit (PS_EXIT_CONFIG_ERROR);
+    }
+
+sequence:
+    { // find the set of sequences which define the ppSim data to be produced
+	psMetadataItem *item = psMetadataLookup (config, "SEQUENCE");
+	if (item == NULL) {
+	    psLogMsg ("ppSimSequence", PS_LOG_WARN, "missing SEQUENCE description");
+	    exit (PS_EXIT_CONFIG_ERROR);
+	}
+
+	if (item->type == PS_DATA_METADATA) {
+	    sequences = psArrayAlloc(1);
+	    sequences->data[0] = psMemIncrRefCounter (item->data.V);
+	} else {
+	    if (item->type != PS_DATA_METADATA_MULTI)  {
+		psLogMsg ("ppSimSequence", PS_LOG_WARN, "SEQUENCE is not MULTI or METADATA");
+		exit (1);
+	    }
+	    sequences = psListToArray (item->data.list);
+	}
     }
 
@@ -172,4 +212,8 @@
             camera = psMetadataLookupStr (&status, sequence, "CAMERA");
         }
+	if (!camera) {
+            psLogMsg ("ppSimSequence", PS_LOG_WARN, "CAMERA is not defined");
+            exit (1);
+	}
 
         psString injectCommandReal = NULL;
@@ -180,17 +224,25 @@
 
         if (!strcasecmp (type, "BIAS")) {
-            ppSimSequenceBias (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceBias (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
         if (!strcasecmp (type, "DARK")) {
-            ppSimSequenceDark (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceDark (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
         if (!strcasecmp (type, "FLAT")) {
-            ppSimSequenceFlat (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceFlat (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
         if (!strcasecmp (type, "OBJECT")) {
-            ppSimSequenceObject (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal);
+            ppSimSequenceObject (simfile, inject, sequence, i, rng, path, basename, ppSimCommandReal, injectCommandReal, files);
+	    psFree (injectCommandReal);
+	    psFree (ppSimCommandReal);
             continue;
         }
Index: /branches/pap/ppSim/src/ppSimSequence.h
===================================================================
--- /branches/pap/ppSim/src/ppSimSequence.h	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimSequence.h	(revision 28003)
@@ -12,8 +12,8 @@
 #include <psastro.h>
 
-bool ppSimSequenceBias 	 (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand);
-bool ppSimSequenceDark 	 (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand);
-bool ppSimSequenceFlat 	 (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand);
-bool ppSimSequenceObject (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand);
+bool ppSimSequenceBias 	 (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files);
+bool ppSimSequenceDark 	 (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files);
+bool ppSimSequenceFlat 	 (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files);
+bool ppSimSequenceObject (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files);
 
 #endif
Index: /branches/pap/ppSim/src/ppSimSequenceBias.c
===================================================================
--- /branches/pap/ppSim/src/ppSimSequenceBias.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimSequenceBias.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "ppSimSequence.h"
 
-bool ppSimSequenceBias (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand) {
+bool ppSimSequenceBias (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files) {
 
     bool status, setLevel, setRange;
@@ -14,5 +14,5 @@
     int nImage = 0;
     for (int i = 0; i < nImages; i++) {
-	    
+	        
 	// define the output filename
 	psString filename = NULL;
@@ -30,19 +30,23 @@
 	if (setLevel) psStringAppend (&command, " -biaslevel %f", level);
 	if (setRange) psStringAppend (&command, " -biasrange %f", range);
-      
+          
 	psStringAppend (&command, " %s", filename);
 
 	fprintf (simfile, "%s\n", command);
 	psFree (command);
-			    
+			        
 	// define the inject command
 	// path should be dirname/filename
-	command = psStringCopy (injectCommand);
-	psStringAppend (&command, " %s*.fits",    filename);
-	fprintf (inject, "%s\n", command);
-	psFree (command);
+	
+	// we use the filename above (really the file root) to construct the filenames
+	for (int i = 0; i < files->n; i++) {
+	    command = psStringCopy (injectCommand);
+            psStringAppend (&command, " %s.%s", filename, (char *) files->data[i]);
+            fprintf (inject, "%s\n", command);
+	    psFree (command);
+	}
+
 	psFree (filename);
-
-	nImage ++;
+        nImage ++;
     }
     return true;
Index: /branches/pap/ppSim/src/ppSimSequenceDark.c
===================================================================
--- /branches/pap/ppSim/src/ppSimSequenceDark.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimSequenceDark.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "ppSimSequence.h"
 
-bool ppSimSequenceDark (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand) {
+bool ppSimSequenceDark (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files) {
 
     bool status, setRate;
@@ -39,5 +39,5 @@
 
 	    psStringAppend (&command, "%s -type DARK", ppSimCommand);
-      
+          
 	    if (setRate) {
 		double frnd = psRandomUniform(rng);
@@ -52,15 +52,19 @@
 	    fprintf (simfile, "%s\n", command);
 	    psFree (command);
-			    
+			        
 	    // define the inject command
 	    // path should be dirname/filename
-	    command = psStringCopy (injectCommand);
-	    psStringAppend (&command, " %s*.fits",    filename);
-	    fprintf (inject, "%s\n", command);
-	    psFree (command);
-	    psFree (filename);
+	
+	    // we use the filename above (really the file root) to construct the filenames
+	    for (int i = 0; i < files->n; i++) {
+		command = psStringCopy (injectCommand);
+		psStringAppend (&command, " %s.%s", filename, (char *) files->data[i]);
+		fprintf (inject, "%s\n", command);
+		psFree (command);
+	    }
 
-	    nImage ++;
-	}
+            psFree (filename);
+            nImage ++;
+        }
     }
     return true;
Index: /branches/pap/ppSim/src/ppSimSequenceFlat.c
===================================================================
--- /branches/pap/ppSim/src/ppSimSequenceFlat.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimSequenceFlat.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "ppSimSequence.h"
 
-bool ppSimSequenceFlat (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand) {
+bool ppSimSequenceFlat (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files) {
 
     bool status;
@@ -26,5 +26,5 @@
 	// loop over the filters & exposure times
 	for (int j = 0; j < nSetup; j++) {
-	    
+	        
 	    // define the output filename
 	    psString filename = NULL;
@@ -50,11 +50,15 @@
 	    // define the inject command
 	    // path should be dirname/filename
-	    command = psStringCopy (injectCommand);
-	    psStringAppend (&command, " %s*.fits",    filename);
-	    fprintf (inject, "%s\n", command);
-	    psFree (command);
-	    psFree (filename);
+	
+	    // we use the filename above (really the file root) to construct the filenames
+	    for (int i = 0; i < files->n; i++) {
+		command = psStringCopy (injectCommand);
+		psStringAppend (&command, " %s.%s", filename, (char *) files->data[i]);
+		fprintf (inject, "%s\n", command);
+		psFree (command);
+	    }
 
-	    nImage ++;
+            psFree (filename);
+            nImage ++;
 	}
     }
Index: /branches/pap/ppSim/src/ppSimSequenceObject.c
===================================================================
--- /branches/pap/ppSim/src/ppSimSequenceObject.c	(revision 28002)
+++ /branches/pap/ppSim/src/ppSimSequenceObject.c	(revision 28003)
@@ -1,5 +1,5 @@
 # include "ppSimSequence.h"
 
-bool ppSimSequenceObject (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand) {
+bool ppSimSequenceObject (FILE *simfile, FILE *inject, psMetadata *sequence, int nSeq, psRandom *rng, const char *path, const char *basename, const char *ppSimCommand, const char *injectCommand, psArray *files) {
 
     bool status;
@@ -34,12 +34,12 @@
     // loop over the filters & exposure times
     for (int i = 0; i < filters->n; i++) {
-	    
+	        
 	// offset parameters
 	float dR = psMetadataLookupF32 (&status, sequence, "OFFSET.RA");
 	float dD = psMetadataLookupF32 (&status, sequence, "OFFSET.DEC");
-  
+      
 	int nR = psMetadataLookupS32 (&status, sequence, "OFFSET.NR");
 	int nD = psMetadataLookupS32 (&status, sequence, "OFFSET.ND");
-  
+      
 	// loop over the offset sequence
 	for (int iR = 0; iR < nR; iR++) {
@@ -50,12 +50,12 @@
 		float R = Ro + dR*(iR - 0.5*nR + 0.5) / cos (RAD_DEG*Do) / 3600.0;
 		float D = Do + dD*(iD - 0.5*nD + 0.5) / 3600.0;
-      
+              
 		// dither parameters
 		float dr = psMetadataLookupF32 (&status, sequence, "DITHER.RA");
 		float dd = psMetadataLookupF32 (&status, sequence, "DITHER.DEC");
-  
+          
 		int nr = psMetadataLookupS32 (&status, sequence, "DITHER.NR");
 		int nd = psMetadataLookupS32 (&status, sequence, "DITHER.ND");
-  
+          
 		// loop over the dither sequence
 		for (int ir = 0; ir < nr; ir++) {
@@ -65,5 +65,5 @@
 			float ra = R + dr*(ir - 0.5*nr + 0.5) / cos (RAD_DEG*D) / 3600.0;
 			float dec = D + dd*(id - 0.5*nd + 0.5) / 3600.0;
-	  
+	              
 			// rotation sequence parameters
 			float pos_min   = psMetadataLookupF32 (&status, sequence, "POS_MIN");
@@ -72,8 +72,8 @@
 			assert (pos_delta > 0.0);
 			assert (pos_max >= pos_min);
-	    
+	                
 			// loop over rotation sequence
 			for (float pos = pos_min; pos <= pos_max; pos += pos_delta) {
-	      
+	                  
 			    // define the output filename
 			    psString filename = NULL;
@@ -95,9 +95,9 @@
 			    psStringAppend (&command, " -dec %f", dec);
 			    psStringAppend (&command, " -pa %f", pos);
-                            psStringAppend (&command, " -obs_mode OBJECT.%s", (char *) filters->data[i]);
+			    psStringAppend (&command, " -obs_mode OBJECT.%s", (char *) filters->data[i]);
 
 			    double frnd = psRandomUniform(rng);
 			    float seeing = IQmin + (IQmax - IQmin)*frnd;
-	      
+	                  
 			    psStringAppend (&command, " -seeing %f", seeing);
 
@@ -106,13 +106,17 @@
 			    fprintf (simfile, "%s\n", command);
 			    psFree (command);
-			    
+			                
 			    // define the inject command
 			    // path should be dirname/filename
-			    command = psStringCopy (injectCommand);
-			    psStringAppend (&command, " %s*.fits",    filename);
-			    fprintf (inject, "%s\n", command);
-			    psFree (command);
+			    
+			    // we use the filename above (really the file root) to construct the filenames
+			    for (int i = 0; i < files->n; i++) {
+				command = psStringCopy (injectCommand);
+				psStringAppend (&command, " %s.%s", filename, (char *) files->data[i]);
+				fprintf (inject, "%s\n", command);
+				psFree (command);
+			    }
+
 			    psFree (filename);
-
 			    nImage ++;
 			}
Index: /branches/pap/ppStack/src/ppStackCamera.c
===================================================================
--- /branches/pap/ppStack/src/ppStackCamera.c	(revision 28002)
+++ /branches/pap/ppStack/src/ppStackCamera.c	(revision 28003)
@@ -252,5 +252,5 @@
     output->save = true;
 
-    if (!pmFPAAddSourceFromFormat(outFPA, "Stack", output->format)) {
+    if (!pmFPAAddSourceFromFormat(outFPA, output->format)) {
         psError(psErrorCodeLast(), false, "Unable to generate output FPA.");
         return false;
@@ -302,5 +302,5 @@
     exp->save = true;
 
-    if (!pmFPAAddSourceFromFormat(expFPA, "Stack", exp->format)) {
+    if (!pmFPAAddSourceFromFormat(expFPA, exp->format)) {
         psError(psErrorCodeLast(), false, "Unable to generate output FPA.");
         return false;
@@ -369,5 +369,5 @@
     unConv->save = true;
 
-    if (!pmFPAAddSourceFromFormat(unconvFPA, "Stack", unConv->format)) {
+    if (!pmFPAAddSourceFromFormat(unconvFPA, unConv->format)) {
         psError(psErrorCodeLast(), false, "Unable to generate output FPA.");
         return false;
@@ -419,5 +419,5 @@
     unconvExp->save = true;
 
-    if (!pmFPAAddSourceFromFormat(unconvExpFPA, "Stack", unconvExp->format)) {
+    if (!pmFPAAddSourceFromFormat(unconvExpFPA, unconvExp->format)) {
         psError(psErrorCodeLast(), false, "Unable to generate output FPA.");
         return false;
Index: /branches/pap/ppStack/src/ppStackCombineFinal.c
===================================================================
--- /branches/pap/ppStack/src/ppStackCombineFinal.c	(revision 28002)
+++ /branches/pap/ppStack/src/ppStackCombineFinal.c	(revision 28003)
@@ -142,5 +142,5 @@
         float exptime = 0.0;            // Summed exposure time
         for (int i = 0; i < options->num; i++) {
-            if (options->inputMask) {
+            if (options->inputMask->data.U8[i]) {
                 continue;
             }
Index: /branches/pap/ppStack/src/ppStackFinish.c
===================================================================
--- /branches/pap/ppStack/src/ppStackFinish.c	(revision 28002)
+++ /branches/pap/ppStack/src/ppStackFinish.c	(revision 28003)
@@ -62,4 +62,5 @@
     if (errorCode != PS_ERR_NONE) {
         psErrorStackPrint(stderr, "Unable to perform stack.");
+        pmFPAfileFreeSetStrict(false);
         switch (errorCode) {
           case PPSTACK_ERR_UNKNOWN:
Index: /branches/pap/ppStack/src/ppStackSources.c
===================================================================
--- /branches/pap/ppStack/src/ppStackSources.c	(revision 28002)
+++ /branches/pap/ppStack/src/ppStackSources.c	(revision 28003)
@@ -230,6 +230,10 @@
             sources = sourceLists->data[i];
         }
+        options->quality = PPSTACK_ERR_REJECTED;
         options->sources = psMemIncrRefCounter(sources);
-        psLogMsg("ppStack", PS_LOG_WARN, "Single image with sources --- no need to match transparency.");
+        options->norm = psVectorAlloc(num, PS_TYPE_F32);
+        psVectorInit(options->norm, 1.0);
+        options->zp = NAN;
+        psLogMsg("ppStack", PS_LOG_WARN, "Single image with sources --- cannot match transparency.");
         psFree(zp);
         psFree(zpExp);
Index: /branches/pap/ppSub/src/ppSubExit.c
===================================================================
--- /branches/pap/ppSub/src/ppSubExit.c	(revision 28002)
+++ /branches/pap/ppSub/src/ppSubExit.c	(revision 28003)
@@ -13,4 +13,5 @@
     psErrorCode errorCode = psErrorCodeLast(); // Error code
     if (errorCode != PS_ERR_NONE) {
+        pmFPAfileFreeSetStrict(false);
         psErrorStackPrint(stderr, "Error in subtraction:");
         switch (errorCode) {
Index: /branches/pap/ppSub/src/ppSubMakePSF.c
===================================================================
--- /branches/pap/ppSub/src/ppSubMakePSF.c	(revision 28002)
+++ /branches/pap/ppSub/src/ppSubMakePSF.c	(revision 28003)
@@ -106,5 +106,5 @@
     // save the resulting PSF information on the pmFPAfile PSPHOT.PSF.LOAD
     pmFPAfile *psfFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.PSF.LOAD"); // PSF file
-    if (!ppSubCopyPSF (psfFile, photFile, view)) {
+    if (!ppSubCopyPSF(psfFile, photFile, view)) {
         psErrorStackPrint(stderr, "PSF was not generated");
         psWarning("PSF was not generated --- suspect bad data quality.");
@@ -121,8 +121,6 @@
 }
 
-bool ppSubCopyPSF (pmFPAfile *output, pmFPAfile *input, pmFPAview *view) {
-
-    bool mdok = false;
-
+bool ppSubCopyPSF(pmFPAfile *output, pmFPAfile *input, pmFPAview *view)
+{
     pmChip *inputChip   = pmFPAviewThisChip(view, input->fpa); // Chip with PSF info
     pmChip *outputChip  = pmFPAviewThisChip(view, output->fpa); // Chip to store PSF info
@@ -134,31 +132,14 @@
         pmCell *outputCell  = pmFPAviewThisCell(view, output->fpa);
         outputRO = pmReadoutAlloc(outputCell);
-        outputRO->image = psMemIncrRefCounter (inputRO->image);
+        outputRO->image = psMemIncrRefCounter(inputRO->image);
     }
 
-    // copy the PSF-related data to PSPHOT.PSF.LOAD for safe-keeping
-    psMetadata *psfRegions = psMetadataAlloc();
-
-    int nRegions = psMetadataLookupS32 (&mdok, inputRO->analysis, "PSF.CLUMP.NREGIONS");
-    if (!nRegions) {
-        psErrorStackPrint(stderr, "No PSF available");
-        return false;
+    // Copy the PSF-related data
+    psMetadataIterator *iter = psMetadataIteratorAlloc(inputRO->analysis, PS_LIST_HEAD, "^PSF\\.CLUMP.*");
+    psMetadataItem *item;               // Item from iteration
+    while ((item = psMetadataGetAndIncrement(iter))) {
+        psMetadataAddItem(outputRO->analysis, item, PS_LIST_TAIL, PS_META_REPLACE);
     }
-    psMetadataAddS32 (psfRegions, PS_LIST_TAIL, "PSF.CLUMP.NREGIONS",  PS_META_REPLACE, "psf clump regions", nRegions);
-
-    for (int i = 0; i < nRegions; i++) {
-        char fieldName[80];
-        snprintf (fieldName, 80, "PSF.CLUMP.REGION.%03d", i);
-        psMetadata *regionMD = psMetadataLookupPtr (&mdok, inputRO->analysis, fieldName);
-        if (!regionMD) {
-            psWarning ("missing psf clump region metadata for entry %d", i);
-            continue;
-        }
-        psMetadataAddMetadata (psfRegions, PS_LIST_TAIL, fieldName, PS_META_REPLACE, "psf clump region", regionMD);
-    }
-
-    // XXX why am I replacing the entire analysis MD?
-    psFree(outputRO->analysis);
-    outputRO->analysis = psfRegions;
+    psFree(iter);
 
     // copy the PSF model data
@@ -169,5 +150,6 @@
     }
 
-    psMetadataAddPtr(outputChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE, "PSF from ppSubMakePSF", psf);
+    psMetadataAddPtr(outputChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE,
+                     "PSF from ppSubMakePSF", psf);
 
     return true;
Index: /branches/pap/ppSub/src/ppSubReadoutInverse.c
===================================================================
--- /branches/pap/ppSub/src/ppSubReadoutInverse.c	(revision 28002)
+++ /branches/pap/ppSub/src/ppSubReadoutInverse.c	(revision 28003)
@@ -20,4 +20,5 @@
     invRO->variance = psMemIncrRefCounter(outRO->variance);
     invRO->covariance = psMemIncrRefCounter(outRO->covariance);
+    invRO->analysis = psMetadataCopy(invRO->analysis, outRO->analysis);
 
     invRO->data_exists = invRO->parent->data_exists = invRO->parent->parent->data_exists = true;
Index: /branches/pap/ppViz/src/ppCoord/ppCoord.h
===================================================================
--- /branches/pap/ppViz/src/ppCoord/ppCoord.h	(revision 28002)
+++ /branches/pap/ppViz/src/ppCoord/ppCoord.h	(revision 28003)
@@ -17,4 +17,5 @@
     psString radecName;                 // Filename with sky coordinates
     psString streaksName;               // Filename with streaks (sky coordinates)
+    psString clustersName;              // Filename with clusters (sky coordinates)
     pmConfig *config;                   // Configuration
     bool radians;                       // RA,Dec are in radians?
Index: /branches/pap/ppViz/src/ppCoord/ppCoordArguments.c
===================================================================
--- /branches/pap/ppViz/src/ppCoord/ppCoordArguments.c	(revision 28002)
+++ /branches/pap/ppViz/src/ppCoord/ppCoordArguments.c	(revision 28003)
@@ -52,4 +52,5 @@
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-radec", 0, "Filename with RA,Dec (default decimal degrees)", NULL);
     psMetadataAddStr(arguments, PS_LIST_TAIL, "-streaks", 0, "Filename with streaks", NULL);
+    psMetadataAddStr(arguments, PS_LIST_TAIL, "-clusters", 0, "Filename with clusters", NULL);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-radians", 0, "RA,Dec in radians?", NULL);
     psMetadataAddBool(arguments, PS_LIST_TAIL, "-all", 0, "Output all coordinates?", NULL);
@@ -67,4 +68,5 @@
     data->radecName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-radec"));
     data->streaksName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-streaks"));
+    data->clustersName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-clusters"));
     data->radians = psMetadataLookupBool(NULL, arguments, "-radians");
     data->all = psMetadataLookupBool(NULL, arguments, "-all");
@@ -90,5 +92,5 @@
     }
 
-    if (!data->pixelsName && !data->radecName && !data->streaksName) {
+    if (!data->pixelsName && !data->radecName && !data->streaksName && !data->clustersName) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Neither -pixels nor -radec provided.");
         return false;
Index: /branches/pap/ppViz/src/ppCoord/ppCoordCamera.c
===================================================================
--- /branches/pap/ppViz/src/ppCoord/ppCoordCamera.c	(revision 28002)
+++ /branches/pap/ppViz/src/ppCoord/ppCoordCamera.c	(revision 28003)
@@ -33,7 +33,7 @@
 
     fileArguments("ASTROM", data->astromName, "Input astrometry", data->config);
-    pmFPAfile *astrom = pmFPAfileDefineFromArgs(&status, data->config, "PSWARP.ASTROM", "ASTROM"); // File
+    pmFPAfile *astrom = pmFPAfileDefineFromArgs(&status, data->config, "PPCOORD.ASTROM", "ASTROM"); // File
     if (!status || !astrom) {
-        psError(PS_ERR_IO, false, "Failed to build file from PSWARP.ASTROM");
+        psError(PS_ERR_IO, false, "Failed to build file from PPCOORD.ASTROM");
         return false;
     }
@@ -41,7 +41,7 @@
     if (data->rawName) {
         fileArguments("RAW", data->rawName, "Input raw image", data->config);
-        pmFPAfile *raw = pmFPAfileDefineFromArgs(&status, data->config, "PPIMAGE.INPUT", "RAW"); // File
+        pmFPAfile *raw = pmFPAfileDefineFromArgs(&status, data->config, "PPCOORD.RAW", "RAW"); // File
         if (!status || !raw) {
-            psError(PS_ERR_IO, false, "Failed to build file from PPIMAGE.INPUT");
+            psError(PS_ERR_IO, false, "Failed to build file from PPCOORD.RAW");
             return false;
         }
Index: /branches/pap/ppViz/src/ppCoord/ppCoordLoop.c
===================================================================
--- /branches/pap/ppViz/src/ppCoord/ppCoordLoop.c	(revision 28002)
+++ /branches/pap/ppViz/src/ppCoord/ppCoordLoop.c	(revision 28003)
@@ -71,5 +71,5 @@
 {
     pmConfig *config = data->config;                                        // Configuration data
-    pmFPAfile *astromFile = pmFPAfileSelectSingle(config->files, "PSWARP.ASTROM", 0); // File with astrometry
+    pmFPAfile *astromFile = pmFPAfileSelectSingle(config->files, "PPCOORD.ASTROM", 0); // File with astrometry
 
     if (astromFile->fpa->chips->n > 0 && data->pixelsName && !data->chipName) {
@@ -77,9 +77,9 @@
     }
 
-    pmFPAfile *rawFile = data->rawName ? pmFPAfileSelectSingle(config->files, "PPIMAGE.INPUT", 0) :
+    pmFPAfile *rawFile = data->rawName ? pmFPAfileSelectSingle(config->files, "PPCOORD.RAW", 0) :
         NULL; // File with raw image
 
-    psArray *pixels = NULL, *radec = NULL, *streaks = NULL; // Array of vectors with coordinates
-    psArray *radecOut = NULL, *streaksOut = NULL;           // Output for sky coordinates
+    psArray *pixels = NULL, *radec = NULL, *streaks = NULL, *clusters = NULL; // Array of coordinate vectors
+    psArray *radecOut = NULL, *streaksOut = NULL, *clustersOut = NULL;        // Output for sky coordinates
     if (data->pixelsName) {
         pixels = psVectorsReadFromFile(data->pixelsName, "%f %f");
@@ -145,4 +145,37 @@
         psVectorInit(streaksOut->data[6], NAN);
         psVectorInit(streaksOut->data[7], NAN);
+    }
+
+    if (data->clustersName) {
+        psString file = psSlurpFilename(data->clustersName); // Contents of clusters file
+        if (!file) {
+            psError(psErrorCodeLast(), false, "Unable to read clusters file %s", data->clustersName);
+            return false;
+        }
+        psArray *lines = psStringSplitArray(file, "\n", false); // Lines of clusters
+        psFree(file);
+
+        int num = lines->n - 1;         // Number of clusters
+        clusters = psArrayAlloc(2);
+        psVector *ra = clusters->data[0] = psVectorAlloc(num, PS_TYPE_F64);
+        psVector *dec = clusters->data[1] = psVectorAlloc(num, PS_TYPE_F64);
+
+        // Skip the first line
+        for (int i = 1; i < lines->n; i++) {
+            const char *line = lines->data[i]; // Line of interest
+            if (sscanf(line, "%lf %lf", &ra->data.F64[i-1], &dec->data.F64[i-1]) != 2) {
+                psError(PS_ERR_IO, true, "Unable to read line %d of %s", i, data->clustersName);
+                return false;
+            }
+        }
+        psFree(lines);
+
+        clustersOut = psArrayAlloc(4);
+        clustersOut->data[0] = psArrayAlloc(num);
+        clustersOut->data[1] = psVectorAlloc(num, PS_TYPE_F32);
+        clustersOut->data[2] = psVectorAlloc(num, PS_TYPE_F32);
+        clustersOut->data[3] = psArrayAlloc(num);
+        psVectorInit(clustersOut->data[1], NAN);
+        psVectorInit(clustersOut->data[2], NAN);
     }
 
@@ -369,5 +402,5 @@
                 float x1, y1;   // Coordinates of point 1
                 coordSky2Chip(&x1, &y1, ra1->data.F64[i], dec1->data.F64[i],
-                              data->radians, astromFile->fpa, chip);
+                              true, astromFile->fpa, chip);
                 if ((x1 >= 0 && x1 < numCols && y1 >= 0 && y1 < numRows)) {
                     if (rawChip) {
@@ -384,5 +417,5 @@
                 float x2, y2;   // Coordinates of point 2
                 coordSky2Chip(&x2, &y2, ra2->data.F64[i], dec2->data.F64[i],
-                              data->radians, astromFile->fpa, chip);
+                              true, astromFile->fpa, chip);
                 if ((x2 >= 0 && x2 < numCols && y2 >= 0 && y2 < numRows)) {
                     if (rawChip) {
@@ -396,4 +429,42 @@
                     yPix2->data.F32[i] = y2;
                 }
+            }
+        }
+
+        if (clusters) {
+            psVector *ra = clusters->data[0], *dec = clusters->data[1]; // Pixel coordinates
+            long num = ra->n;                                     // Number of coordinates
+
+            int numCols = psMetadataLookupS32(NULL, hdu->header, "IMNAXIS1"); // Number of columns
+            int numRows = psMetadataLookupS32(NULL, hdu->header, "IMNAXIS2"); // Number of rows
+            if (numCols <= 0 || numRows <= 0) {
+                psError(psErrorCodeLast(), false, "Unable to read size of chip.");
+                return false;
+            }
+
+            psArray *chipPix = clustersOut->data[0]; // Chip for pixels
+            psVector *xPix = clustersOut->data[1];   // x coordinate for pixels
+            psVector *yPix = clustersOut->data[2];   // y coordinate for pixels
+            psArray *cellPix = clustersOut->data[3]; // Cell for pixels
+
+            for (long i = 0; i < num; i++) {
+                float x, y;             // Pixel coordinates
+                coordSky2Chip(&x, &y, ra->data.F64[i], dec->data.F64[i],
+                                false, astromFile->fpa, chip);
+                if ((x < 0 || x > numCols || y < 0 || y > numRows)) {
+                    // Not on this chip
+                    continue;
+                }
+
+                if (rawChip) {
+                    psString cellName = NULL; // Name of cell
+                    coordChip2Cell(&cellName, &x, &y, x, y, cellNames, cellBounds,
+                                   cellX0, cellY0, cellParityX, cellParityY, cellBinX, cellBinY);
+                    cellPix->data[i] = cellName;
+                }
+
+                chipPix->data[i] = psStringCopy(chipName);
+                xPix->data.F32[i] = x;
+                yPix->data.F32[i] = y;
             }
         }
@@ -482,5 +553,5 @@
                         data->ds9color);
             } else {
-                fprintf(stdout, "%.10lf %.10lf %.10lf %.10lf --> %.3f %.3f %s%s%s %.3f %.3f %s%s%s\n",
+                fprintf(stdout, "Streak %.10lf %.10lf %.10lf %.10lf --> %.3f %.3f %s%s%s %.3f %.3f %s%s%s\n",
                         ra1->data.F64[i], dec1->data.F64[i],
                         ra2->data.F64[i], dec2->data.F64[i],
@@ -498,4 +569,33 @@
     }
 
+    if (clustersOut) {
+        psArray *chipPix = clustersOut->data[0]; // Chip for pixels
+        psVector *xPix = clustersOut->data[1];   // x coordinate for pixels
+        psVector *yPix = clustersOut->data[2];   // y coordinate for pixels
+        psArray *cellPix = clustersOut->data[3]; // Cell for pixels
+        psVector *ra = clusters->data[0];        // RA coordinate
+        psVector *dec = clusters->data[1];       // Dec coordinate
+
+        for (long i = 0; i < chipPix->n; i++) {
+            const char *chipName = chipPix->data[i]; // Name of chip
+            const char *cellName = cellPix->data[i]; // Name of cell, or NULL
+            if (!data->all && (!isfinite(xPix->data.F32[i]) || !isfinite(yPix->data.F32[i]) ||
+                               !chipName || (rawFile && !cellName))) {
+                continue;
+            }
+            if (!rawFile && data->ds9) {
+                // Region file is only appropriate if we're not mapping all the way back to cell coordinates
+                fprintf(data->ds9, "image;circle(%f,%f,%f) # color=%s\n",
+                        xPix->data.F32[i], yPix->data.F32[i], data->ds9radius, data->ds9color);
+            } else {
+                fprintf(stdout, "Cluster %.10lf %.10lf --> %.3f %.3f %s%s%s\n",
+                        ra->data.F64[i], dec->data.F64[i], xPix->data.F32[i], yPix->data.F32[i],
+                        chipName ? chipName : "UNKNOWN",
+                        rawFile ? " " : "",
+                        rawFile && cellName ? cellName : (rawFile ? "UNKNOWN" : ""));
+            }
+        }
+    }
+
     psFree(pixels);
     psFree(radec);
@@ -503,4 +603,6 @@
     psFree(streaks);
     psFree(streaksOut);
+    psFree(clusters);
+    psFree(clustersOut);
 
     return true;
Index: /branches/pap/psLib/src/imageops/psImageConvolve.c
===================================================================
--- /branches/pap/psLib/src/imageops/psImageConvolve.c	(revision 28002)
+++ /branches/pap/psLib/src/imageops/psImageConvolve.c	(revision 28003)
@@ -37,7 +37,7 @@
 
 
+
 static bool threaded = false;           // Run image convolution threaded?
-
-
+static pthread_mutex_t threadMutex = PTHREAD_MUTEX_INITIALIZER;
 
 
@@ -871,14 +871,13 @@
             psFree(job);
         }
+        if (!psThreadPoolWait(true)) {
+            psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
+            psFree(gaussNorm);
+            psFree(out);
+            return NULL;
+        }
     } else if (!imageSmoothMaskPixels(out, image, mask, maskVal, x, y,
                                       gaussNorm, minGauss, size, 0, num)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to smooth pixels.");
-        psFree(gaussNorm);
-        psFree(out);
-        return NULL;
-    }
-
-    if (threaded && !psThreadPoolWait(true)) {
-        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
         psFree(gaussNorm);
         psFree(out);
@@ -1192,35 +1191,48 @@
           psImage *calcMask = psImageAlloc(numRows, numCols, PS_TYPE_IMAGE_MASK); /* Mask for calculation image; BW */
 
-          /** Smooth in X direction **/
-          for (int rowStart = 0; rowStart < numRows; rowStart+=scanRows) {
-              int rowStop = PS_MIN (rowStart + scanRows, numRows);
-
-              // allocate a job, construct the arguments for this job
-              psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_SMOOTHMASK_SCANROWS");
-              psArrayAdd(job->args, 1, calculation);
-              psArrayAdd(job->args, 1, calcMask);
-              psArrayAdd(job->args, 1, (psImage *) image); // cast away const
-              psArrayAdd(job->args, 1, (psImage *) mask); // cast away const
-              PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
-              psArrayAdd(job->args, 1, gaussNorm);
-              PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
-              PS_ARRAY_ADD_SCALAR(job->args, size,     PS_TYPE_S32);
-              PS_ARRAY_ADD_SCALAR(job->args, rowStart, PS_TYPE_S32);
-              PS_ARRAY_ADD_SCALAR(job->args, rowStop,  PS_TYPE_S32);
-              // -> psImageSmoothMask_ScanRows_F32 (calculation, calcMask, image, mask, maskVal, gauss, minGauss, size, rowStart, rowStop);
-
-              // if threading is not active, we simply run the job and return
-              if (!psThreadJobAddPending(job)) {
+          if (threaded) {
+              /** Smooth in X direction **/
+              for (int rowStart = 0; rowStart < numRows; rowStart+=scanRows) {
+                  int rowStop = PS_MIN (rowStart + scanRows, numRows);
+
+                  // allocate a job, construct the arguments for this job
+                  psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_SMOOTHMASK_SCANROWS");
+                  psArrayAdd(job->args, 1, calculation);
+                  psArrayAdd(job->args, 1, calcMask);
+                  psArrayAdd(job->args, 1, (psImage *) image); // cast away const
+                  psArrayAdd(job->args, 1, (psImage *) mask); // cast away const
+                  PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
+                  psArrayAdd(job->args, 1, gaussNorm);
+                  PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
+                  PS_ARRAY_ADD_SCALAR(job->args, size,     PS_TYPE_S32);
+                  PS_ARRAY_ADD_SCALAR(job->args, rowStart, PS_TYPE_S32);
+                  PS_ARRAY_ADD_SCALAR(job->args, rowStop,  PS_TYPE_S32);
+                  // -> psImageSmoothMask_ScanRows_F32 (calculation, calcMask, image, mask, maskVal, gauss, minGauss, size, rowStart, rowStop);
+
+                  // if threading is not active, we simply run the job and return
+                  if (!psThreadJobAddPending(job)) {
+                      psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
+                      psFree(job);
+                      psFree(calculation);
+                      psFree(calcMask);
+                      psFree(gaussNorm);
+                      return false;
+                  }
+                  psFree(job);
+              }
+              // wait here for the threaded jobs to finish (NOP if threading is not active)
+              if (!psThreadPoolWait(true)) {
                   psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
-                  psFree(job);
+                  psFree(calculation);
+                  psFree(calcMask);
+                  psFree(gaussNorm);
                   return false;
               }
-              psFree(job);
-
-          }
-
-          // wait here for the threaded jobs to finish (NOP if threading is not active)
-          if (!psThreadPoolWait(true)) {
+          } else if (!psImageSmoothMask_ScanRows_F32(calculation, calcMask, image, mask, maskVal,
+                                                     gaussNorm, minGauss, size, 0, numRows)) {
               psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
+              psFree(calculation);
+              psFree(calcMask);
+              psFree(gaussNorm);
               return false;
           }
@@ -1229,34 +1241,50 @@
 
           /** Smooth in Y direction  **/
-          for (int colStart = 0; colStart < numCols; colStart+=scanCols) {
-              int colStop = PS_MIN (colStart + scanCols, numCols);
-
-              // allocate a job, construct the arguments for this job
-              psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_SMOOTHMASK_SCANCOLS");
-              psArrayAdd(job->args, 1, output);
-              psArrayAdd(job->args, 1, calculation);
-              psArrayAdd(job->args, 1, calcMask);
-              PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
-              psArrayAdd(job->args, 1, gaussNorm);
-              PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
-              PS_ARRAY_ADD_SCALAR(job->args, size,     PS_TYPE_S32);
-              PS_ARRAY_ADD_SCALAR(job->args, colStart, PS_TYPE_S32);
-              PS_ARRAY_ADD_SCALAR(job->args, colStop,  PS_TYPE_S32);
-              // -> psImageSmoothMask_ScanCols_F32 (output, calculation, calcMask, maskVal, gauss, minGauss, size, colStart, colStop);
-
-              // if threading is not active, we simply run the job and return
-              if (!psThreadJobAddPending(job)) {
+          if (threaded) {
+              for (int colStart = 0; colStart < numCols; colStart+=scanCols) {
+                  int colStop = PS_MIN (colStart + scanCols, numCols);
+
+                  // allocate a job, construct the arguments for this job
+                  psThreadJob *job = psThreadJobAlloc("PSLIB_IMAGE_SMOOTHMASK_SCANCOLS");
+                  psArrayAdd(job->args, 1, output);
+                  psArrayAdd(job->args, 1, calculation);
+                  psArrayAdd(job->args, 1, calcMask);
+                  PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
+                  psArrayAdd(job->args, 1, gaussNorm);
+                  PS_ARRAY_ADD_SCALAR(job->args, minGauss, PS_TYPE_F32);
+                  PS_ARRAY_ADD_SCALAR(job->args, size,     PS_TYPE_S32);
+                  PS_ARRAY_ADD_SCALAR(job->args, colStart, PS_TYPE_S32);
+                  PS_ARRAY_ADD_SCALAR(job->args, colStop,  PS_TYPE_S32);
+                  // -> psImageSmoothMask_ScanCols_F32 (output, calculation, calcMask, maskVal, gauss, minGauss, size, colStart, colStop);
+
+                  // if threading is not active, we simply run the job and return
+                  if (!psThreadJobAddPending(job)) {
+                      psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
+                      psFree(job);
+                      psFree(calculation);
+                      psFree(calcMask);
+                      psFree(gaussNorm);
+                      return false;
+                  }
+                  psFree(job);
+              }
+
+              // wait here for the threaded jobs to finish (NOP if threading is not active)
+              if (!psThreadPoolWait(true)) {
                   psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
-                  psFree(job);
+                  psFree(calculation);
+                  psFree(calcMask);
+                  psFree(gaussNorm);
                   return false;
               }
-              psFree(job);
-          }
-
-          // wait here for the threaded jobs to finish (NOP if threading is not active)
-          if (!psThreadPoolWait(true)) {
+          } else if (!psImageSmoothMask_ScanCols_F32(output, calculation, calcMask, maskVal,
+                                                     gaussNorm, minGauss, size, 0, numCols)) {
               psError(PS_ERR_UNKNOWN, false, "Unable to smooth image");
+              psFree(calculation);
+              psFree(calcMask);
+              psFree(gaussNorm);
               return false;
           }
+
           psFree(calculation);
           psFree(calcMask);
@@ -1559,13 +1587,12 @@
             psFree(job);
         }
+        if (!psThreadPoolWait(true)) {
+            psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
+            psFree(conv);
+            psFree(out);
+            return NULL;
+        }
     } else if (!imageConvolveMaskColumns(conv, mask, 0, numRows, maskVal, xMin, xMax)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask columns.");
-        psFree(conv);
-        psFree(out);
-        return NULL;
-    }
-
-    if (threaded && !psThreadPoolWait(true)) {
-        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
         psFree(conv);
         psFree(out);
@@ -1597,13 +1624,12 @@
             psFree(job);
         }
+        if (!psThreadPoolWait(true)) {
+            psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
+            psFree(conv);
+            psFree(out);
+            return NULL;
+        }
     } else if (!imageConvolveMaskRows(out, conv, 0, numCols, setVal, yMin, yMax)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask columns.");
-        psFree(conv);
-        psFree(out);
-        return NULL;
-    }
-
-    if (threaded && !psThreadPoolWait(true)) {
-        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
         psFree(conv);
         psFree(out);
@@ -1679,4 +1705,5 @@
 bool psImageConvolveSetThreads(bool set)
 {
+    pthread_mutex_lock(&threadMutex);
     bool old = threaded;                // Old value
     if (set && !threaded) {
@@ -1711,4 +1738,5 @@
     }
     threaded = set;
+    pthread_mutex_unlock(&threadMutex);
     return old;
 }
Index: /branches/pap/psLib/src/mathtypes/psImage.h
===================================================================
--- /branches/pap/psLib/src/mathtypes/psImage.h	(revision 28002)
+++ /branches/pap/psLib/src/mathtypes/psImage.h	(revision 28003)
@@ -66,4 +66,5 @@
 #define P_PSIMAGE_SET_ROW0(img,r0) {*(int*)&img->row0 = r0;}
 #define P_PSIMAGE_SET_TYPE(img,t) {*(psMathType*)&img->type = t;}
+#define P_PSIMAGE_GET_TYPE(img) ((img)->type->type)
 
 /** Create an image of the specified size and type.
Index: /branches/pap/psLib/src/types/psLookupTable.c
===================================================================
--- /branches/pap/psLib/src/types/psLookupTable.c	(revision 28002)
+++ /branches/pap/psLib/src/types/psLookupTable.c	(revision 28003)
@@ -31,4 +31,6 @@
 #include "psString.h"
 #include "psError.h"
+#include "psString.h"
+#include "psSlurp.h"
 #include "psLookupTable.h"
 
@@ -153,5 +155,7 @@
         char *end = NULL; \
         ps##TYPE value = FUNC(strValue, &end, 0); \
-        if (*end != '\0' && !isspace(*end)) { \
+        if (*end != '\0' && *end != '\n' && !isspace(*end)) { \
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Characters left over after parsing %s: %s", \
+                strValue, end); \
             *status = PS_PARSE_ERROR_VALUE; \
         } \
@@ -164,5 +168,7 @@
         char *end = NULL; \
         ps##TYPE value = FUNC(strValue, &end); \
-        if (*end != '\0' && !isspace(*end)) { \
+        if (*end != '\0' && *end != '\n' && !isspace(*end)) { \
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Characters left over after parsing %s: %s", \
+                strValue, end); \
             *status = PS_PARSE_ERROR_VALUE; \
         } \
@@ -244,175 +250,132 @@
 }
 
-psArray *psVectorsReadFromFile(const char *filename,
-                               const char *format)
+psArray *psVectorsReadFromFile(const char *filename, const char *format)
 {
     PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
     PS_ASSERT_STRING_NON_EMPTY(format, NULL);
 
-    psArray*          outputArray = NULL;
-    psVector*         colVector   = NULL;
-    char*             strValue    = NULL;
-    char*             strNum      = NULL;
-    char*             line        = NULL;
-    char*             linePtr     = NULL;
-    int               numCols     = 0;
-    int               numRows     = 0;
-    FILE*             fp          = NULL;
-    const char*       tempFormat  = NULL;
-    psParseErrorType  parseStatus = PS_PARSE_SUCCESS;
-
-    // Create temp pointer which can then be used several times
-    tempFormat = format;
-
-    // Create output array and set array elements to zero
-    outputArray = psArrayAllocEmpty(INITIAL_NUM);
-
-    // Parse the format string to determine how many vectors
-    // and whether the format string is valid
-    while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus))) {
-
-        // Check for %d format sub string
+    psArray *outputArray = psArrayAllocEmpty(INITIAL_NUM); // Array of vectors to return
+    psParseErrorType parseStatus = PS_PARSE_SUCCESS; // Status of parsing
+
+    // Parse the format string to determine how many vectors and whether the format string is valid
+    const char *tempFormat = format;    // Pointer into format
+    psString strValue;                  // Format of interest
+    int numCols = 0;                    // Number of columns found in format
+    while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus)) &&
+           parseStatus == PS_PARSE_SUCCESS) {
+        if (strstr(strValue,"\%*") != 0) {
+            // Don't increase number of columns
+            continue;
+        }
+        psElemType type;                // Type specified
         if (strcmp(strValue,"\%d") == 0 ) {
-            numCols++;
-            colVector = psVectorAlloc(1,PS_TYPE_S32);
-            outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
-            psFree(colVector);
+            type = PS_TYPE_S32;
         } else if (strcmp(strValue,"\%ld") == 0) {
-            numCols++;
-            colVector = psVectorAlloc(1,PS_TYPE_S64);
-            outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
-            psFree(colVector);
+            type = PS_TYPE_S64;
         } else if (strcmp(strValue,"\%f") == 0) {
-            numCols++;
-            colVector = psVectorAlloc(1,PS_TYPE_F32);
-            outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
-            psFree(colVector);
+            type = PS_TYPE_F32;
         } else if (strcmp(strValue,"\%lf") == 0) {
-            numCols++;
-            colVector = psVectorAlloc(1,PS_TYPE_F64);
-            outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
-            psFree(colVector);
-        } else if (strstr(strValue,"\%*") != 0) {
-            // Don't increase number of columns
+            type = PS_TYPE_F64;
         } else {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                    "Invalid format specifier");
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Invalid format specifier: %s", strValue);
             psFree(strValue);
-            numCols = 0;
-            break;
-        }
+            psFree(outputArray);
+            return NULL;
+        }
+        psVector *colVector = psVectorAllocEmpty(1, type); // Vector for type
+        outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
+        psFree(colVector);
+        numCols++;
         psFree(strValue);
+    }
+    if (parseStatus != PS_PARSE_SUCCESS) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Failed to parse format at column %d: %s",
+                numCols, strValue);
+        psFree(strValue);
+        psFree(outputArray);
+        return NULL;
+    }
+
+    if (numCols == 0) {
+        // Format string parse error detected
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Format string was not parsed sucessfully");
+        psFree(outputArray);
+        return NULL;
     }
 
     // If the format string was parsed successfully and return numCols the
     // prepare to open file and read values
-    if (numCols > 0) {
-
-        // Open specified file
-        if ((fp=fopen(filename, "r")) == NULL) {
-            psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."),
-                    filename);
-            psFree(outputArray);
-            return NULL;
-        } else {
-            // Initialize array index
-            int arrayIndex = 0;
-
-            // Create reusable line for continuous read
-            line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
-
-            // Loop through file to get numRows, numCols, and column data types
-            while ((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&
-                    (parseStatus == PS_PARSE_SUCCESS))   {
-
-                // Copy pointer to line for parsing
-                linePtr = line;
-
-                // If line is not a comment or blank, then extract data
-                if (!ignoreLine(linePtr)) {
-                    numRows++;
-
-                    // Copy format pointer for parsing
-                    tempFormat = format;
-                    arrayIndex = 0;
-                    parseStatus = PS_PARSE_SUCCESS;
-
-                    // Loop through format and line strings to get values in text table file
-                    while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus))
-                            && (strNum=getToken((char**)&linePtr," \t",&parseStatus)) ) {
-                        // Set column vector
-                        colVector = outputArray->data[arrayIndex];
-
-                        // Set column entries based on format string defining the type
-                        if (strcmp(strValue,"\%d") == 0 ) {
-                            colVector = psVectorRecycle(colVector, numRows,
-                                                        colVector->type.type);
-                            parseValue(colVector,numRows-1,strNum,&parseStatus);
-                            arrayIndex++;
-                        } else if (strcmp(strValue,"\%ld") == 0) {
-                            colVector = psVectorRecycle(colVector, numRows,
-                                                        colVector->type.type);
-                            parseValue(colVector,numRows-1,strNum,&parseStatus);
-                            arrayIndex++;
-                        } else if (strcmp(strValue,"\%f") == 0) {
-                            colVector = psVectorRecycle(colVector, numRows,
-                                                        colVector->type.type);
-                            parseValue(colVector,numRows-1,strNum,&parseStatus);
-                            arrayIndex++;
-                        } else if (strcmp(strValue,"\%lf") == 0) {
-                            colVector = psVectorRecycle(colVector, numRows,
-                                                        colVector->type.type);
-                            parseValue(colVector,numRows-1,strNum,&parseStatus);
-                            arrayIndex++;
-                        } else if (strstr(strValue,"\%*") != 0) {
-                            // Don't increase number of columns
-                        }
-                        psFree(strValue);
-                        psFree(strNum);
-
-                        // If the file line was not parsed successful report
-                        // error and return NULL
-                        if (parseStatus != PS_PARSE_SUCCESS) {
-                            psError(PS_ERR_UNKNOWN, true,
-                                    "Parsing text file failed.");
-                            fclose(fp);
-                            psFree(outputArray);
-                            psFree(line);
-                            return NULL;
-                        }
-                    }
-                    if (strValue != NULL && strNum == NULL) {
-                        psError(PS_ERR_UNKNOWN, true,
-                                "Parsing text file failed - missing table value(s).");
-                        fclose(fp);
-                        psFree(outputArray);
-                        psFree(line);
-                        psFree(strValue);
-                        return NULL;
-                    }
-                }  // ignore line
+
+    psString file = psSlurpFilename(filename); // Contents of file
+    if (!file) {
+        psError(psErrorCodeLast(), false, "Unable to read file of vectors");
+        psFree(outputArray);
+        return NULL;
+    }
+
+    psArray *lines = psStringSplitArray(file, "\n", false); // Lines of file
+    psFree(file);
+    long numRows = 0;                                  // Number of rows
+    for (long i = 0; i < lines->n; i++) {
+        psString line = lines->data[i]; // Line of interest
+        if (ignoreLine(line)) {
+            continue;
+        }
+        numRows++;
+
+        char *linePtr = line;           // Pointer into line
+
+        // Copy format pointer for parsing
+        const char *tempFormat = format; // Pointer into format
+        long arrayIndex = 0;            // Index in array
+        parseStatus = PS_PARSE_SUCCESS;
+
+        // Loop through format and line strings to get values in text table file
+        char *strNum;                   // Number within line
+        while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus)) &&
+               (strNum=getToken((char**)&linePtr," \t",&parseStatus)) &&
+               parseStatus == PS_PARSE_SUCCESS) {
+            if (strstr(strValue,"\%*") != 0) {
+                continue;
             }
 
-            //Return NULL for an empty table
-            if (numRows == 0) {
-                psError(PS_ERR_UNKNOWN, true,
-                        "Parsing text file failed - input table is empty.");
-                fclose(fp);
+            // Set column vector
+            psVector *colVector = outputArray->data[arrayIndex]; // Column vector of interest
+
+            outputArray->data[arrayIndex] = colVector = psVectorRecycle(colVector, numRows,
+                                                                        colVector->type.type);
+            parseValue(colVector, numRows - 1, strNum, &parseStatus);
+            arrayIndex++;
+
+            if (parseStatus != PS_PARSE_SUCCESS) {
+                psError(PS_ERR_UNKNOWN, false, "Parsing text file failed: %s as %s", strNum, strValue);
                 psFree(outputArray);
-                psFree(line);
+                psFree(lines);
+                psFree(strNum);
+                psFree(strValue);
                 return NULL;
             }
-
-            // Read on the lines in the file - close file pointer
-            fclose(fp);
-            psFree(line);
-        }
-    } else {
-        // Format string parse error detected
-        psError(PS_ERR_UNKNOWN, true,
-                "Format string was not parsed sucessfully");
+            psFree(strValue);
+            psFree(strNum);
+
+        }
+        if (strValue != NULL && strNum == NULL) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Parsing text file failed - missing table value(s).");
+            psFree(outputArray);
+            psFree(lines);
+            psFree(strValue);
+            return NULL;
+        }
+    }
+    if (parseStatus != PS_PARSE_SUCCESS) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Failed to parse format at column %d: %s",
+                numCols, strValue);
+        psFree(strValue);
         psFree(outputArray);
         return NULL;
     }
+
+    psFree(lines);
 
     // Return populated array
Index: /branches/pap/psModules/src/astrom/pmAstrometryWCS.c
===================================================================
--- /branches/pap/psModules/src/astrom/pmAstrometryWCS.c	(revision 28002)
+++ /branches/pap/psModules/src/astrom/pmAstrometryWCS.c	(revision 28003)
@@ -972,4 +972,8 @@
     // FPA  -> TPA : identidy
 
+    // NOTE: streaksremove's linearizeTransform function passes pointers to skeleton outFPA and outChip structs
+    // Only outFPA->toSky is valid. No other memebers in these structs should be read. The resulting output transforms
+    // are copied to inFPA and inChip by the caller.
+
     int nSamples = 10;  // 10 samples in each dimension
 
Index: /branches/pap/psModules/src/camera/pmFPAConstruct.c
===================================================================
--- /branches/pap/psModules/src/camera/pmFPAConstruct.c	(revision 28002)
+++ /branches/pap/psModules/src/camera/pmFPAConstruct.c	(revision 28003)
@@ -100,27 +100,4 @@
 
     return num;
-}
-
-// Get the name of a PHU chip or cell from the header
-static psString phuNameFromHeader(const char *name, // The name to lookup: "CELL.NAME" or "CHIP.NAME"
-                                  const psMetadata *fileInfo, // FILE within the camera format description
-                                  const psMetadata *header // Primary header
-                                 )
-{
-    assert(name && strlen(name) > 0);
-    assert(fileInfo);
-    assert(header);
-
-    bool mdok = true;                   // Result of MD lookup
-    psString keyword = psMetadataLookupStr(&mdok, fileInfo, name);
-    if (!mdok || strlen(keyword) == 0) {
-        return false;
-    }
-    psMetadataItem *resultItem = psMetadataLookup(header, keyword);
-    if (!resultItem) {
-        psError(PS_ERR_IO, true, "Unable to find %s in primary header to identify %s.\n", keyword, name);
-        return NULL;
-    }
-    return psMetadataItemParseString(resultItem);
 }
 
@@ -1102,5 +1079,4 @@
 // It returns a view corresponding to the PHU
 static pmFPAview *addSource(pmFPA *fpa,       // The FPA
-                            const char *fpaObs, // The desired FPA observation name
                             const pmFPAview *phuView, // The view corresponding to the PHU, or NULL
                             const psMetadata *header, // The PHU header, or NULL
@@ -1114,19 +1090,4 @@
 
     bool mdok;                          // Status of MD lookup
-
-    // If FPA.OBS is already defined, new name must match it; otherwise, warn the user that something
-    // potentially bad is happening.
-    if (fpaObs && install) {
-        const char *currentName = psMetadataLookupStr(&mdok, fpa->concepts, "FPA.OBS"); // Current name
-        if (mdok && currentName && strlen(currentName) > 0 && strcmp(currentName, fpaObs) != 0) {
-            psWarning("FPA.OBS for new source (%s) doesn't match FPA.OBS for current fpa (%s).",
-                      fpaObs, currentName);
-        }
-        psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.OBS", PS_META_REPLACE, "Observation identifier",
-                         fpaObs);
-    } else if (!psMetadataLookup(fpa->concepts, "FPA.OBS")) {
-        // Make sure there is an FPA.OBS
-        psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.OBS", 0, "Observation identifier", "UNKNOWN");
-    }
 
     psMetadata *fileInfo = psMetadataLookupMetadata(&mdok, format, "FILE"); // The file information
@@ -1350,5 +1311,5 @@
 }
 
-bool pmFPAAddSourceFromFormat(pmFPA *fpa, const char *fpaObs, const psMetadata *format)
+bool pmFPAAddSourceFromFormat(pmFPA *fpa, const psMetadata *format)
 {
     PS_ASSERT_PTR_NON_NULL(fpa, false);
@@ -1359,5 +1320,5 @@
     pmFPAview *view = pmFPAviewAlloc(0);// View for current level
     if (phuLevel == PM_FPA_LEVEL_FPA) {
-        if (!pmFPAAddSourceFromView(fpa, fpaObs, view, format)) {
+        if (!pmFPAAddSourceFromView(fpa, view, format)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
             psFree(view);
@@ -1368,5 +1329,5 @@
         while ((chip = pmFPAviewNextChip(view, fpa, 1))) {
             if (phuLevel == PM_FPA_LEVEL_CHIP) {
-                if (!pmFPAAddSourceFromView(fpa, fpaObs, view, format)) {
+                if (!pmFPAAddSourceFromView(fpa, view, format)) {
                     psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
                     psFree(view);
@@ -1377,5 +1338,5 @@
                 while ((cell = pmFPAviewNextCell(view, fpa, 1))) {
                     if (phuLevel == PM_FPA_LEVEL_CELL) {
-                        if (!pmFPAAddSourceFromView(fpa, fpaObs, view, format)) {
+                        if (!pmFPAAddSourceFromView(fpa, view, format)) {
                             psError(PS_ERR_UNKNOWN, false, "Unable to add PHU to FPA.");
                             psFree(view);
@@ -1392,5 +1353,5 @@
 }
 
-bool pmFPAAddSourceFromView(pmFPA *fpa, const char *fpaObs, const pmFPAview *phuView,
+bool pmFPAAddSourceFromView(pmFPA *fpa, const pmFPAview *phuView,
                             const psMetadata *format)
 {
@@ -1399,5 +1360,5 @@
     PS_ASSERT_PTR_NON_NULL(format, false);
 
-    pmFPAview *view = addSource(fpa, fpaObs, phuView, NULL, format, true);
+    pmFPAview *view = addSource(fpa, phuView, NULL, format, true);
     bool status = (view != NULL);
     psFree(view);
@@ -1418,12 +1379,5 @@
     }
 
-    // Check the name of the FPA
-    psString fpaObs = phuNameFromHeader("FPA.OBS", fileInfo, phu); // New observation name for the FPA
-    if (!fpaObs || strlen(fpaObs) == 0) {
-        psWarning("Unable to determine FPA.OBS: check for FPA.OBS in FILE in camera format");
-    }
-
-    pmFPAview *view = addSource(fpa, fpaObs, NULL, phu, format, true); // View of PHU, to return
-    psFree(fpaObs);
+    pmFPAview *view = addSource(fpa, NULL, phu, format, true); // View of PHU, to return
 
     return view;
@@ -1437,5 +1391,5 @@
     PS_ASSERT_PTR_NON_NULL(format, NULL);
 
-    return addSource(fpa, NULL, NULL, phu, format, false);
+    return addSource(fpa, NULL, phu, format, false);
 }
 
Index: /branches/pap/psModules/src/camera/pmFPAConstruct.h
===================================================================
--- /branches/pap/psModules/src/camera/pmFPAConstruct.h	(revision 28002)
+++ /branches/pap/psModules/src/camera/pmFPAConstruct.h	(revision 28003)
@@ -29,5 +29,4 @@
 /// This is suitable for generating an output FPA given the desired format.
 bool pmFPAAddSourceFromFormat(pmFPA *fpa, ///< The FPA
-                              const char *fpaObs, ///< FPA.NAME for the source
                               const psMetadata *format ///< Format of file
     );
@@ -38,5 +37,4 @@
 /// configuration is required in order to describe how the FPA is laid out in terms of disk files.
 bool pmFPAAddSourceFromView(pmFPA *fpa,   ///< The FPA
-                            const char *fpaObs, ///< FPA.NAME for the source
                             const pmFPAview *phuView, ///< The view, corresponding to the PHU
                             const psMetadata *format ///< Format of file
Index: /branches/pap/psModules/src/camera/pmFPAWrite.c
===================================================================
--- /branches/pap/psModules/src/camera/pmFPAWrite.c	(revision 28002)
+++ /branches/pap/psModules/src/camera/pmFPAWrite.c	(revision 28003)
@@ -165,21 +165,21 @@
     // generate the HDU, but only copies the structure.
     if (!blank && !hdu->blankPHU && !*imageArray) {
-	if (!pmHDUGenerateForCell(cell)) {
-	    psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell --- likely programming error.");
-	    return false;
-	}
-	if (!*imageArray) {
-	    if (type == FPA_WRITE_TYPE_IMAGE) {
-		psError(PS_ERR_UNKNOWN, false, "Expected to write an image, but it is missing...programming error?.");
-		return false;
-	    }
-	    if (type == FPA_WRITE_TYPE_MASK) {
-		psWarning("No mask image for this cell; skipping");
-	    }
-	    if (type == FPA_WRITE_TYPE_VARIANCE) {
-		psWarning("No variance image for this cell; skipping");
-	    }
-	    return true;
-	}
+        if (!pmHDUGenerateForCell(cell)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell --- likely programming error.");
+            return false;
+        }
+        if (!*imageArray) {
+            if (type == FPA_WRITE_TYPE_IMAGE) {
+                psError(PS_ERR_UNKNOWN, false, "Expected to write an image, but it is missing...programming error?.");
+                return false;
+            }
+            if (type == FPA_WRITE_TYPE_MASK) {
+                psWarning("No mask image for this cell; skipping");
+            }
+            if (type == FPA_WRITE_TYPE_VARIANCE) {
+                psWarning("No variance image for this cell; skipping");
+            }
+            return true;
+        }
     }
 
@@ -307,5 +307,5 @@
 
         if (writeBlank || writeImage) {
-	    if (!pmConceptsWriteFPA(fpa, true, config)) {
+            if (!pmConceptsWriteFPA(fpa, true, config)) {
                 psError(PS_ERR_IO, false, "Unable to write concepts for FPA.\n");
                 return false;
@@ -341,5 +341,5 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-// Update the FPA.OBS, CHIP.NAME and CELL.NAME in the FITS header, if required
+// Update the CHIP.NAME and CELL.NAME in the FITS header, if required
 bool pmFPAUpdateNames(pmFPA *fpa, pmChip *chip, pmCell *cell, psS64 imageId, psS64 sourceId)
 {
@@ -375,12 +375,4 @@
         psError(PS_ERR_UNKNOWN, true, "Unable to find FILE information in camera format.\n");
         return false;
-    }
-    if (fpa) {
-        const char *fpaObsHdr = psMetadataLookupStr(&mdok, fileData, "FPA.OBS");
-        if (mdok && fpaObsHdr && strlen(fpaObsHdr) > 0) {
-            const char *fpaObs = psMetadataLookupStr(NULL, fpa->concepts, "FPA.OBS");
-            psMetadataAddStr(hduHigh->header, PS_LIST_TAIL, fpaObsHdr, PS_META_REPLACE,
-                             "Observation identifier", fpaObs);
-        }
     }
 
Index: /branches/pap/psModules/src/camera/pmFPAfileFitsIO.c
===================================================================
--- /branches/pap/psModules/src/camera/pmFPAfileFitsIO.c	(revision 28002)
+++ /branches/pap/psModules/src/camera/pmFPAfileFitsIO.c	(revision 28003)
@@ -75,13 +75,6 @@
     }
 
-    pmFPA *nameSource = file->src; // Source of FPA.OBS
-    if (!nameSource) {
-        nameSource = file->fpa;
-    }
-    bool mdok;                  // Status of MD lookup
-    const char *fpaObs = psMetadataLookupStr(&mdok, nameSource->concepts, "FPA.OBS"); // Observation id
-
     pmFPA *copy = pmFPAConstruct(file->camera, file->cameraName);  // FPA to return
-    if (!pmFPAAddSourceFromView(copy, fpaObs, phuView, file->format)) {
+    if (!pmFPAAddSourceFromView(copy, phuView, file->format)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to insert HDU into FPA for writing.\n");
         psFree(copy);
Index: /branches/pap/psModules/src/camera/pmFPAfileIO.c
===================================================================
--- /branches/pap/psModules/src/camera/pmFPAfileIO.c	(revision 28002)
+++ /branches/pap/psModules/src/camera/pmFPAfileIO.c	(revision 28003)
@@ -286,12 +286,5 @@
             }
 
-            pmFPA *nameSource = file->src; // Source of FPA.OBS
-            if (!nameSource) {
-                nameSource = file->fpa;
-            }
-            bool mdok;                  // Status of MD lookup
-            const char *fpaObs = psMetadataLookupStr(&mdok, nameSource->concepts, "FPA.OBS"); // Obs. id
-
-            pmFPAAddSourceFromView(file->fpa, fpaObs, view, format);
+            pmFPAAddSourceFromView(file->fpa, view, format);
             psTrace ("psModules.camera", 5, "created fpa data elements for %s (%s) (%d:%d:%d)\n",
                      file->name, file->name, view->chip, view->cell, view->readout);
Index: /branches/pap/psModules/src/detrend/pmShutterCorrection.c
===================================================================
--- /branches/pap/psModules/src/detrend/pmShutterCorrection.c	(revision 28002)
+++ /branches/pap/psModules/src/detrend/pmShutterCorrection.c	(revision 28003)
@@ -1015,11 +1015,15 @@
 
         pmShutterCorrection *corr = pmShutterCorrectionFullFit(newtimes, newcounts, newerrors, guess); // The actual correction
-        psTrace("psModules.detrend", 5, "Shutter correction fit: scale: %f, offset: %f, offref: %f\n", corr->scale, corr->offset, corr->offref);
-
-        if (corr && isfinite(corr->offref) && corr->valid) {
-            psTrace("psModules.detrend", 5, "Sample reference value: %f\n", corr->offref);
-            meanRef += corr->offref;
-            numGood++;
-        }
+
+        if (corr) {
+	    psTrace("psModules.detrend", 5, "Shutter correction fit: scale: %f, offset: %f, offref: %f\n", corr->scale, corr->offset, corr->offref);
+	    if (isfinite(corr->offref) && corr->valid) {
+		psTrace("psModules.detrend", 5, "Sample reference value: %f\n", corr->offref);
+		meanRef += corr->offref;
+		numGood++;
+	    }
+        } else {
+	    psTrace("psModules.detrend", 5, "failed Shutter correction fit\n");
+	}
 
         psFree(corr);
Index: /branches/pap/psModules/src/extras/Makefile.am
===================================================================
--- /branches/pap/psModules/src/extras/Makefile.am	(revision 28002)
+++ /branches/pap/psModules/src/extras/Makefile.am	(revision 28003)
@@ -17,4 +17,5 @@
 	pmKapaPlots.h \
 	pmVisual.h \
+	ippDiffMode.h \
 	ippStages.h
 
Index: /branches/pap/psModules/src/extras/ippDiffMode.h
===================================================================
--- /branches/pap/psModules/src/extras/ippDiffMode.h	(revision 28003)
+++ /branches/pap/psModules/src/extras/ippDiffMode.h	(revision 28003)
@@ -0,0 +1,20 @@
+/* @file ippDiffMode.h
+ * @brief some macro defintions for the stages of the pipeline
+ * @author Bill Sweeney, IfA
+ *
+ * Copyright 2010 Institute for Astronomy, University of Hawaii
+ */
+
+#ifndef IPP_DIFF_MODE_H
+#define IPP_DIFF_MODE_H
+
+typedef enum {
+    IPP_DIFF_MODE_UNDEFINED   = 0,
+    IPP_DIFF_MODE_WARP_WARP   = 1,
+    IPP_DIFF_MODE_WARP_STACK  = 2,
+    IPP_DIFF_MODE_STACK_WARP  = 3,
+    IPP_DIFF_MODE_STACK_STACK = 4
+} ippDiffMode;
+
+
+#endif
Index: /branches/pap/psModules/src/extras/ippStages.h
===================================================================
--- /branches/pap/psModules/src/extras/ippStages.h	(revision 28002)
+++ /branches/pap/psModules/src/extras/ippStages.h	(revision 28003)
@@ -1,3 +1,3 @@
-/* @file psVisual.h
+/* @file ippStages.h
  * @brief some macro defintions for the stages of the pipeline
  * @author Bill Sweeney, IfA
Index: /branches/pap/psModules/src/objects/pmPSFtryModel.c
===================================================================
--- /branches/pap/psModules/src/objects/pmPSFtryModel.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmPSFtryModel.c	(revision 28003)
@@ -107,6 +107,6 @@
     // as we loop over orders, we need to refer to the initial selection, but we modify the
     // option values to match the current guess: save the max values here:
-    int Nx = options->psfTrendNx;
-    int Ny = options->psfTrendNy;
+    int Nx = (options->psfTrendMode == PM_TREND_MAP) ? options->psfTrendNx : options->psfTrendNx + 1;
+    int Ny = (options->psfTrendMode == PM_TREND_MAP) ? options->psfTrendNy : options->psfTrendNy + 1;
     for (int i = orderMin; i <= orderMax; i++) {
 
Index: /branches/pap/psModules/src/objects/pmSourceExtendedPars.c
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceExtendedPars.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceExtendedPars.c	(revision 28003)
@@ -36,23 +36,67 @@
 #include "pmSourceExtendedPars.h"
 
-// *** pmSourceRadialProfile describes the radial profile of a source in elliptical contours, and 
-// intermediate data used to measure the profile
+// pmSourceRadialFlux carries the raw radial flux information, including angular bins
+static void pmSourceRadialFluxFree(pmSourceRadialFlux *flux)
+{
+    if (!flux) return;
+    psFree(flux->radii);
+    psFree(flux->fluxes);
+    psFree(flux->theta);
+    psFree(flux->isophotalRadii);
+}
+
+pmSourceRadialFlux *pmSourceRadialFluxAlloc()
+{
+    pmSourceRadialFlux *flux = (pmSourceRadialFlux *)psAlloc(sizeof(pmSourceRadialFlux));
+    psMemSetDeallocator(flux, (psFreeFunc) pmSourceRadialFluxFree);
+
+    flux->radii = NULL;
+    flux->fluxes = NULL;
+    flux->theta = NULL;
+    flux->isophotalRadii = NULL;
+
+    return flux;
+}
+
+bool psMemCheckSourceRadialFlux(psPtr ptr)
+{
+    PS_ASSERT_PTR(ptr, false);
+    return ( psMemGetDeallocator(ptr) == (psFreeFunc) pmSourceRadialFluxFree);
+}
+
+// pmSourceEllipticalFlux carries the elliptical renormalized radial flux info
+static void pmSourceEllipticalFluxFree(pmSourceEllipticalFlux *flux)
+{
+    if (!flux) return;
+    psFree(flux->radiusElliptical);
+    psFree(flux->fluxElliptical);
+}
+
+pmSourceEllipticalFlux *pmSourceEllipticalFluxAlloc()
+{
+    pmSourceEllipticalFlux *flux = (pmSourceEllipticalFlux *)psAlloc(sizeof(pmSourceEllipticalFlux));
+    psMemSetDeallocator(flux, (psFreeFunc) pmSourceEllipticalFluxFree);
+
+    flux->radiusElliptical = NULL;
+    flux->fluxElliptical = NULL;
+
+    return flux;
+}
+
+bool psMemCheckSourceEllipticalFlux(psPtr ptr)
+{
+    PS_ASSERT_PTR(ptr, false);
+    return ( psMemGetDeallocator(ptr) == (psFreeFunc) pmSourceEllipticalFluxFree);
+}
+
+// pmSourceRadialProfile defines flux information in radial bins
 static void pmSourceRadialProfileFree(pmSourceRadialProfile *profile)
 {
-    if (!profile) {
-        return;
-    }
-    psFree(profile->radii);
-    psFree(profile->fluxes);
-    psFree(profile->theta);
-    psFree(profile->isophotalRadii);
-
-    psFree(profile->radiusElliptical);
-    psFree(profile->fluxElliptical);
-
+    if (!profile) return;
     psFree(profile->binSB);
     psFree(profile->binSBstdev);
     psFree(profile->binSBerror);
-
+    psFree(profile->binSum);
+    psFree(profile->binFill);
     psFree(profile->radialBins);
     psFree(profile->area);
@@ -63,20 +107,12 @@
     pmSourceRadialProfile *profile = (pmSourceRadialProfile *)psAlloc(sizeof(pmSourceRadialProfile));
     psMemSetDeallocator(profile, (psFreeFunc) pmSourceRadialProfileFree);
-
-    profile->radii = NULL;
-    profile->fluxes = NULL;
-    profile->theta = NULL;
-    profile->isophotalRadii = NULL;
-
-    profile->radiusElliptical = NULL;
-    profile->fluxElliptical = NULL;
 
     profile->binSB = NULL;
     profile->binSBstdev = NULL;
     profile->binSBerror = NULL;
-
+    profile->binSum = NULL;
+    profile->binFill = NULL;
     profile->radialBins = NULL;
     profile->area = NULL;
-
     return profile;
 }
@@ -88,6 +124,6 @@
 }
 
-
-// *** pmSourceRadialProfileFreeVectors frees the intermediate data values
+# if (0)
+// pmSourceRadialProfileFreeVectors frees the intermediate data values
 bool pmSourceRadialProfileFreeVectors(pmSourceRadialProfile *profile) {
 
@@ -124,4 +160,5 @@
     return true;
 }
+# endif
 
 // *** pmSourceRadialProfileSortPair is a utility function for sorting a pair of vectors
@@ -150,7 +187,8 @@
     if (!pars) return;
 
-    psFree(pars->profile);
-    psFree(pars->petrosian_50);
-    psFree(pars->petrosian_80);
+    psFree(pars->radFlux);
+    psFree(pars->ellipticalFlux);
+    psFree(pars->radProfile);
+    psFree(pars->petProfile);
     return;
 }
@@ -160,8 +198,17 @@
     psMemSetDeallocator(pars, (psFreeFunc) pmSourceExtendedParsFree);
 
-    pars->profile = NULL;
-    pars->petrosian_50 = NULL;
-    pars->petrosian_80 = NULL;
-
+    pars->radFlux = NULL;
+    pars->ellipticalFlux = NULL;
+    pars->radProfile = NULL;
+    pars->petProfile = NULL;
+
+    pars->petrosianFlux = NAN;
+    pars->petrosianFluxErr = NAN;
+    pars->petrosianRadius = NAN;
+    pars->petrosianRadiusErr = NAN;
+    pars->petrosianR90 = NAN;
+    pars->petrosianR90Err = NAN;
+    pars->petrosianR50 = NAN;
+    pars->petrosianR50Err = NAN;
     return pars;
 }
Index: /branches/pap/psModules/src/objects/pmSourceExtendedPars.h
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceExtendedPars.h	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceExtendedPars.h	(revision 28003)
@@ -19,30 +19,49 @@
     psVector *theta;			// angles corresponding to above radial profiles
     psVector *isophotalRadii;		// isophotal radius for the above angles
+} pmSourceRadialFlux;
 
+typedef struct {
     psVector *radiusElliptical;		// normalized radial coordinates for all relevant pixels
     psVector *fluxElliptical;		// flux for the above radial coordinates
+} pmSourceEllipticalFlux;
 
+typedef struct {
     psVector *binSB;			// mean surface brightness within radial bins
     psVector *binSBstdev;		// scatter of mean surface brightness within radial bins
     psVector *binSBerror;		// formal error on mean surface brightness within radial bins
-
-    psVector *radialBins;		// radii corresponding to above binnedBlux
+    psVector *binSum;			// sum of flux within radial bins
+    psVector *binFill;			// fraction of area actually lit
+    psVector *radialBins;		// radii corresponding to above binnedFlux
     psVector *area;			// differential area of the non-overlapping radial bins
-
-    psEllipseAxes axes;			// shape of elliptical contour
 } pmSourceRadialProfile;
 
 typedef struct {
-  float flux;
-  float fluxErr;
-  float radius;
-  float radiusErr;
+    float flux;
+    float fluxErr;
+    float radius;
+    float radiusErr;
 } pmSourceExtendedFlux;
 
 typedef struct {
-  pmSourceRadialProfile   *profile;
-  pmSourceExtendedFlux    *petrosian_50;
-  pmSourceExtendedFlux    *petrosian_80;
+    pmSourceRadialFlux     *radFlux;	    // raw radial flux information
+    pmSourceEllipticalFlux *ellipticalFlux; // flux for elliptically-renormalized radii
+    pmSourceRadialProfile  *radProfile;	    // surface brightness profile in specified fixed bins
+    pmSourceRadialProfile  *petProfile;	    // surface brightness profile in petrosian bins
+    psEllipseAxes axes;			    // shape of elliptical contour
+    float petrosianFlux;
+    float petrosianFluxErr;
+    float petrosianRadius;
+    float petrosianRadiusErr;
+    float petrosianR90;
+    float petrosianR90Err;
+    float petrosianR50;
+    float petrosianR50Err;
 } pmSourceExtendedPars;
+
+pmSourceRadialFlux *pmSourceRadialFluxAlloc();
+bool psMemCheckSourceRadialFlux(psPtr ptr);
+
+pmSourceEllipticalFlux *pmSourceEllipticalFluxAlloc();
+bool psMemCheckSourceEllipticalFlux(psPtr ptr);
 
 // *** pmSourceRadialProfile describes the radial profile of a source in elliptical contours, and 
@@ -50,7 +69,4 @@
 pmSourceRadialProfile *pmSourceRadialProfileAlloc();
 bool psMemCheckSourceRadialProfile(psPtr ptr);
-
-// *** pmSourceRadialProfileFreeVectors frees the intermediate data values
-bool pmSourceRadialProfileFreeVectors(pmSourceRadialProfile *profile);
 
 // *** pmSourceExtendedPars describes the possible collection of extended flux measurements for a source
@@ -65,4 +81,6 @@
 bool pmSourceRadialProfileSortPair(psVector *index, psVector *extra);
 
+
+
 /// @}
 # endif /* PM_SOURCE_H */
Index: /branches/pap/psModules/src/objects/pmSourceFitSet.c
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceFitSet.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceFitSet.c	(revision 28003)
@@ -62,5 +62,5 @@
     // before pmSourceFitSetInit is called
     for (int i = 0; i < fitSets->n; i++) {
-        psAssert (fitSets->data[i] == NULL, "failure to init or clear fitSets?");
+        psAssert(fitSets->data[i] == NULL, "failure to init or clear fitSets?");
     }
     return true;
@@ -68,5 +68,6 @@
 
 void pmSourceFitSetDone (void) {
-    psFree (fitSets);
+    psFree(fitSets);
+    fitSets = NULL;
 }
 
@@ -113,38 +114,31 @@
 }
 
-pmSourceFitSetData *pmSourceFitSetDataSet (psArray *modelSet) {
-
-    pmSourceFitSetData *thisSet = NULL;
-
-    psAssert (fitSets, "pmSourceFitSetInit not called");
+pmSourceFitSetData *pmSourceFitSetDataSet (psArray *modelSet)
+{
+    psAssert(fitSets, "pmSourceFitSetInit not called");
 
     // find the fitSet used by this thread
     pthread_t id = pthread_self();
 
-    // is our ID is already on the stack, abort.
-    // we do not need to lock to do this....
+    // If our ID is already on the stack, abort.
+    // We do need to lock on this because someone might pull one of the fitSets out from under us
+    pthread_mutex_lock(&fitSetInitMutex);
     for (int i = 0; i < fitSets->n; i++) {
-        thisSet = fitSets->data[i];
+        pmSourceFitSetData *thisSet = fitSets->data[i];
         if (!thisSet) continue;
         if (thisSet->thread == id) {
-            break;
-        }
-        thisSet = NULL;
-    }
-    psAssert (thisSet == NULL, "pmSourceFitSetDataSet() called but previous entry not cleared");
-
-    thisSet = pmSourceFitSetDataAlloc(modelSet);
-
-    pthread_mutex_lock (&fitSetInitMutex);
-
-    // find an entry that is NULL and place it there
+            psAbort("pmSourceFitSetDataSet() called but previous entry not cleared");
+        }
+    }
+
+    // Find an open slot
     for (int i = 0; i < fitSets->n; i++) {
         if (fitSets->data[i]) continue;
-        fitSets->data[i] = thisSet;
-        pthread_mutex_unlock (&fitSetInitMutex);
+        pmSourceFitSetData *thisSet = fitSets->data[i] = pmSourceFitSetDataAlloc(modelSet);
+        pthread_mutex_unlock(&fitSetInitMutex);
         return thisSet;
     }
-    pthread_mutex_unlock (&fitSetInitMutex);
-    psAbort ("no empty slot for new pmSourceFitSetData");
+    pthread_mutex_unlock(&fitSetInitMutex);
+    psAbort("no empty slot for new pmSourceFitSetData");
     return NULL;
 }
@@ -152,47 +146,41 @@
 pmSourceFitSetData *pmSourceFitSetDataGet (void) {
 
-    psAssert (fitSets, "pmSourceFitSetInit not called");
-
-    // find the fitSet used by this thread
+    psAssert(fitSets, "pmSourceFitSetInit not called");
+
+    // Find the fitSet used by this thread
+    // We do need to lock on this because someone might pull one of the fitSets out from under us
     pthread_t id = pthread_self();
-
-    // can we find our fitSet?  we do not need to lock to do this....
-    pmSourceFitSetData *thisSet = NULL;
+    pthread_mutex_lock(&fitSetInitMutex);
     for (int i = 0; i < fitSets->n; i++) {
-        thisSet = fitSets->data[i];
+        pmSourceFitSetData *thisSet = fitSets->data[i];
         if (!thisSet) continue;
         if (thisSet->thread == id) {
-            break;
-        }
-        thisSet = NULL;
-    }
-    psAssert (thisSet != NULL, "pmSourceFitSetDataGet() called, but no entry found");
-
-    return thisSet;
-}
-
-void pmSourceFitSetDataClear (void) {
-
-    int i;
-
+            pthread_mutex_unlock(&fitSetInitMutex);
+            return thisSet;
+        }
+    }
+    psAbort("pmSourceFitSetDataGet() called, but no entry found");
+}
+
+void pmSourceFitSetDataClear (void)
+{
     psAssert (fitSets, "pmSourceFitSetInit not called");
 
-    // find the fitSet used by this thread
+    // Find the fitSet used by this thread
+    // We do need to lock on this because someone might pull one of the fitSets out from under us
     pthread_t id = pthread_self();
-
-    // can we find our fitSet?  we do not need to lock to do this....
-    pmSourceFitSetData *thisSet = NULL;
-    for (i = 0; i < fitSets->n; i++) {
-        thisSet = fitSets->data[i];
+    pthread_mutex_lock(&fitSetInitMutex);
+    for (int i = 0; i < fitSets->n; i++) {
+        pmSourceFitSetData *thisSet = fitSets->data[i];
         if (!thisSet) continue;
         if (thisSet->thread == id) {
-            break;
-        }
-        thisSet = NULL;
-    }
-    psAssert (thisSet != NULL, "pmSourceFitSetDataClear() called, but no entry found");
-
-    psFree (thisSet);
-    fitSets->data[i] = NULL;
+            psFree(thisSet);
+            fitSets->data[i] = NULL;
+            pthread_mutex_unlock(&fitSetInitMutex);
+            return;
+        }
+    }
+    psAbort("pmSourceFitSetDataClear() called, but no entry found");
+
     return;
 }
@@ -481,5 +469,5 @@
 
             // Convert i/j to image space:
-	    // 0.5 PIX: the coordinate values must be in pixel coords, not index	    
+            // 0.5 PIX: the coordinate values must be in pixel coords, not index
             coord->data.F32[0] = (psF32) (j + 0.5 + source->pixels->col0);
             coord->data.F32[1] = (psF32) (i + 0.5 + source->pixels->row0);
Index: /branches/pap/psModules/src/objects/pmSourceIO.c
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceIO.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceIO.c	(revision 28003)
@@ -551,11 +551,11 @@
 		}
 		if (!strcmp (exttype, "PS1_V1")) {
-		    status &= pmSourcesWrite_CMF_PS1_V1_XSRC (file->fits, sources, xsrcname, recipe);
+		    status &= pmSourcesWrite_CMF_PS1_V1_XSRC (file->fits, readout, sources, file->header, xsrcname, recipe);
 		}
 		if (!strcmp (exttype, "PS1_V2")) {
-		    status &= pmSourcesWrite_CMF_PS1_V2_XSRC (file->fits, sources, xsrcname, recipe);
+		    status &= pmSourcesWrite_CMF_PS1_V2_XSRC (file->fits, readout, sources, file->header, xsrcname, recipe);
 		}
 		if (!strcmp (exttype, "PS1_DV1")) {
-		    status &= pmSourcesWrite_CMF_PS1_DV1_XSRC (file->fits, sources, xsrcname, recipe);
+		    status &= pmSourcesWrite_CMF_PS1_DV1_XSRC (file->fits, readout, sources, file->header, xsrcname, recipe);
 		}
             }
@@ -568,11 +568,11 @@
 		}
 		if (!strcmp (exttype, "PS1_V1")) {
-		    status &= pmSourcesWrite_CMF_PS1_V1_XFIT (file->fits, sources, xfitname);
+		    status &= pmSourcesWrite_CMF_PS1_V1_XFIT (file->fits, readout, sources, xfitname);
 		}
 		if (!strcmp (exttype, "PS1_V2")) {
-		    status &= pmSourcesWrite_CMF_PS1_V2_XFIT (file->fits, sources, xfitname);
+		    status &= pmSourcesWrite_CMF_PS1_V2_XFIT (file->fits, readout, sources, xfitname);
 		}
 		if (!strcmp (exttype, "PS1_DV1")) {
-		    status &= pmSourcesWrite_CMF_PS1_DV1_XFIT (file->fits, sources, xfitname);
+		    status &= pmSourcesWrite_CMF_PS1_DV1_XFIT (file->fits, readout, sources, xfitname);
 		}
             }
Index: /branches/pap/psModules/src/objects/pmSourceIO.h
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceIO.h	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceIO.h	(revision 28003)
@@ -36,14 +36,14 @@
 
 bool pmSourcesWrite_CMF_PS1_V1 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
-bool pmSourcesWrite_CMF_PS1_V1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe);
-bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, psArray *sources, char *extname);
+bool pmSourcesWrite_CMF_PS1_V1_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe);
+bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname);
 
 bool pmSourcesWrite_CMF_PS1_V2 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
-bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe);
-bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, psArray *sources, char *extname);
+bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe);
+bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname);
 
 bool pmSourcesWrite_CMF_PS1_DV1 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname);
-bool pmSourcesWrite_CMF_PS1_DV1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe);
-bool pmSourcesWrite_CMF_PS1_DV1_XFIT (psFits *fits, psArray *sources, char *extname);
+bool pmSourcesWrite_CMF_PS1_DV1_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe);
+bool pmSourcesWrite_CMF_PS1_DV1_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname);
 
 bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config);
Index: /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c	(revision 28003)
@@ -364,5 +364,5 @@
 
 // XXX this layout is still the same as PS1_DEV_1
-bool pmSourcesWrite_CMF_PS1_DV1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe)
+bool pmSourcesWrite_CMF_PS1_DV1_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)
 {
 
@@ -536,5 +536,5 @@
 
 // XXX this layout is still the same as PS1_DEV_1
-bool pmSourcesWrite_CMF_PS1_DV1_XFIT (psFits *fits, psArray *sources, char *extname)
+bool pmSourcesWrite_CMF_PS1_DV1_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname)
 {
 
Index: /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_V1.c	(revision 28003)
@@ -339,5 +339,5 @@
 
 // XXX this layout is still the same as PS1_DEV_1
-bool pmSourcesWrite_CMF_PS1_V1_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe)
+bool pmSourcesWrite_CMF_PS1_V1_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)
 {
 
@@ -516,5 +516,5 @@
 
 // XXX this layout is still the same as PS1_DEV_1
-bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, psArray *sources, char *extname)
+bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname)
 {
 
Index: /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c
===================================================================
--- /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c	(revision 28002)
+++ /branches/pap/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c	(revision 28003)
@@ -45,6 +45,5 @@
 // followed by a zero-size matrix, followed by the table data
 
-bool pmSourcesWrite_CMF_PS1_V2 (psFits *fits, pmReadout *readout, psArray *sources,
-                                psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
+bool pmSourcesWrite_CMF_PS1_V2 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
 {
     PS_ASSERT_PTR_NON_NULL(fits, false);
@@ -54,5 +53,4 @@
     psArray *table;
     psMetadata *row;
-    int i;
     psF32 *PAR, *dPAR;
     psEllipseAxes axes;
@@ -83,8 +81,8 @@
         pmSource *source = (pmSource *) sources->data[0];
         if (source->seq == -1) {
-          // let's write these out in S/N order
-          sources = psArraySort (sources, pmSourceSortBySN);
+	    // let's write these out in S/N order
+	    sources = psArraySort (sources, pmSourceSortBySN);
         } else {
-          sources = psArraySort (sources, pmSourceSortBySeq);
+	    sources = psArraySort (sources, pmSourceSortBySeq);
         }
     }
@@ -94,5 +92,5 @@
     // we write out PSF-fits for all sources, regardless of quality.  the source flags tell us the state
     // by the time we call this function, all values should be assigned.  let's use asserts to be sure in some cases.
-    for (i = 0; i < sources->n; i++) {
+    for (int i = 0; i < sources->n; i++) {
         pmSource *source = (pmSource *) sources->data[i];
 
@@ -102,5 +100,5 @@
         // generated on Alloc, and would thus be wrong for read in sources.
         if (source->seq == -1) {
-          source->seq = i;
+	    source->seq = i;
         }
 
@@ -114,10 +112,10 @@
             yPos = PAR[PM_PAR_YPOS];
             if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) {
-              xErr = dPAR[PM_PAR_XPOS];
-              yErr = dPAR[PM_PAR_YPOS];
+		xErr = dPAR[PM_PAR_XPOS];
+		yErr = dPAR[PM_PAR_YPOS];
             } else {
-              // in linear-fit mode, there is no error on the centroid
-              xErr = source->peak->dx;
-              yErr = source->peak->dy;
+		// in linear-fit mode, there is no error on the centroid
+		xErr = source->peak->dx;
+		yErr = source->peak->dy;
             }
             if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
@@ -212,4 +210,5 @@
     }
 
+    // XXX why do we make a copy here to be supplemented with the masks?  why not do this in the calling function?
     psMetadata *header = psMetadataCopy(NULL, tableHeader);
     pmSourceMasksHeader(header);
@@ -344,6 +343,5 @@
 }
 
-// XXX this layout is still the same as PS1_DEV_1
-bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe)
+bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)
 {
 
@@ -354,4 +352,5 @@
     psF32 xPos, yPos;
     psF32 xErr, yErr;
+    int nRow = -1;
 
     // create a header to hold the output data
@@ -361,4 +360,20 @@
     psMetadataAddStr (outhead, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "xsrc table extension", extname);
 
+    pmChip *chip = readout->parent->parent;
+    pmFPA  *fpa  = chip->parent;
+
+    // zero point corrections
+    bool status1 = false;
+    bool status2 = false;
+    float magOffset = 0.0;
+    float exptime   = psMetadataLookupF32(&status1, fpa->concepts, "FPA.EXPOSURE");
+    float zeropt    = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");
+    if (!isfinite(zeropt)) {
+        zeropt    = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
+    }
+    if (status1 && status2 && (exptime > 0.0)) {
+        magOffset = zeropt + 2.5*log10(exptime);
+    }
+
     // let's write these out in S/N order
     sources = psArraySort (sources, pmSourceSortBySN);
@@ -367,12 +382,24 @@
 
     // which extended source analyses should we perform?
-    // bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
+    bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
+    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
     // bool doIsophotal    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ISOPHOTAL");
-    // bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
     // bool doKron         = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON");
 
-    psVector *radialBinsLower = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
-    psVector *radialBinsUpper = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
-    assert (radialBinsLower->n == radialBinsUpper->n);
+    psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
+    psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    psAssert (radMin->n == radMax->n, "inconsistent annular bins");
+
+    // int nRadialBins = 0;
+    // if (doAnnuli) {
+    // 	// get the max count of radial bins
+    // 	for (int i = 0; i < sources->n; i++) {
+    // 	    pmSource *source = sources->data[i];
+    // 	    if (!source->extpars) continue;
+    // 	    if (!source->extpars->radProfile ) continue;
+    //         if (!source->extpars->radProfile->binSB) continue;
+    // 	    nRadialBins = PS_MAX(nRadialBins, source->extpars->radProfile->binSB->n);
+    // 	}
+    // }
 
     // we write out all sources, regardless of quality.  the source flags tell us the state
@@ -410,14 +437,31 @@
         psMetadataAdd (row, PS_LIST_TAIL, "Y_EXT_SIG",        PS_DATA_F32, "Sigma in EXT y coordinate",                  yErr);
 
-# if (0)
+	float AxialRatio = NAN;
+	float AxialTheta = NAN;
+	pmSourceExtendedPars *extpars = source->extpars;
+	if (extpars) {
+	    AxialRatio = extpars->axes.minor / extpars->axes.major;
+	    AxialTheta = extpars->axes.theta;
+	}
+        psMetadataAdd (row, PS_LIST_TAIL, "F25_ARATIO",       PS_DATA_F32, "Axial Ratio of radial profile",              AxialRatio);
+        psMetadataAdd (row, PS_LIST_TAIL, "F25_THETA",        PS_DATA_F32, "Angle of radial profile ellipse",                  AxialTheta);
+
         // Petrosian measurements
         // XXX insert header data: petrosian ref radius, flux ratio
+	// XXX check flags to see if Pet was measured
         if (doPetrosian) {
-            pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
-            if (petrosian) {
-                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       petrosian->mag);
-                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
-                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
-                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
+	    pmSourceExtendedPars *extpars = source->extpars;
+            if (extpars) {
+		// XXX note that this mag is either calibrated or instrumental depending on existence of zero point 
+		float mag = (extpars->petrosianFlux > 0.0) ? -2.5*log10(extpars->petrosianFlux) + magOffset : NAN; // XXX zero point
+		float magErr = (extpars->petrosianFlux > 0.0) ? extpars->petrosianFlux / extpars->petrosianFluxErr : NAN; // XXX zero point
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude", mag);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", magErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius (pix)", extpars->petrosianRadius);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error (pix)", extpars->petrosianRadiusErr);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50",     PS_DATA_F32, "Petrosian R50 (pix)", extpars->petrosianR50);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)", extpars->petrosianR50Err);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90",     PS_DATA_F32, "Petrosian R90 (pix)", extpars->petrosianR90);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)", extpars->petrosianR90Err);
             } else {
                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
@@ -425,7 +469,12 @@
                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50",     PS_DATA_F32, "Petrosian R50 (pix)", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)",NAN); 
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90",     PS_DATA_F32, "Petrosian R90 (pix)", NAN);
+                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)",NAN); 
             }
         }
 
+# if (0)
         // Kron measurements
         if (doKron) {
@@ -460,67 +509,74 @@
             }
         }
-
-        // Flux Annuli
+# endif
+
+        // Flux Annuli (if we have extended source measurements, we have these.  only optionally save them)
         if (doAnnuli) {
-            pmSourceAnnuli *annuli = source->extpars->annuli;
-            if (annuli) {
-                psVector *fluxVal = annuli->flux;
-                psVector *fluxErr = annuli->fluxErr;
-                psVector *fluxVar = annuli->fluxVar;
-
-                for (int j = 0; j < fluxVal->n; j++) {
-                    char name[32];
-                    sprintf (name, "FLUX_VAL_R_%02d", j);
-                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
-                    sprintf (name, "FLUX_ERR_R_%02d", j);
-                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
-                    sprintf (name, "FLUX_VAR_R_%02d", j);
-                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
-                }
-            } else {
-                for (int j = 0; j < radialBinsLower->n; j++) {
-                    char name[32];
-                    sprintf (name, "FLUX_VAL_R_%02d", j);
-                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
-                    sprintf (name, "FLUX_ERR_R_%02d", j);
-                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
-                    sprintf (name, "FLUX_VAR_R_%02d", j);
-                    psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
-                }
-            }
-        }
-
-# endif
-        psArrayAdd (table, 100, row);
-        psFree (row);
-    }
-
+	    psVector *radSB   = psVectorAlloc(radMin->n, PS_TYPE_F32);
+	    psVector *radFlux = psVectorAlloc(radMin->n, PS_TYPE_F32);
+	    psVector *radFill = psVectorAlloc(radMin->n, PS_TYPE_F32);
+	    psVectorInit (radSB, NAN);
+	    psVectorInit (radFlux, NAN);
+	    psVectorInit (radFill, NAN);
+	    if (!source->extpars) goto empty_annuli;
+	    if (!source->extpars->radProfile) goto empty_annuli;
+	    if (!source->extpars->radProfile->binSB) goto empty_annuli;
+	    psAssert (source->extpars->radProfile->binSum, "programming error");
+	    psAssert (source->extpars->radProfile->binFill, "programming error");
+	    psAssert (source->extpars->radProfile->binSB->n <= radFlux->n, "inconsistent vector lengths");
+	    psAssert (source->extpars->radProfile->binSum->n <= radFlux->n, "inconsistent vector lengths");
+	    psAssert (source->extpars->radProfile->binFill->n <= radFlux->n, "inconsistent vector lengths");
+
+	    // copy the data from fluxVal (which is not guaranteed to be the full length) to radFlux
+	    for (int j = 0; j < source->extpars->radProfile->binSB->n; j++) {
+		radSB->data.F32[j]   = source->extpars->radProfile->binSB->data.F32[j];
+		radFlux->data.F32[j] = source->extpars->radProfile->binSum->data.F32[j];
+		radFill->data.F32[j] = source->extpars->radProfile->binFill->data.F32[j];
+	    }
+
+	empty_annuli:
+	    psMetadataAdd (row, PS_LIST_TAIL, "PROF_SB", PS_DATA_VECTOR, "mean surface brightness annuli", radSB);
+	    psMetadataAdd (row, PS_LIST_TAIL, "PROF_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux);
+	    psMetadataAdd (row, PS_LIST_TAIL, "PROF_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill);
+	    psFree (radSB);
+	    psFree (radFlux);
+	    psFree (radFill);
+	}
+	if (nRow < 0) {
+	    nRow = row->list->n;
+	} else {
+	    psAssert (nRow == row->list->n, "inconsistent row lengths");
+	}
+	psArrayAdd (table, 100, row);
+	psFree (row);
+    }
+    
     if (table->n == 0) {
-        if (!psFitsWriteBlank (fits, outhead, extname)) {
-            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
-            psFree(outhead);
-            psFree(table);
-            return false;
-        }
-        psFree (outhead);
-        psFree (table);
-        return true;
-    }
-
+	if (!psFitsWriteBlank (fits, outhead, extname)) {
+	    psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
+	    psFree(outhead);
+	    psFree(table);
+	    return false;
+	}
+	psFree (outhead);
+	psFree (table);
+	return true;
+    }
+    
     psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
     if (!psFitsWriteTable (fits, outhead, table, extname)) {
-        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
-        psFree (outhead);
-        psFree(table);
-        return false;
+	psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
+	psFree (outhead);
+    psFree(table);
+    return false;
     }
     psFree (outhead);
     psFree (table);
-
+    
     return true;
 }
 
 // XXX this layout is still the same as PS1_DEV_1
-bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, psArray *sources, char *extname)
+bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname)
 {
 
Index: /branches/pap/psModules/src/psmodules.h
===================================================================
--- /branches/pap/psModules/src/psmodules.h	(revision 28002)
+++ /branches/pap/psModules/src/psmodules.h	(revision 28003)
@@ -10,4 +10,6 @@
 #include <pmKapaPlots.h>
 #include <pmVisual.h>
+#include <ippStages.h>
+#include <ippDiffMode.h>
 
 // XXX the following headers define constructs needed by the elements below
Index: /branches/pap/psconfig/tagsets/ipp-2.9.dist
===================================================================
--- /branches/pap/psconfig/tagsets/ipp-2.9.dist	(revision 28002)
+++ /branches/pap/psconfig/tagsets/ipp-2.9.dist	(revision 28003)
@@ -72,4 +72,5 @@
 
   YYYYY  ppTranslate            ipp-2-9          -0
+  YYYYY  ppViz                  ipp-2-9          -0
 
   YYYYY  extsrc/gpcsw           ipp-2-9          -0
Index: /branches/pap/psconfig/tagsets/ipp-2.9.perl
===================================================================
--- /branches/pap/psconfig/tagsets/ipp-2.9.perl	(revision 28002)
+++ /branches/pap/psconfig/tagsets/ipp-2.9.perl	(revision 28003)
@@ -79,5 +79,5 @@
   68    Test::URI                      Test-URI-1.08.tar.gz                     0              NONE      NONE
 # 69    Sys::Statistics::Linux::DiskUsage Sys-Statistics-Linux-0.26.tar.gz      0              NONE      NONE
-# 70    Config::YAML                   Config-YAML-1.42.tar.gz                  0              NONE      NONE
+  70    Config::YAML                   Config-YAML-1.42.tar.gz                  0              NONE      NONE
 # 72    File::ExtAttr                  File-ExtAttr-1.07.tar.gz                 0              NONE      NONE
   73    DBI                            DBI-1.601.tar.gz                         0              NONE      NONE
Index: /branches/pap/psphot/doc/stack.txt
===================================================================
--- /branches/pap/psphot/doc/stack.txt	(revision 28002)
+++ /branches/pap/psphot/doc/stack.txt	(revision 28003)
@@ -1,2 +1,12 @@
+
+20100503:
+
+  psphotStack : outline
+
+  * load N images
+  * make chisq detection image
+  * detect sources on all (N+1) images
+  * convolve N input images (to match, to target)
+  * measure source properties on convolved images
 
 20100126:
@@ -4,8 +14,4 @@
   * watch out for psphotSetMomentsWindow & MOMENTS_SX_MAX,etc
   * watch out for psphotSignificanceImage.c:,psphotEfficiency using the FWHM_MAJ from psphotChoosePSF
-    * ppSimDetections.c : SIGMA_SMOOTH
-ppSmooth/src/ppSmoothReadout.c:    psMetadataAddF32(recipe, PS_LIST_TAIL, "EFFECTIVE_AREA", PS_META_REPLACE, "Effective Area", effArea);
-ppSmooth/src/ppSmoothReadout.c:    psMetadataAddF32(recipe, PS_LIST_TAIL, "SIGNIFICANCE_SCALE_FACTOR", PS_META_REPLACE, "Signicance scale factor", factor);
-
 
 20100120 : more stack processing mods:
Index: /branches/pap/psphot/src/Makefile.am
===================================================================
--- /branches/pap/psphot/src/Makefile.am	(revision 28002)
+++ /branches/pap/psphot/src/Makefile.am	(revision 28003)
@@ -185,7 +185,9 @@
         psphotEllipticalContour.c      \
         psphotEllipticalProfile.c      \
+	psphotRadialBins.c	       \
 	psphotPetrosian.c	       \
         psphotPetrosianRadialBins.c    \
         psphotPetrosianStats.c         \
+        psphotPetrosianVisual.c        \
 	psphotEfficiency.c
 
@@ -197,5 +199,4 @@
 #	psphotAnnuli.c		       \
 #	psphotKron.c		       \
-#       psphotPetrosianVisual.c        \
 #
 
Index: /branches/pap/psphot/src/psphot.h
===================================================================
--- /branches/pap/psphot/src/psphot.h	(revision 28002)
+++ /branches/pap/psphot/src/psphot.h	(revision 28003)
@@ -245,5 +245,5 @@
 float           psphotRadiusFromProfile (pmSource *source, psVector *radius, psVector *flux, float fluxMin, float fluxMax);
 bool            psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax);
-bool            psphotEllipticalProfile (pmSource *source);
+bool            psphotEllipticalProfile (pmSource *source, bool RAW_RADIUS);
 bool            psphotEllipticalContour (pmSource *source);
 
@@ -281,12 +281,14 @@
 
 // XXX visualization functions related to radial profiles (disabled)
-// bool psphotPetrosianVisualProfileByAngle (psVector *radius, psVector *flux);
-// bool psphotPetrosianVisualProfileRadii (psVector *radius, psVector *flux, psVector *radiusBin, psVector *fluxBin, float peakFlux, float RadiusRef);
-// bool psphotPetrosianVisualEllipticalContour (pmPetrosian *petrosian);
-// bool psphotPetrosianVisualStats (psVector *radBin, psVector *fluxBin,
-//                               psVector *refRadius, psVector *meanSB,
-//                               psVector *petRatio, psVector *petRatioErr, psVector *fluxSum,
-//                               float petRadius, float ratioForRadius,
-//                               float petFlux, float radiusForFlux);
+bool psphotPetrosianVisualProfileByAngle (psVector *radius, psVector *flux);
+bool psphotPetrosianVisualProfileRadii (psVector *radius, psVector *flux, psVector *radiusBin, psVector *fluxBin, float peakFlux, float RadiusRef);
+bool psphotPetrosianVisualEllipticalContour (pmSourceRadialFlux *radFlux, pmSourceExtendedPars *extpars);
+bool psphotPetrosianVisualStats (psVector *radBin, psVector *fluxBin,
+                               psVector *refRadius, psVector *meanSB,
+                               psVector *petRatio, psVector *petRatioErr, psVector *fluxSum,
+                               float petRadius, float ratioForRadius,
+                               float petFlux, float radiusForFlux);
+
+bool psphotRadialBins (psMetadata *recipe, pmSource *source, float radiusMax, float skynoise);
 
 // structures & functions to support psf-convolved model fitting
Index: /branches/pap/psphot/src/psphotCleanup.c
===================================================================
--- /branches/pap/psphot/src/psphotCleanup.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotCleanup.c	(revision 28003)
@@ -14,9 +14,6 @@
     psFree (config);
 
-    psThreadPoolFinalize ();
-    psTimerStop ();
     psMemCheckCorruption (stderr, true);
     pmModelClassCleanup ();
-    psTimeFinalize ();
     pmSourceFitSetDone ();
     pmConceptsDone ();
Index: /branches/pap/psphot/src/psphotEllipticalContour.c
===================================================================
--- /branches/pap/psphot/src/psphotEllipticalContour.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotEllipticalContour.c	(revision 28003)
@@ -7,5 +7,10 @@
 bool psphotEllipticalContour (pmSource *source) {
 
-    pmSourceRadialProfile *profile = source->extpars->profile;
+    psAssert (source, "missing source");
+    psAssert (source->extpars, "missing extpars");
+    psAssert (source->extpars->radFlux, "missing radFlux");
+
+    pmSourceRadialFlux *profile = source->extpars->radFlux;
+    pmSourceExtendedPars *extpars = source->extpars;
 
     // use LMM to fit theta vs radius to an ellipse
@@ -85,20 +90,20 @@
     /// XXX rationalize? if epsilon > 1, flip major and minor axes (rotate by 90 degrees)
     if (params->data.F32[PAR_EPSILON] < 1.0) {
-	profile->axes.major = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON];
-	profile->axes.minor = params->data.F32[PAR_RMIN];
-	profile->axes.theta = params->data.F32[PAR_PHI];
+	extpars->axes.major = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON];
+	extpars->axes.minor = params->data.F32[PAR_RMIN];
+	extpars->axes.theta = params->data.F32[PAR_PHI];
     } else {
-	profile->axes.major = params->data.F32[PAR_RMIN];
-	profile->axes.minor = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON];
-	profile->axes.theta = params->data.F32[PAR_PHI] + 0.5*M_PI;
+	extpars->axes.major = params->data.F32[PAR_RMIN];
+	extpars->axes.minor = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON];
+	extpars->axes.theta = params->data.F32[PAR_PHI] + 0.5*M_PI;
     }
 
     psTrace ("psphot", 4, "# fitted values:\n");
-    psTrace ("psphot", 4, "Phi:   %f\n", profile->axes.theta*PS_DEG_RAD);
-    psTrace ("psphot", 4, "Rmaj:  %f\n", profile->axes.major);
-    psTrace ("psphot", 4, "Rmin:  %f\n", profile->axes.minor);
+    psTrace ("psphot", 4, "Phi:   %f\n", extpars->axes.theta*PS_DEG_RAD);
+    psTrace ("psphot", 4, "Rmaj:  %f\n", extpars->axes.major);
+    psTrace ("psphot", 4, "Rmin:  %f\n", extpars->axes.minor);
     
     // show the results
-    // psphotPetrosianVisualEllipticalContour (petrosian);
+    // psphotPetrosianVisualEllipticalContour (profile, extpars);
 
     psFree (x);
Index: /branches/pap/psphot/src/psphotEllipticalProfile.c
===================================================================
--- /branches/pap/psphot/src/psphotEllipticalProfile.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotEllipticalProfile.c	(revision 28003)
@@ -1,7 +1,16 @@
 # include "psphotInternal.h"
 
-bool psphotEllipticalProfile (pmSource *source) {
+bool psphotEllipticalProfile (pmSource *source, bool RAW_RADIUS) {
 
-    pmSourceRadialProfile *profile = source->extpars->profile;
+    psAssert (source, "missing source");
+    psAssert (source->extpars, "missing extpars");
+    psAssert (source->pixels, "missing pixels");
+
+    pmSourceExtendedPars *extpars = source->extpars;
+
+    if (!source->extpars->ellipticalFlux) {
+	source->extpars->ellipticalFlux = pmSourceEllipticalFluxAlloc();
+    }
+    pmSourceEllipticalFlux *profile = source->extpars->ellipticalFlux;
 
     profile->radiusElliptical = psVectorAllocEmpty(100, PS_TYPE_F32);
@@ -21,11 +30,17 @@
 
     psEllipseAxes axes;
-    axes.major = M_SQRT1_2;
-    axes.minor = M_SQRT1_2 * (profile->axes.minor / profile->axes.major);
+    if (RAW_RADIUS) {
+	// force circular profile
+	axes.major = M_SQRT1_2;
+	axes.minor = M_SQRT1_2;
+    } else {
+	axes.major = M_SQRT1_2;
+	axes.minor = M_SQRT1_2 * (extpars->axes.minor / extpars->axes.major);
+    }
 
     // axes.major = 1.0;
-    // axes.minor = profile->axes.minor / profile->axes.major;
+    // axes.minor = extpars->axes.minor / extpars->axes.major;
 
-    axes.theta = profile->axes.theta;
+    axes.theta = extpars->axes.theta;
     psEllipseShape shape = psEllipseAxesToShape (axes);
 
@@ -46,9 +61,9 @@
 
 	    float r2 = 0.5*PS_SQR(x/Sxx) + 0.5*PS_SQR(y/Syy) + x*y*Sxy;
+	    float Rraw = hypot(x, y);
 
 	    psVectorAppend(radius, sqrt(r2));
 	    psVectorAppend(flux, source->pixels->data.F32[iy][ix]);
 
-	    float Rraw = hypot(x, y);
 	    psVectorAppend(radiusRaw, Rraw);
 	    psVectorAppend(fluxRaw, source->pixels->data.F32[iy][ix]);
@@ -67,5 +82,5 @@
     // }
 
-    // psphotPetrosianVisualProfileRadii (radius, flux, radiusRaw, fluxRaw, 0.0);
+    psphotPetrosianVisualProfileRadii (radius, flux, radiusRaw, fluxRaw, source->peak->flux, 0.0);
     // psphotPetrosianVisualProfileByAngle (radius, flux);
 
Index: /branches/pap/psphot/src/psphotExtendedSourceAnalysis.c
===================================================================
--- /branches/pap/psphot/src/psphotExtendedSourceAnalysis.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotExtendedSourceAnalysis.c	(revision 28003)
@@ -39,4 +39,6 @@
     int Nkron = 0;
 
+    psTimerStart ("psphot.extended");
+
     // find the currently selected readout
     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
@@ -66,11 +68,4 @@
     float skynoise = psMetadataLookupF32 (&status, recipe, "SKY.NOISE");
 
-# if (0)
-    // if backModel or backStdev are missing, the values of sky and/or skyErr will be set to NAN
-    // XXX use this to set skynoise
-    pmReadout *backModel = psphotSelectBackground (config, view);
-    pmReadout *backStdev = psphotSelectBackgroundStdev (config, view);
-# endif
-
     // S/N limit to perform full non-linear fits
     float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");
@@ -81,4 +76,11 @@
     bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
     bool doKron         = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON");
+
+# if (0)
+    // if backModel or backStdev are missing, the values of sky and/or skyErr will be set to NAN
+    // XXX use this to set skynoise
+    pmReadout *backModel = psphotSelectBackground (config, view);
+    pmReadout *backStdev = psphotSelectBackgroundStdev (config, view);
+# endif
 
     // source analysis is done in S/N order (brightest first)
@@ -119,4 +121,11 @@
 	Next ++;
 
+	// force source image to be a bit larger...
+	float radius = source->peak->xf - source->pixels->col0;
+	radius = PS_MAX (radius, source->peak->yf - source->pixels->row0);
+	radius = PS_MAX (radius, source->pixels->numRows - source->peak->yf + source->pixels->row0);
+	radius = PS_MAX (radius, source->pixels->numCols - source->peak->xf + source->pixels->col0);
+	pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, 1.5*radius);
+
 	// if we request any of these measurements, we require the radial profile
 	if (doPetrosian || doIsophotal || doAnnuli || doKron) {
@@ -134,5 +143,5 @@
 	if (doPetrosian) {
 	    if (!psphotPetrosian (source, recipe, skynoise, maskVal)) {
-		psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
+		psTrace ("psphot", 5, "FAILED petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
 	    } else {
 		psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);
@@ -169,9 +178,10 @@
 
 	if (source->extpars) {
-	    pmSourceRadialProfileFreeVectors(source->extpars->profile);
+	    psFree(source->extpars->radFlux);
+	    psFree(source->extpars->ellipticalFlux);
 	}
     }
 
-    psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot"), Next);
+    psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);
     psLogMsg ("psphot", PS_LOG_INFO, "  %d petrosian\n", Npetro);
     psLogMsg ("psphot", PS_LOG_INFO, "  %d isophotal\n", Nisophot);
Index: /branches/pap/psphot/src/psphotMosaicChip.c
===================================================================
--- /branches/pap/psphot/src/psphotMosaicChip.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotMosaicChip.c	(revision 28003)
@@ -21,6 +21,5 @@
     pmChip *inChip = pmFPAviewThisChip(view, in->fpa);
     if (!outChip->hdu && !outChip->parent->hdu) {
-        const char *name = psMetadataLookupStr(&status, in->fpa->concepts, "FPA.OBS"); // Name of FPA
-        pmFPAAddSourceFromView(out->fpa, name, view, out->format);
+        pmFPAAddSourceFromView(out->fpa, view, out->format);
     }
 
Index: /branches/pap/psphot/src/psphotPetrosian.c
===================================================================
--- /branches/pap/psphot/src/psphotPetrosian.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotPetrosian.c	(revision 28003)
@@ -7,5 +7,5 @@
 
     psAssert (source->extpars, "need to run psphotRadialProfile first");
-    psAssert (source->extpars->profile, "need to run psphotRadialProfile first");
+    psAssert (source->extpars->ellipticalFlux, "need to run psphotRadialProfile first");
 
     // integrate the radial profile for radial bins defined for the petrosian measurement:
@@ -24,8 +24,8 @@
     psTrace ("psphot", 3, "source at %f,%f: petrosian radius: %f, flux: %f, axis ratio: %f, angle: %f",
 	     source->peak->xf, source->peak->yf, 
-	     source->extpars->petrosian_80->radius, 
-	     source->extpars->petrosian_80->flux, 
-	     source->extpars->profile->axes.minor/source->extpars->profile->axes.major, 
-	     source->extpars->profile->axes.theta*PS_DEG_RAD);
+	     source->extpars->petrosianRadius, 
+	     source->extpars->petrosianFlux, 
+	     source->extpars->axes.minor/source->extpars->axes.major, 
+	     source->extpars->axes.theta*PS_DEG_RAD);
 
     return true;
Index: /branches/pap/psphot/src/psphotPetrosianRadialBins.c
===================================================================
--- /branches/pap/psphot/src/psphotPetrosianRadialBins.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotPetrosianRadialBins.c	(revision 28003)
@@ -1,3 +1,4 @@
 # include "psphotInternal.h"
+float InterpolateValues (float X0, float Y0, float X1, float Y1, float X);
 
 // convert the flux vs elliptical radius to annular bins
@@ -5,5 +6,5 @@
 // we are guaranteed to be limited by either the seeing (1 - few pixels) or by the pixels
 // themselves.  this function does not attempt to measure the radial profiles accurately
-// for radii that are smaller than a minimum (currently 1.0 pixels).  
+// for radii that are smaller than ~2 pixels
 
 // for small radii, we are measuring the mean surface brightness in non-overlapping radial
@@ -13,16 +14,27 @@
 // track the non-overlapping radius values.
 
+// Photo interpolates the image of interest to place the peak on the center of the central
+// pixel, and then uses the exact fractions of the pixels in each of the first few annuli.
+// Seems like a reasonable thing, but is there any significance to the difference?
+
 // XXX move the resulting elements from profile to extpars->petrosian?
 bool psphotPetrosianRadialBins (pmSource *source, float radiusMax, float skynoise) {
 
-    pmSourceRadialProfile *profile = source->extpars->profile;
-
-    float skyModelErrorSQ = PS_SQR(skynoise);
-
-    psVector *radius = profile->radiusElliptical;
-    psVector *flux = profile->fluxElliptical;
+    psAssert (source, "missing source");
+    psAssert (source->extpars, "missing extpars");
+    psAssert (source->extpars->ellipticalFlux, "missing ellipticalFlux");
+
+    psVector *radius = source->extpars->ellipticalFlux->radiusElliptical;
+    psVector *flux = source->extpars->ellipticalFlux->fluxElliptical;
 
     // sort incoming vectors by radius
     pmSourceRadialProfileSortPair (radius, flux);
+
+    if (!source->extpars->petProfile) {
+	source->extpars->petProfile = pmSourceRadialProfileAlloc();
+    }
+    pmSourceRadialProfile *profile = source->extpars->petProfile;
+
+    float skyModelErrorSQ = PS_SQR(skynoise);
 
     int nMax = radiusMax;
@@ -107,8 +119,4 @@
     psVector *values = psVectorAllocEmpty (flux->n, PS_TYPE_F32);
     psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
-    // psStats *stats = psStatsAlloc(PS_STAT_FITTED_MEAN_V4 | PS_STAT_FITTED_STDEV_V4);
-
-    // integrate flux, radius for each of these bins.  since flux is sorted by radius, 
-    // we can do this fairly quickly
 
     bool done = false;
@@ -133,9 +141,7 @@
 		dvalue = NAN;
 	    }
-	    // binSB->data.F32[nOut] = stats->sampleMedian;
+
 	    binSB->data.F32[nOut] = value;
 	    binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ);
-	    // binSB->data.F32[nOut] = stats->fittedMean;
-	    // binSBstdev->data.F32[nOut] = sqrt(PS_SQR(stats->fittedStdev) / values->n + skyModelErrorSQ);
 
 	    // error in the SB is the stdev per bin / sqrt (number of pixels) 
@@ -143,6 +149,5 @@
 	    // residual flux, but the sky from the sky model)
 
-	    psTrace ("psphot", 5, "%3d  %5.1f %5.1f : %5.1f  %5.2f\n", 
-		     nOut, radAlp->data.F32[nOut], radBet->data.F32[nOut], binSB->data.F32[nOut], binSBstdev->data.F32[nOut]);
+	    psTrace ("psphot", 5, "%3d  %5.1f %5.1f : %5.1f  %5.2f\n", nOut, radAlp->data.F32[nOut], radBet->data.F32[nOut], binSB->data.F32[nOut], binSBstdev->data.F32[nOut]);
 
 	    nOut ++;
@@ -163,4 +168,39 @@
     // XXX I think this misses the last radial bin -- do we care?
 
+    // interpolate any bins that were empty (extrapolate to center if needed)
+    if (!isfinite(binSB->data.F32[0]) && !isfinite(binSB->data.F32[1])) {
+	psWarning ("center 2 bins of source at %f, %f are NAN, skipping this source", source->peak->xf, source->peak->yf);
+	// XXX raise a flag
+	psFree(binSB);
+	psFree(binSBstdev);
+	psFree(binRad);
+	psFree(binArea);
+	psFree(radMin);
+	psFree(radMax);
+	psFree(radAlp);
+	psFree(radBet);
+	psFree(values);
+	psFree(stats);
+	return false;
+    }
+
+    // if center bin is empty assume same SB as next radius (probably true due to PSF)
+    if (!isfinite(binSB->data.F32[0])) {
+	binSB->data.F32[0] = binSB->data.F32[1];
+	binSBstdev->data.F32[0] = binSBstdev->data.F32[1];
+    }
+
+    // interpolate any bins that were empty (if center if needed)
+    for (int i = 1; i < binSB->n - 1; i++) {
+	if (isfinite(binSB->data.F32[i])) continue;
+	binSB->data.F32[i] = InterpolateValues (binRad->data.F32[i-1], binSB->data.F32[i-1], binRad->data.F32[i+1], binSB->data.F32[i+1], binRad->data.F32[i]);
+	binSBstdev->data.F32[i] = InterpolateValues (binRad->data.F32[i-1], binSBstdev->data.F32[i-1], binRad->data.F32[i+1], binSBstdev->data.F32[i+1], binRad->data.F32[i]);
+    }
+
+    psFree(profile->binSB);
+    psFree(profile->binSBstdev);
+    psFree(profile->radialBins);
+    psFree(profile->area);
+
     // save the vectors
     profile->radialBins = binRad;
Index: /branches/pap/psphot/src/psphotPetrosianStats.c
===================================================================
--- /branches/pap/psphot/src/psphotPetrosianStats.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotPetrosianStats.c	(revision 28003)
@@ -10,8 +10,9 @@
 bool psphotPetrosianStats (pmSource *source) {
 
-    pmSourceRadialProfile *profile = source->extpars->profile;
-
-    float petRadius = NAN;
-    float petFlux = NAN;
+    psAssert (source, "missing source");
+    psAssert (source->extpars, "missing extpars");
+    psAssert (source->extpars->petProfile, "missing petProfile");
+
+    pmSourceRadialProfile *profile = source->extpars->petProfile;
 
     psVector *binSB      = profile->binSB;
@@ -28,4 +29,7 @@
     psVector *areaSum     = psVectorAllocEmpty(binSB->n, PS_TYPE_F32);
 
+    float petRadius = NAN;
+    float petFlux = NAN;
+
     bool anyPetro = false;
     bool manyPetro = false;
@@ -38,4 +42,6 @@
     int lowestSignificantRadius = 0;
     float lowestSignificantRatio = 1.0;
+
+    // find the Petrosian Radius and Petrosian Flux
 
     int nOut = 0;
@@ -142,14 +148,48 @@
     }
 
-    if (!source->extpars->petrosian_80) {
-        source->extpars->petrosian_80 = pmSourceExtendedFluxAlloc ();
-    }
-    pmSourceExtendedFlux *petrosian = source->extpars->petrosian_80;
+    // now measure the radii R90 and R50 where flux = 0.9 (or 0.5) * petFlux;
+    float flux90 = 0.9 * petFlux;
+    float flux50 = 0.5 * petFlux;
+    float R50 = NAN;
+    float R90 = NAN;
+    bool found50 = false;
+    bool found90 = false;
+    // XXX use bisection to do this faster:
+    for (int i = 0; !(found50 && found90) && i < refRadius->n; i++) {
+	if (!found50 && (fluxSum->data.F32[i] > flux50)) {
+	    if (i == 0) {
+		psWarning ("does this case make any sense? (fluxSum[0] > flux50)");
+		continue;
+	    } else {
+		R50 = InterpolateValues (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux50);
+		found50 = true;
+	    }
+	}
+	if (!found90 && (fluxSum->data.F32[i] > flux90)) {
+	    if (i == 0) {
+		psWarning ("does this case make any sense? (fluxSum[0] > flux90)");
+		continue;
+	    } else {
+		R90 = InterpolateValues (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux90);
+		found90 = true;
+	    }
+	}
+    }
+
 
     // XXX save flags (anyPetro, manyPetro)
-    petrosian->radius = petRadius;
-    petrosian->flux   = petFlux;
-
-    // psphotPetrosianVisualStats (binRad, binSB, refRadius, meanSB, petRatio, petRatioErr, fluxSum, petRadius, PETROSIAN_RATIO, petFlux, apRadius);
+    source->extpars->petrosianRadius = petRadius;
+    source->extpars->petrosianFlux   = petFlux;
+    source->extpars->petrosianR50    = R50;
+    source->extpars->petrosianR90    = R90;
+    
+    // XXX add the errors
+    source->extpars->petrosianRadiusErr = NAN;
+    source->extpars->petrosianFluxErr   = NAN;
+    source->extpars->petrosianR50Err    = NAN;
+    source->extpars->petrosianR90Err    = NAN;
+
+    fprintf (stderr, "source @ %f,%f\n", source->peak->xf, source->peak->yf);
+    psphotPetrosianVisualStats (binRad, binSB, refRadius, meanSB, petRatio, petRatioErr, fluxSum, petRadius, PETROSIAN_RATIO, petFlux, apRadius);
 
     psFree(fluxSum);
Index: /branches/pap/psphot/src/psphotPetrosianVisual.c
===================================================================
--- /branches/pap/psphot/src/psphotPetrosianVisual.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotPetrosianVisual.c	(revision 28003)
@@ -1,3 +1,4 @@
 # include "psphotInternal.h"
+# define FORCE_VISUAL 0
 
 // this function displays representative images as the psphot analysis progresses:
@@ -54,5 +55,5 @@
 
     // return true;
-    if (!pmVisualIsVisual()) return true;
+    if (!FORCE_VISUAL && !pmVisualIsVisual()) return true;
 
     if (kapa2 == -1) {
@@ -101,5 +102,5 @@
 
     // return true;
-    if (!pmVisualIsVisual()) return true;
+    if (!FORCE_VISUAL && !pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -172,5 +173,143 @@
     KapaSection section;
 
-    if (!pmVisualIsVisual()) return true;
+    if (!FORCE_VISUAL && !pmVisualIsVisual()) return true;
+
+    if (kapa2 == -1) {
+        kapa2 = KapaOpenNamedSocket ("kapa", "psphot:stats");
+        if (kapa2 == -1) {
+            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
+            pmVisualSetVisual(false);
+            return false;
+        }
+    }
+
+    KapaClearPlots (kapa2);
+    KapaInitGraph (&graphdata);
+    KapaSetFont (kapa2, "courier", 14);
+
+    // radius vs flux
+    // radius vs mean SB
+    // radius vs petRatio
+
+    // *** section 1: radius vs mean SB
+    section.dx = 1.00;
+    section.dy = 0.33;
+    section.x  = 0.00;
+    section.y  = 0.00;
+    section.name = psStringCopy ("meanSB");
+    KapaSetSection (kapa2, &section);
+    psFree (section.name);
+
+    graphdata.color = KapaColorByName ("black");
+    pmVisualLimitsFromVectors (&graphdata, radBin, fluxBin);
+    KapaSetLimits (kapa2, &graphdata);
+
+    KapaBox (kapa2, &graphdata);
+    KapaSendLabel (kapa2, "radius", KAPA_LABEL_XM);
+    KapaSendLabel (kapa2, "mean SB", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.style = 2;
+    graphdata.ptype = 0;
+    graphdata.size = 1.0;
+    KapaPrepPlot (kapa2, radBin->n, &graphdata);
+    KapaPlotVector (kapa2, radBin->n, radBin->data.F32, "x");
+    KapaPlotVector (kapa2, radBin->n, fluxBin->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.style = 2;
+    graphdata.ptype = 1;
+    graphdata.size = 2.0;
+    KapaPrepPlot (kapa2, refRadius->n, &graphdata);
+    KapaPlotVector (kapa2, refRadius->n, refRadius->data.F32, "x");
+    KapaPlotVector (kapa2, refRadius->n, meanSB->data.F32, "y");
+
+    // *** section 2: radius vs petrosian ratio
+    section.dx = 1.00;
+    section.dy = 0.33;
+    section.x  = 0.00;
+    section.y  = 0.33;
+    section.name = psStringCopy ("ratio");
+    KapaSetSection (kapa2, &section);
+    psFree (section.name);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.ymax = +1.05;
+    graphdata.ymin = -0.05;
+    pmVisualLimitsFromVectors (&graphdata, radBin, NULL);
+    KapaSetLimits (kapa2, &graphdata);
+
+    KapaBox (kapa2, &graphdata);
+    KapaSendLabel (kapa2, "radius", KAPA_LABEL_XM);
+    KapaSendLabel (kapa2, "ratio", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.style = 2;
+    graphdata.ptype = 0;
+    graphdata.size = 1.0;
+    graphdata.etype = 0x01;
+    KapaPrepPlot (kapa2, refRadius->n, &graphdata);
+    KapaPlotVector (kapa2, refRadius->n, refRadius->data.F32, "x");
+    KapaPlotVector (kapa2, refRadius->n, petRatio->data.F32, "y");
+    KapaPlotVector (kapa2, refRadius->n, petRatioErr->data.F32, "dym");
+    KapaPlotVector (kapa2, refRadius->n, petRatioErr->data.F32, "dyp");
+    graphdata.etype = 0;
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.style = 2;
+    graphdata.ptype = 2;
+    graphdata.size = 2.0;
+    KapaPrepPlot   (kapa2, 1, &graphdata);
+    KapaPlotVector (kapa2, 1, &petRadius, "x");
+    KapaPlotVector (kapa2, 1, &ratioForRadius, "y");
+
+    // *** section 3: radius vs integrated flux
+    section.dx = 1.00;
+    section.dy = 0.33;
+    section.x  = 0.00;
+    section.y  = 0.66;
+    section.name = psStringCopy ("flux");
+    KapaSetSection (kapa2, &section);
+    psFree (section.name);
+
+    graphdata.color = KapaColorByName ("black");
+    pmVisualLimitsFromVectors (&graphdata, radBin, fluxSum);
+    KapaSetLimits (kapa2, &graphdata);
+
+    KapaBox (kapa2, &graphdata);
+    KapaSendLabel (kapa2, "radius", KAPA_LABEL_XM);
+    KapaSendLabel (kapa2, "integrated flux", KAPA_LABEL_YM);
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.style = 2;
+    graphdata.ptype = 0;
+    graphdata.size = 1.0;
+    KapaPrepPlot   (kapa2, refRadius->n, &graphdata);
+    KapaPlotVector (kapa2, refRadius->n, refRadius->data.F32, "x");
+    KapaPlotVector (kapa2, refRadius->n, fluxSum->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("red");
+    graphdata.ptype = 2;
+    graphdata.style = 2;
+    graphdata.size = 2.0;
+    KapaPrepPlot   (kapa2, 1, &graphdata);
+    KapaPlotVector (kapa2, 1, &radiusForFlux, "x");
+    KapaPlotVector (kapa2, 1, &petFlux, "y");
+
+    // pause and wait for user input:
+    // continue, save (provide name), ??
+    char key[10];
+    fprintf (stdout, "[c]ontinue? ");
+    if (!fgets(key, 8, stdin)) {
+        psWarning("Unable to read option");
+    }
+    return true;
+}
+
+bool psphotPetrosianVisualEllipticalContour (pmSourceRadialFlux *radFlux, pmSourceExtendedPars *extpars) {
+
+    Graphdata graphdata;
+
+    if (!FORCE_VISUAL && !pmVisualIsVisual()) return true;
 
     if (kapa == -1) {
@@ -187,112 +326,71 @@
     KapaSetFont (kapa, "courier", 14);
 
-    // radius vs flux
-    // radius vs mean SB
-    // radius vs petRatio
-
-    // *** section 1: radius vs mean SB
-    section.dx = 1.00;
-    section.dy = 0.33;
-    section.x  = 0.00;
-    section.y  = 0.00;
-    section.name = psStringCopy ("meanSB");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    graphdata.color = KapaColorByName ("black");
-    pmVisualLimitsFromVectors (&graphdata, radBin, fluxBin);
+    psVector *theta = radFlux->theta;
+    psVector *radius = radFlux->isophotalRadii;
+
+    // find Rmin and Rmax for the initial guess
+    float Rmin = radius->data.F32[0];
+    float Rmax = radius->data.F32[0];
+
+    psVector *Rx = psVectorAlloc(radius->n, PS_TYPE_F32);
+    psVector *Ry = psVectorAlloc(radius->n, PS_TYPE_F32);
+
+    for (int i = 0; i < theta->n; i++) {
+	Rx->data.F32[i] = radius->data.F32[i]*cos(theta->data.F32[i]);
+	Ry->data.F32[i] = radius->data.F32[i]*sin(theta->data.F32[i]);
+
+	// check the radius range
+	Rmin = MIN (Rmin, radius->data.F32[i]);
+	Rmax = MAX (Rmax, radius->data.F32[i]);
+    }	
+
+    psVector *rx = psVectorAlloc(361, PS_TYPE_F32);
+    psVector *ry = psVectorAlloc(361, PS_TYPE_F32);
+
+    float epsilon = extpars->axes.minor / extpars->axes.major;
+
+    for (int i = 0; i < 361; i++) {
+
+	float alpha = PS_RAD_DEG * i;
+
+	float cs_alpha = cos(alpha);
+	float sn_alpha = sin(alpha);
+
+	float cs_phi = cos(alpha - extpars->axes.theta);
+	float sn_phi = sin(alpha - extpars->axes.theta);
+
+	float r = 1.0 / sqrt(SQ(sn_phi) + SQ(epsilon*cs_phi));
+
+	// generate the model fit here
+	rx->data.F32[i] = extpars->axes.minor * cs_alpha * r;
+	ry->data.F32[i] = extpars->axes.minor * sn_alpha * r;
+    }	
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.xmin = -1.1*Rmax;
+    graphdata.ymin = -1.1*Rmax;
+    graphdata.xmax = +1.1*Rmax;
+    graphdata.ymax = +1.1*Rmax;
     KapaSetLimits (kapa, &graphdata);
 
     KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "radius", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "mean SB", KAPA_LABEL_YM);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.style = 2;
-    graphdata.ptype = 0;
-    graphdata.size = 1.0;
-    KapaPrepPlot (kapa, radBin->n, &graphdata);
-    KapaPlotVector (kapa, radBin->n, radBin->data.F32, "x");
-    KapaPlotVector (kapa, radBin->n, fluxBin->data.F32, "y");
+    KapaSendLabel (kapa, "R_x", KAPA_LABEL_XM);
+    KapaSendLabel (kapa, "R_y", KAPA_LABEL_YM);
 
     graphdata.color = KapaColorByName ("red");
     graphdata.style = 2;
-    graphdata.ptype = 1;
-    graphdata.size = 2.0;
-    KapaPrepPlot (kapa, refRadius->n, &graphdata);
-    KapaPlotVector (kapa, refRadius->n, refRadius->data.F32, "x");
-    KapaPlotVector (kapa, refRadius->n, meanSB->data.F32, "y");
-
-    // *** section 2: radius vs petrosian ratio
-    section.dx = 1.00;
-    section.dy = 0.33;
-    section.x  = 0.00;
-    section.y  = 0.33;
-    section.name = psStringCopy ("ratio");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.ymax = +1.05;
-    graphdata.ymin = -0.05;
-    pmVisualLimitsFromVectors (&graphdata, radBin, NULL);
-    KapaSetLimits (kapa, &graphdata);
-
-    KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "radius", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "ratio", KAPA_LABEL_YM);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.style = 2;
-    graphdata.ptype = 0;
-    graphdata.size = 1.0;
-    graphdata.etype = 0x01;
-    KapaPrepPlot (kapa, refRadius->n, &graphdata);
-    KapaPlotVector (kapa, refRadius->n, refRadius->data.F32, "x");
-    KapaPlotVector (kapa, refRadius->n, petRatio->data.F32, "y");
-    KapaPlotVector (kapa, refRadius->n, petRatioErr->data.F32, "dym");
-    KapaPlotVector (kapa, refRadius->n, petRatioErr->data.F32, "dyp");
-    graphdata.etype = 0;
-
-    graphdata.color = KapaColorByName ("red");
-    graphdata.style = 2;
     graphdata.ptype = 2;
-    graphdata.size = 2.0;
-    KapaPrepPlot   (kapa, 1, &graphdata);
-    KapaPlotVector (kapa, 1, &petRadius, "x");
-    KapaPlotVector (kapa, 1, &ratioForRadius, "y");
-
-    // *** section 3: radius vs integrated flux
-    section.dx = 1.00;
-    section.dy = 0.33;
-    section.x  = 0.00;
-    section.y  = 0.66;
-    section.name = psStringCopy ("flux");
-    KapaSetSection (kapa, &section);
-    psFree (section.name);
-
-    graphdata.color = KapaColorByName ("black");
-    pmVisualLimitsFromVectors (&graphdata, radBin, fluxSum);
-    KapaSetLimits (kapa, &graphdata);
-
-    KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "radius", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "integrated flux", KAPA_LABEL_YM);
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.style = 2;
-    graphdata.ptype = 0;
-    graphdata.size = 1.0;
-    KapaPrepPlot   (kapa, refRadius->n, &graphdata);
-    KapaPlotVector (kapa, refRadius->n, refRadius->data.F32, "x");
-    KapaPlotVector (kapa, refRadius->n, fluxSum->data.F32, "y");
-
-    graphdata.color = KapaColorByName ("red");
-    graphdata.ptype = 2;
-    graphdata.style = 2;
-    graphdata.size = 2.0;
-    KapaPrepPlot   (kapa, 1, &graphdata);
-    KapaPlotVector (kapa, 1, &radiusForFlux, "x");
-    KapaPlotVector (kapa, 1, &petFlux, "y");
+    graphdata.size = 1.0;
+    KapaPrepPlot (kapa, Rx->n, &graphdata);
+    KapaPlotVector (kapa, Rx->n, Rx->data.F32, "x");
+    KapaPlotVector (kapa, Rx->n, Ry->data.F32, "y");
+
+    graphdata.color = KapaColorByName ("black");
+    graphdata.style = 0;
+    graphdata.ptype = 0;
+    graphdata.size = 1.0;
+    KapaPrepPlot (kapa, rx->n, &graphdata);
+    KapaPlotVector (kapa, rx->n, rx->data.F32, "x");
+    KapaPlotVector (kapa, rx->n, ry->data.F32, "y");
 
     // pause and wait for user input:
@@ -306,100 +404,3 @@
 }
 
-bool psphotPetrosianVisualEllipticalContour (pmPetrosian *petrosian) {
-
-    Graphdata graphdata;
-
-    if (!pmVisualIsVisual()) return true;
-
-    if (kapa == -1) {
-        kapa = KapaOpenNamedSocket ("kapa", "psphot:plots");
-        if (kapa == -1) {
-            fprintf (stderr, "failure to open kapa; visual mode disabled\n");
-            pmVisualSetVisual(false);
-            return false;
-        }
-    }
-
-    KapaClearPlots (kapa);
-    KapaInitGraph (&graphdata);
-    KapaSetFont (kapa, "courier", 14);
-
-    psVector *theta = petrosian->theta;
-    psVector *radius = petrosian->isophotalRadii;
-
-    // find Rmin and Rmax for the initial guess
-    float Rmin = radius->data.F32[0];
-    float Rmax = radius->data.F32[0];
-
-    psVector *Rx = psVectorAlloc(radius->n, PS_TYPE_F32);
-    psVector *Ry = psVectorAlloc(radius->n, PS_TYPE_F32);
-
-    for (int i = 0; i < theta->n; i++) {
-	Rx->data.F32[i] = radius->data.F32[i]*cos(theta->data.F32[i]);
-	Ry->data.F32[i] = radius->data.F32[i]*sin(theta->data.F32[i]);
-
-	// check the radius range
-	Rmin = MIN (Rmin, radius->data.F32[i]);
-	Rmax = MAX (Rmax, radius->data.F32[i]);
-    }	
-
-    psVector *rx = psVectorAlloc(361, PS_TYPE_F32);
-    psVector *ry = psVectorAlloc(361, PS_TYPE_F32);
-
-    float epsilon = petrosian->axes.minor / petrosian->axes.major;
-
-    for (int i = 0; i < 361; i++) {
-
-	float alpha = PS_RAD_DEG * i;
-
-	float cs_alpha = cos(alpha);
-	float sn_alpha = sin(alpha);
-
-	float cs_phi = cos(alpha - petrosian->axes.theta);
-	float sn_phi = sin(alpha - petrosian->axes.theta);
-
-	float r = 1.0 / sqrt(SQ(sn_phi) + SQ(epsilon*cs_phi));
-
-	// generate the model fit here
-	rx->data.F32[i] = petrosian->axes.minor * cs_alpha * r;
-	ry->data.F32[i] = petrosian->axes.minor * sn_alpha * r;
-    }	
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.xmin = -1.1*Rmax;
-    graphdata.ymin = -1.1*Rmax;
-    graphdata.xmax = +1.1*Rmax;
-    graphdata.ymax = +1.1*Rmax;
-    KapaSetLimits (kapa, &graphdata);
-
-    KapaBox (kapa, &graphdata);
-    KapaSendLabel (kapa, "R_x", KAPA_LABEL_XM);
-    KapaSendLabel (kapa, "R_y", KAPA_LABEL_YM);
-
-    graphdata.color = KapaColorByName ("red");
-    graphdata.style = 2;
-    graphdata.ptype = 2;
-    graphdata.size = 1.0;
-    KapaPrepPlot (kapa, Rx->n, &graphdata);
-    KapaPlotVector (kapa, Rx->n, Rx->data.F32, "x");
-    KapaPlotVector (kapa, Rx->n, Ry->data.F32, "y");
-
-    graphdata.color = KapaColorByName ("black");
-    graphdata.style = 0;
-    graphdata.ptype = 0;
-    graphdata.size = 1.0;
-    KapaPrepPlot (kapa, rx->n, &graphdata);
-    KapaPlotVector (kapa, rx->n, rx->data.F32, "x");
-    KapaPlotVector (kapa, rx->n, ry->data.F32, "y");
-
-    // pause and wait for user input:
-    // continue, save (provide name), ??
-    char key[10];
-    fprintf (stdout, "[c]ontinue? ");
-    if (!fgets(key, 8, stdin)) {
-        psWarning("Unable to read option");
-    }
-    return true;
-}
-
 # endif
Index: /branches/pap/psphot/src/psphotRadialBins.c
===================================================================
--- /branches/pap/psphot/src/psphotRadialBins.c	(revision 28003)
+++ /branches/pap/psphot/src/psphotRadialBins.c	(revision 28003)
@@ -0,0 +1,204 @@
+# include "psphotInternal.h"
+float InterpolateValues (float X0, float Y0, float X1, float Y1, float X);
+
+// convert the flux vs elliptical radius to annular bins
+
+// we are guaranteed to be limited by either the seeing (1 - few pixels) or by the pixels
+// themselves.  this function does not attempt to measure the radial profiles accurately
+// for radii that are smaller than ~2 pixels
+
+// for small radii, we are measuring the mean surface brightness in non-overlapping radial
+// bins.  for large radii (r > 2 pixels), we are measuring the surface brightness for a
+// radius range \alpha r_i < i < \beta r_i, but performing this measurement for radii more
+// finely spaced than r_{i+1} = r_i * \beta / \alpha.  for the integration, we need to
+// track the non-overlapping radius values.
+
+// Photo interpolates the image of interest to place the peak on the center of the central
+// pixel, and then uses the exact fractions of the pixels in each of the first few annuli.
+// Seems like a reasonable thing, but is there any significance to the difference?
+
+// XXX move the resulting elements from profile to extpars->petrosian?
+bool psphotRadialBins (psMetadata *recipe, pmSource *source, float radiusMax, float skynoise) {
+
+    psAssert (source, "missing source");
+    psAssert (source->extpars, "missing extpars");
+    psAssert (source->extpars->ellipticalFlux, "missing ellipticalFlux");
+
+    psVector *radius = source->extpars->ellipticalFlux->radiusElliptical;
+    psVector *flux = source->extpars->ellipticalFlux->fluxElliptical;
+
+    // sort incoming vectors by radius
+    pmSourceRadialProfileSortPair (radius, flux);
+
+    if (!source->extpars->radProfile) {
+	source->extpars->radProfile = pmSourceRadialProfileAlloc();
+    }
+    pmSourceRadialProfile *profile = source->extpars->radProfile;
+
+    float skyModelErrorSQ = PS_SQR(skynoise);
+    psEllipseAxes axes = source->extpars->axes;
+    float AxialRatio = axes.minor / axes.major;
+
+    // radMin, radMax store the bounds of the annuli
+    bool status = false;
+    psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
+    psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
+    if (!radMin || !radMin->n) return false;
+    if (!radMax || !radMax->n) return false;
+
+    psVector *binSB      = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // surface brightness of radial bin
+    psVector *binSBstdev = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // surface brightness error of radial bin
+    psVector *binSum     = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // surface brightness of radial bin
+    psVector *binFill    = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // surface brightness of radial bin
+    psVector *binRad  	 = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // mean radius of radial bin
+    psVector *binArea 	 = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // area of radial bin (contiguous, non-overlapping)
+
+    psVectorInit (binSB, 0.0);
+    psVectorInit (binSBstdev, 0.0);
+    psVectorInit (binSum, 0.0);
+    psVectorInit (binFill, 0.0);
+
+    psVectorInit (binRad, 0.0);
+
+    // generate radial area-weighted mean radius & non-overlapping areas
+    for (int i = 0; i < radMin->n; i++) {
+	float rMin2 = PS_SQR(radMin->data.F32[i]);
+	float rMax2 = PS_SQR(radMax->data.F32[i]);
+
+	float rMin3 = rMin2*radMin->data.F32[i];
+	float rMax3 = rMax2*radMax->data.F32[i];
+
+	float rBin = 2.0 * (rMax3 - rMin3) / (rMax2 - rMin2) / 3.0;
+	
+	// XXX calculate area-weighted radius rather than asserting?
+	binRad->data.F32[i] = rBin;
+	binArea->data.F32[i] = M_PI * (rMax2 - rMin2);
+    }
+
+    // storage vector for stats
+    psVector *values = psVectorAllocEmpty (flux->n, PS_TYPE_F32);
+    psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
+
+    float fluxSum = 0.0;
+    int nPixSum = 0;
+
+    bool done = false;
+    int nOut = 0;
+    float Rmin = radMin->data.F32[nOut];
+    float Rmax = radMax->data.F32[nOut];
+    float Rnxt = radMin->data.F32[nOut+1];  // minimum radius for next range
+    int iNext = 0;
+    int iLast = -1;
+    for (int i = 0; !done && (i < radius->n); i++) {
+	if (radius->data.F32[i] < Rnxt) {
+	    iNext = i; // on the next pass, we will start back here to ensure we hit all pixels in the next bin
+	}
+	if (radius->data.F32[i] > Rmax) {
+	    // calculate the surface brightness for bin 'nOut'
+	    float value, dvalue;
+	    if (values->n > 0) {
+		psVectorStats (stats, values, NULL, NULL, 0);
+		value = stats->robustMedian;
+		dvalue = stats->robustStdev;
+	    } else {
+		value = NAN;
+		dvalue = NAN;
+	    }
+
+	    binSB->data.F32[nOut] = value;
+	    binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ);
+
+	    // calculate the total flux for bin 'nOut'
+	    float Area = M_PI*AxialRatio*PS_SQR(Rmax);
+	    binSum->data.F32[nOut] = fluxSum;
+	    binFill->data.F32[nOut] = nPixSum / Area;
+
+	    psTrace ("psphot", 5, "radial bins: %3d  %5.1f %5.1f : %7.1f  %6.2f : %8.1f %4.2f %6.1f\n", 
+		     nOut, radMin->data.F32[nOut], radMax->data.F32[nOut], 
+		     binSB->data.F32[nOut], binSBstdev->data.F32[nOut], 
+		     binSum->data.F32[nOut], binFill->data.F32[nOut], Area);
+
+	    nOut ++;
+	    if (nOut >= radMin->n) break;
+	    Rmin = radMin->data.F32[nOut];
+	    Rmax = radMax->data.F32[nOut];
+	    Rnxt = (nOut < radMin->n - 1) ? radMin->data.F32[nOut+1] : Rmax;  // minimum radius for next range
+	    values->n = 0;
+	    psStatsInit(stats);
+	    iLast = i;
+	    i = iNext;
+	}
+	if (radius->data.F32[i] < Rmin) {
+	    continue;
+	}
+	psVectorAppend (values, flux->data.F32[i]);
+
+	if (i > iLast) {
+	    fluxSum += flux->data.F32[i];
+	    nPixSum ++;
+	}
+    }
+    binSB->n = binSBstdev->n = binRad->n = binArea->n = nOut;
+
+    // interpolate any bins that were empty (extrapolate to center if needed)
+    if (!isfinite(binSB->data.F32[0]) && !isfinite(binSB->data.F32[1])) {
+	psWarning ("center 2 bins of source at %f, %f are NAN, skipping this source", source->peak->xf, source->peak->yf);
+	// XXX raise a flag
+	psFree(binSB);
+	psFree(binSBstdev);
+
+	psFree(binSum);
+	psFree(binFill);
+
+	psFree(binRad);
+	psFree(binArea);
+	psFree(values);
+	psFree(stats);
+	return false;
+    }
+
+    // if center bin is empty assume same SB as next radius (probably true due to PSF)
+    if (!isfinite(binSB->data.F32[0])) {
+	binSB->data.F32[0] = binSB->data.F32[1];
+	binSBstdev->data.F32[0] = binSBstdev->data.F32[1];
+    }
+
+    // interpolate any bins that were empty (if center if needed)
+    for (int i = 1; i < binSB->n - 1; i++) {
+	if (isfinite(binSB->data.F32[i])) continue;
+	binSB->data.F32[i] = InterpolateValues (binRad->data.F32[i-1], binSB->data.F32[i-1], binRad->data.F32[i+1], binSB->data.F32[i+1], binRad->data.F32[i]);
+	binSBstdev->data.F32[i] = InterpolateValues (binRad->data.F32[i-1], binSBstdev->data.F32[i-1], binRad->data.F32[i+1], binSBstdev->data.F32[i+1], binRad->data.F32[i]);
+    }
+
+    psFree(profile->binSB);
+    psFree(profile->binSBstdev);
+
+    psFree(profile->binSum);
+    psFree(profile->binFill);
+
+    psFree(profile->radialBins);
+    psFree(profile->area);
+
+    // save the vectors
+    profile->binSB      = binSB;
+    profile->binSBstdev = binSBstdev;
+
+    profile->binSum     = binSum;
+    profile->binFill    = binFill;
+
+    profile->radialBins = binRad;
+    profile->area       = binArea;
+
+    psFree(values);
+    psFree(stats);
+
+    return true;
+}
+
+// the area-weighted mean radius is given by:
+
+// integral r * 2 pi r dr / integral 2 pi r dr
+
+// = 2/3 pi (r_max^3 - r_min^3)  / pi (r_max^2 - r_min^2) 
+// = 2/3 (r_max^3 - r_min^3) / (r_max^2 - r_min^2)
+
Index: /branches/pap/psphot/src/psphotRadialProfile.c
===================================================================
--- /branches/pap/psphot/src/psphotRadialProfile.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotRadialProfile.c	(revision 28003)
@@ -3,11 +3,9 @@
 bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal) {
 
+    bool status;
+
     // allocate pmSourceExtendedParameters, if not already defined
     if (!source->extpars) {
         source->extpars = pmSourceExtendedParsAlloc ();
-    }
-
-    if (!source->extpars->profile) {
-        source->extpars->profile = pmSourceRadialProfileAlloc ();
     }
 
@@ -17,4 +15,6 @@
     float fluxMin = 0.0;
     float fluxMax = source->peak->flux;
+
+    bool RAW_RADIUS = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_RAW_RADIUS");
 
     // generate a series of radial profiles at Nsec evenly spaced angles.  the profile flux
@@ -28,5 +28,5 @@
     // use the radial profiles to determine the radius of a given isophote.  this isophote
     // is used to determine the elliptical shape of the object, so it has a relatively high
-    // value (nominally 50% of the peak)
+    // value (nominally 25% of the peak)
     if (!psphotRadiiFromProfiles (source, fluxMin, fluxMax)) {
 	psError (PS_ERR_UNKNOWN, false, "failed to measure isophotal radii from profiles");
@@ -42,6 +42,12 @@
     // generate a single, normalized radial profile following the elliptical contours.
     // the radius is normalized by the axis ratio so that on the major axis, 1 pixel = 1 pixel
-    if (!psphotEllipticalProfile (source)) {
+    if (!psphotEllipticalProfile (source, RAW_RADIUS)) {
 	psError (PS_ERR_UNKNOWN, false, "failed to generate elliptical profile");
+	return false;
+    }
+  
+    // generated profile in averaged bins
+    if (!psphotRadialBins (recipe, source, Rmax, skynoise)) {
+	psError (PS_ERR_UNKNOWN, false, "failed to generate radial bins");
 	return false;
     }
Index: /branches/pap/psphot/src/psphotRadialProfileByAngles.c
===================================================================
--- /branches/pap/psphot/src/psphotRadialProfileByAngles.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotRadialProfileByAngles.c	(revision 28003)
@@ -12,9 +12,14 @@
 bool psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax) {
 
+    psAssert (source->extpars, "define extpars");
+
     // we want to have an even number of sectors so we can do 180 deg symmetrizing
     Nsec = (Nsec % 2) ? Nsec + 1 : Nsec;
     float dtheta = 2.0*M_PI / Nsec;
 
-    pmSourceRadialProfile *profile = source->extpars->profile;
+    if (!source->extpars->radFlux) {
+	source->extpars->radFlux = pmSourceRadialFluxAlloc();
+    }
+    pmSourceRadialFlux *profile = source->extpars->radFlux;
     psFree(profile->radii);
     psFree(profile->fluxes);
@@ -24,5 +29,4 @@
     profile->fluxes = psArrayAllocEmpty(Nsec);
     profile->theta = psVectorAllocEmpty(Nsec, PS_TYPE_F32);
-
 
     for (int i = 0; i < Nsec; i++) {
Index: /branches/pap/psphot/src/psphotRadiiFromProfiles.c
===================================================================
--- /branches/pap/psphot/src/psphotRadiiFromProfiles.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotRadiiFromProfiles.c	(revision 28003)
@@ -5,5 +5,9 @@
 bool psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax) {
 
-    pmSourceRadialProfile *profile = source->extpars->profile;
+    psAssert (source, "missing source");
+    psAssert (source->extpars, "missing extpars");
+    psAssert (source->extpars->radFlux, "missing radFlux");
+
+    pmSourceRadialFlux *profile = source->extpars->radFlux;
 
     psFree(profile->isophotalRadii);
@@ -146,5 +150,5 @@
 
     // show the results
-    // psphotPetrosianVisualProfileRadii (radius, flux, radiusBinned, fluxBinned, Ro);
+    // psphotPetrosianVisualProfileRadii (radius, flux, radiusBinned, fluxBinned, fluxMax, Ro);
 
     psFree(fluxBinned);
@@ -152,2 +156,5 @@
     return Ro;
 }
+
+
+
Index: /branches/pap/psphot/src/psphotStackImageLoop.c
===================================================================
--- /branches/pap/psphot/src/psphotStackImageLoop.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotStackImageLoop.c	(revision 28003)
@@ -41,7 +41,16 @@
                 if (! readout->data_exists) { continue; }
 
+# if (0)		
+		// uncomment to generate matched psfs
+		if (!psphotStackMatchPSFs (config, view)) {
+                    psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
+                    psFree (view);
+                    return false;
+		}
+# endif
+
 		// XXX for now, we assume there is only a single chip in the PHU:
 		if (!psphotStackReadout (config, view)) {
-                    psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
+                    psError(psErrorCodeLast(), false, "failure in psphotStackReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
                     psFree (view);
                     return false;
Index: /branches/pap/psphot/src/psphotStackMatchPSFs.c
===================================================================
--- /branches/pap/psphot/src/psphotStackMatchPSFs.c	(revision 28003)
+++ /branches/pap/psphot/src/psphotStackMatchPSFs.c	(revision 28003)
@@ -0,0 +1,152 @@
+# include "psphotInternal.h"
+
+bool psphotStackMatchPSFs (pmConfig *config, const pmFPAview *view, bool firstPass)
+{
+    bool status = true;
+
+    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
+    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+	if (!psphotStackMatchPSFsReadout (config, view, i)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i);
+	    return false;
+	}
+    }
+    return true;
+}
+
+// convolve the image to match desired PSF
+bool psphotStackMatchPSFsReadout (pmConfig *config, const pmFPAview *view, int index) {
+
+    bool status;
+    int pass;
+    float NSIGMA_PEAK = 25.0;
+    int NMAX = 0;
+
+    // find the currently selected readout
+    pmFPAfile *fileRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", index); // File of interest
+    psAssert (fileRaw, "missing file?");
+
+    pmFPAfile *fileCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT.CONV", index); // File of interest
+    psAssert (fileCnv, "missing file?");
+
+    pmReadout *readoutRaw = pmFPAviewThisReadout(view, fileRaw->fpa);
+    psAssert (readoutRaw, "missing readout?");
+
+    pmReadout *readoutCnv = pmFPAviewThisReadout(view, fileCnv->fpa);
+    psAssert (readoutCnv, "missing readout?");
+
+    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
+    psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels
+    psAssert (maskVal, "missing mask value?");
+
+    /***** set up recipe options *****/
+
+    psMetadata *stackRecipe = psMetadataLookupMetadata(NULL, config->recipes, PPSTACK_RECIPE); // ppStack recipe
+    psAssert(stackRecipe, "We've thrown an error on this before.");
+
+    // Look up appropriate values from the ppSub recipe
+    psMetadata *subRecipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe
+    psAssert(subRecipe, "recipe missing");
+
+    int size = psMetadataLookupS32(NULL, subRecipe, "KERNEL.SIZE"); // Kernel half-size
+
+    float deconvLimit = psMetadataLookupF32(NULL, stackRecipe, "DECONV.LIMIT"); // Limit on deconvolution fraction
+
+    psString maskValStr = psMetadataLookupStr(NULL, subRecipe, "MASK.VAL"); // Name of bits to mask going in
+    psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch
+    psString maskPoorStr = psMetadataLookupStr(NULL, stackRecipe, "MASK.POOR"); // Name of bits to mask for poor
+    psImageMaskType maskPoor = pmConfigMaskGet(maskPoorStr, config); // Bits to mask for poor pixels
+    psString maskBadStr = psMetadataLookupStr(NULL, stackRecipe, "MASK.BAD"); // Name of bits to mask for bad
+    psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
+
+    bool mdok;                          // Status of MD lookup
+    float penalty = psMetadataLookupF32(NULL, subRecipe, "PENALTY"); // Penalty for wideness
+    int threads = psMetadataLookupS32(NULL, config->arguments, "-threads"); // Number of threads
+
+    if (!pmReadoutMaskNonfinite(readout, maskVal)) {
+        psError(psErrorCodeLast(), false, "Unable to mask non-finite pixels in readout.");
+        return false;
+    }
+
+    // Image Matching (PSFs or just flux)
+    if (options->convolve) {
+      // Full match of PSFs
+        pmReadout *conv = pmReadoutAlloc(NULL); // Conv readout, for holding results temporarily
+
+        // Read previously produced kernel
+        if (psMetadataLookupBool(NULL, config->arguments, "PPSTACK.DEBUG.STACK")) {
+	  loadKernel();
+        } else {
+	  matchKernel();
+        } // !DEBUG.STACK
+
+	saveMatchData();
+
+	saveChiSquare();
+
+	renormKernel();
+
+        // Reject image completely if the maximum deconvolution fraction exceeds the limit
+        float deconv = psMetadataLookupF32(NULL, conv->analysis, PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Max deconvolution fraction
+        if (deconv > deconvLimit) {
+            psWarning("Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting image %d\n", deconv, deconvLimit, index);
+            psFree(conv);
+            return NULL;
+        }
+
+        readout->analysis = psMetadataCopy(readout->analysis, conv->analysis);
+
+        psFree(conv);
+    } else {
+        // only match the flux
+        float norm = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation
+        psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(norm, PS_TYPE_F32));
+        psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(norm), PS_TYPE_F32));
+    }
+
+    // Ensure the background value is zero
+    psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background
+    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
+    if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
+        psWarning("Can't measure background for image.");
+        psErrorClear();
+    } else {
+        if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {
+            psLogMsg("ppStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)",
+                     psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), psStatsGetValue(bg, PS_STAT_ROBUST_STDEV));
+            (void)psBinaryOp(readout->image, readout->image, "-",
+                             psScalarAlloc(psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN), PS_TYPE_F32));
+        }
+    }
+
+    if (!stackRenormaliseReadout(config, readout)) {
+        psFree(rng);
+        psFree(bg);
+        return false;
+    }
+
+    // Measure the variance level for the weighting
+    if (psMetadataLookupBool(NULL, stackRecipe, "WEIGHTS")) {
+        if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) {
+            psError(PPSTACK_ERR_DATA, false, "Can't measure mean variance for image.");
+            psFree(rng);
+            psFree(bg);
+            return false;
+        }
+        options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * psImageCovarianceFactor(readout->covariance));
+    } else {
+        options->weightings->data.F32[index] = 1.0;
+    }
+    psLogMsg("ppStack", PS_LOG_INFO, "Weighting for image %d is %f\n",
+             index, options->weightings->data.F32[index]);
+
+    psFree(rng);
+    psFree(bg);
+
+    dumpImage3();
+
+    return true;
+}
Index: /branches/pap/psphot/src/psphotStackMatchPSFsUtils.c
===================================================================
--- /branches/pap/psphot/src/psphotStackMatchPSFsUtils.c	(revision 28003)
+++ /branches/pap/psphot/src/psphotStackMatchPSFsUtils.c	(revision 28003)
@@ -0,0 +1,556 @@
+/***** defines *****/
+
+#define ARRAY_BUFFER 16                 // Number to add to array at a time
+#define MAG_IGNORE 50                   // Ignore magnitudes fainter than this --- they're not real!
+#define FAKE_SIZE 1                     // Size of fake convolution kernel
+#define SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_SATURATED | PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply to input sources
+#define NOISE_FRACTION 0.01             // Set minimum flux to this fraction of noise
+#define COVAR_FRAC 0.01                 // Truncation fraction for covariance matrix
+
+// XXX better name
+bool readImage(psImage **target, // Target for image
+	       const char *name, // Name of FITS file
+	       const pmConfig *config // Configuration
+    )
+{
+    psString resolved = pmConfigConvertFilename(name, config, false, false); // Resolved filename
+    psFits *fits = psFitsOpen(resolved, "r");
+    psFree(resolved);
+    if (!fits) {
+        psError(PPSTACK_ERR_IO, false, "Unable to open previously produced image: %s", name);
+        return false;
+    }
+    psImage *image = psFitsReadImage(fits, psRegionSet(0,0,0,0), 0); // Image of interest
+    if (!image) {
+        psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image: %s", name);
+        psFitsClose(fits);
+        return false;
+    }
+    psFitsClose(fits);
+
+    psFree(*target);
+    *target = image;
+
+    return true;
+}
+
+// Get coordinates from a source
+void coordsFromSource(float *x, float *y, const pmSource *source)
+{
+    assert(x && y);
+    assert(source);
+
+    if (source->modelPSF) {
+        *x = source->modelPSF->params->data.F32[PM_PAR_XPOS];
+        *y = source->modelPSF->params->data.F32[PM_PAR_YPOS];
+    } else {
+        *x = source->peak->xf;
+        *y = source->peak->yf;
+    }
+    return;
+}
+
+psArray *stackSourcesFilter(psArray *sources, // Source list to filter
+                                   int exclusion // Exclusion zone, pixels
+    )
+{
+    psAssert(sources && sources->n > 0, "Require array of sources");
+    if (exclusion <= 0) {
+        return psMemIncrRefCounter(sources);
+    }
+
+    int num = sources->n;               // Number of sources
+    psVector *x = psVectorAlloc(num, PS_TYPE_F32), *y = psVectorAlloc(num, PS_TYPE_F32); // Coordinates
+    int numGood = 0;                    // Number of good sources
+    for (int i = 0; i < num; i++) {
+        pmSource *source = sources->data[i]; // Source of interest
+        if (!source) {
+            continue;
+        }
+        coordsFromSource(&x->data.F32[numGood], &y->data.F32[numGood], source);
+        numGood++;
+    }
+    x->n = y->n = numGood;
+
+    psTree *tree = psTreePlant(2, 2, PS_TREE_EUCLIDEAN, x, y); // kd tree
+
+    psArray *filtered = psArrayAllocEmpty(numGood); // Filtered list of sources
+    psVector *coords = psVectorAlloc(2, PS_TYPE_F64); // Coordinates of source
+    int numFiltered = 0;                // Number of filtered sources
+    for (int i = 0; i < num; i++) {
+        pmSource *source = sources->data[i]; // Source of interest
+        if (!source) {
+            continue;
+        }
+        float xSource, ySource;         // Coordinates of source
+        coordsFromSource(&xSource, &ySource, source);
+
+        coords->data.F64[0] = xSource;
+        coords->data.F64[1] = ySource;
+
+        long numWithin = psTreeWithin(tree, coords, exclusion); // Number within exclusion zone
+        psTrace("ppStack", 9, "Source at %.0lf,%.0lf has %ld sources in exclusion zone",
+                coords->data.F64[0], coords->data.F64[1], numWithin);
+        if (numWithin == 1) {
+            // Only itself inside the exclusion zone
+            filtered = psArrayAdd(filtered, filtered->n, source);
+        } else {
+            numFiltered++;
+        }
+    }
+    psFree(coords);
+    psFree(tree);
+    psFree(x);
+    psFree(y);
+
+    psLogMsg("ppStack", PS_LOG_INFO, "Filtered out %d of %d sources", numFiltered, numGood);
+
+    return filtered;
+}
+
+// Add background into the fake image
+// Based on ppSubBackground()
+static psImage *stackBackgroundModel(pmReadout *ro, // Readout for which to generate background model
+                                     const pmConfig *config // Configuration
+    )
+{
+    psAssert(ro && ro->image, "Need readout image");
+    psAssert(config, "Need configuration");
+
+    psImage *image = ro->image;         // Image of interest
+    int numCols = image->numCols, numRows = image->numRows; // Size of image
+
+    psMetadata *ppStackRecipe = psMetadataLookupPtr(NULL, config->recipes, PPSTACK_RECIPE);
+    psAssert(ppStackRecipe, "Need PPSTACK recipe");
+    psMetadata *psphotRecipe = psMetadataLookupPtr(NULL, config->recipes, PSPHOT_RECIPE);
+    psAssert(psphotRecipe, "Need PSPHOT recipe");
+
+    psString maskBadStr = psMetadataLookupStr(NULL, ppStackRecipe, "MASK.BAD");// Name of bits to mask for bad
+    psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels
+
+    // user-defined masks to test for good/bad pixels (build from recipe list if not yet set)
+    psMetadataAddU8(psphotRecipe, PS_LIST_TAIL, "MASK.PSPHOT", PS_META_REPLACE, "user-defined mask", maskBad);
+
+    psImage *binned = psphotModelBackgroundReadoutNoFile(ro, config); // Binned background model
+    psImageBinning *binning = psMetadataLookupPtr(NULL, ro->analysis,
+                                                  "PSPHOT.BACKGROUND.BINNING"); // Binning for model
+    psAssert(binning, "Need binning parameters");
+    psImage *unbinned = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Unbinned background model
+    if (!psImageUnbin(unbinned, binned, binning)) {
+        psError(PPSTACK_ERR_DATA, false, "Unable to unbin background model");
+        psFree(binned);
+        psFree(unbinned);
+        return NULL;
+    }
+    psFree(binned);
+
+    return unbinned;
+}
+
+// Renormalise a readout's variance map
+bool stackRenormaliseReadout(const pmConfig *config, // Configuration
+                             pmReadout *readout      // Readout to renormalise
+    )
+{
+#if 1
+    bool mdok; // Status of metadata lookups
+
+    psMetadata *recipe = psMetadataLookupPtr(NULL, config->recipes, PPSTACK_RECIPE); // Recipe for ppStack
+    psAssert(recipe, "Need PPSTACK recipe");
+
+    if (!psMetadataLookupBool(&mdok, recipe, "RENORM")) return true;
+
+    int num = psMetadataLookupS32(&mdok, recipe, "RENORM.NUM");
+    if (!mdok) {
+        psError(PPSTACK_ERR_CONFIG, true, "RENORM.NUM is not set in the recipe");
+        return false;
+    }
+    float minValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MIN");
+    if (!mdok) {
+        psError(PPSTACK_ERR_CONFIG, true, "RENORM.MIN is not set in the recipe");
+        return false;
+    }
+    float maxValid = psMetadataLookupF32(&mdok, recipe, "RENORM.MAX");
+    if (!mdok) {
+        psError(PPSTACK_ERR_CONFIG, true, "RENORM.MAX is not set in the recipe");
+        return false;
+    }
+
+    psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask
+
+    psImageCovarianceTransfer(readout->variance, readout->covariance);
+    return pmReadoutVarianceRenormalise(readout, maskBad, num, minValid, maxValid);
+#else
+    return true;
+#endif
+}
+
+// This is a hack to use the temporary convolved images and kernel generated previously.
+// This makes the 'matching' operation much faster, allowing debugging of the stack process easier.
+// It implicitly assumes the output root name is the same between invocations.
+
+bool loadKernel () {
+            pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.CONV.KERNEL", index);
+            psAssert(file, "Require file");
+
+            pmFPAview *view = pmFPAviewAlloc(0); // View to readout of interest
+            view->chip = view->cell = view->readout = 0;
+            psString filename = pmFPAfileNameFromRule(file->filerule, file, view); // Filename of interest
+
+            // Read convolution kernel
+            psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename
+            psFree(filename);
+            psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel
+            psFree(resolved);
+            if (!fits || !pmReadoutReadSubtractionKernels(conv, fits)) {
+                psError(PPSTACK_ERR_IO, false, "Unable to read previously produced kernel");
+                psFitsClose(fits);
+                return false;
+            }
+            psFitsClose(fits);
+
+            if (!readImage(&readout->image, options->convImages->data[index], config) ||
+                !readImage(&readout->mask, options->convMasks->data[index], config) ||
+                !readImage(&readout->variance, options->convVariances->data[index], config)) {
+                psError(PPSTACK_ERR_IO, false, "Unable to read previously produced image.");
+                return false;
+            }
+
+            psRegion *region = psMetadataLookupPtr(NULL, conv->analysis,
+                                                   PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region
+            pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, conv->analysis,
+                                                                PM_SUBTRACTION_ANALYSIS_KERNEL);
+
+            pmSubtractionAnalysis(conv->analysis, NULL, kernels, region,
+                                  readout->image->numCols, readout->image->numRows);
+
+            psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel
+            bool oldThreads = psImageCovarianceSetThreads(true);              // Old thread setting
+            psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix
+            psImageCovarianceSetThreads(oldThreads);
+            psFree(readout->covariance);
+            readout->covariance = covar;
+            psFree(kernel);
+}
+
+bool dumpImage() {
+    // XXX should be optional
+            {
+                pmHDU *hdu = pmHDUFromCell(readout->parent);
+                psString name = NULL;
+                psStringAppend(&name, "fake_%03d.fits", index);
+                pmStackVisualPlotTestImage(fake->image, name);
+                psFits *fits = psFitsOpen(name, "w");
+                psFree(name);
+                psFitsWriteImage(fits, hdu->header, fake->image, 0, NULL);
+                psFitsClose(fits);
+            }
+            {
+                pmHDU *hdu = pmHDUFromCell(readout->parent);
+                psString name = NULL;
+                psStringAppend(&name, "real_%03d.fits", index);
+                pmStackVisualPlotTestImage(readout->image, name);
+                psFits *fits = psFitsOpen(name, "w");
+                psFree(name);
+                psFitsWriteImage(fits, hdu->header, readout->image, 0, NULL);
+                psFitsClose(fits);
+            }
+}
+
+bool dumpImage2() {
+    // XXX should be optional
+
+            {
+                pmHDU *hdu = pmHDUFromCell(readout->parent);
+                psString name = NULL;
+                psStringAppend(&name, "conv_%03d.fits", index);
+                pmStackVisualPlotTestImage(conv->image, name);
+                psFits *fits = psFitsOpen(name, "w");
+                psFree(name);
+                psFitsWriteImage(fits, hdu->header, conv->image, 0, NULL);
+                psFitsClose(fits);
+            }
+            {
+                pmHDU *hdu = pmHDUFromCell(readout->parent);
+                psString name = NULL;
+                psStringAppend(&name, "diff_%03d.fits", index);
+                pmStackVisualPlotTestImage(fake->image, name);
+                psFits *fits = psFitsOpen(name, "w");
+                psFree(name);
+                psBinaryOp(fake->image, conv->image, "-", fake->image);
+                psFitsWriteImage(fits, hdu->header, fake->image, 0, NULL);
+                psFitsClose(fits);
+            }
+}
+
+bool dumpImage3() 
+    {
+        pmHDU *hdu = pmHDUFromCell(readout->parent);
+        psString name = NULL;
+        psStringAppend(&name, "convolved_%03d.fits", index);
+        pmStackVisualPlotTestImage(readout->image, name);
+        psFits *fits = psFitsOpen(name, "w");
+        psFree(name);
+        psFitsWriteImage(fits, hdu->header, readout->image, 0, NULL);
+        psFitsClose(fits);
+    }
+
+bool matchKernel() {
+            // Normal operations here
+            psAssert(options->psf, "Require target PSF");
+            psAssert(options->sourceLists && options->sourceLists->data[index], "Require source list");
+
+            int order = psMetadataLookupS32(NULL, subRecipe, "SPATIAL.ORDER"); // Spatial polynomial order
+            float regionSize = psMetadataLookupF32(NULL, subRecipe, "REGION.SIZE"); // Size of iso-kernel regs
+            float spacing = psMetadataLookupF32(NULL, subRecipe, "STAMP.SPACING"); // Typical stamp spacing
+            int footprint = psMetadataLookupS32(NULL, subRecipe, "STAMP.FOOTPRINT"); // Stamp half-size
+            float threshold = psMetadataLookupF32(NULL, subRecipe, "STAMP.THRESHOLD"); // Threshold for stmps
+            int stride = psMetadataLookupS32(NULL, subRecipe, "STRIDE"); // Size of convolution patches
+            int iter = psMetadataLookupS32(NULL, subRecipe, "ITER"); // Rejection iterations
+            float rej = psMetadataLookupF32(NULL, subRecipe, "REJ"); // Rejection threshold
+            float kernelError = psMetadataLookupF32(NULL, subRecipe, "KERNEL.ERR"); // Relative systematic error in kernel
+            float normFrac = psMetadataLookupF32(NULL, subRecipe, "NORM.FRAC"); // Fraction of window for normalisn windw
+            float sysError = psMetadataLookupF32(NULL, subRecipe, "SYS.ERR"); // Relative systematic error in images
+            float skyErr = psMetadataLookupF32(NULL, subRecipe, "SKY.ERR"); // Additional error in sky
+            float covarFrac = psMetadataLookupF32(NULL, subRecipe, "COVAR.FRAC"); // Fraction for covariance calculation
+
+            const char *typeStr = psMetadataLookupStr(NULL, subRecipe, "KERNEL.TYPE"); // Kernel type
+            pmSubtractionKernelsType type = pmSubtractionKernelsTypeFromString(typeStr); // Kernel type
+            psVector *widths = psMetadataLookupPtr(NULL, subRecipe, "ISIS.WIDTHS"); // ISIS Gaussian widths
+            psVector *orders = psMetadataLookupPtr(NULL, subRecipe, "ISIS.ORDERS"); // ISIS Polynomial orders
+            int inner = psMetadataLookupS32(NULL, subRecipe, "INNER"); // Inner radius
+            int ringsOrder = psMetadataLookupS32(NULL, subRecipe, "RINGS.ORDER"); // RINGS polynomial order
+            int binning = psMetadataLookupS32(NULL, subRecipe, "SPAM.BINNING"); // Binning for SPAM kernel
+            float badFrac = psMetadataLookupF32(NULL, subRecipe, "BADFRAC"); // Maximum bad fraction
+            bool optimum = psMetadataLookupBool(&mdok, subRecipe, "OPTIMUM"); // Derive optimum parameters?
+            float optMin = psMetadataLookupF32(&mdok, subRecipe, "OPTIMUM.MIN"); // Minimum width for search
+            float optMax = psMetadataLookupF32(&mdok, subRecipe, "OPTIMUM.MAX"); // Maximum width for search
+            float optStep = psMetadataLookupF32(&mdok, subRecipe, "OPTIMUM.STEP"); // Step for search
+            float optThresh = psMetadataLookupF32(&mdok, subRecipe, "OPTIMUM.TOL"); // Tolerance for search
+            int optOrder = psMetadataLookupS32(&mdok, subRecipe, "OPTIMUM.ORDER"); // Order for search
+            float poorFrac = psMetadataLookupF32(&mdok, subRecipe, "POOR.FRACTION"); // Fraction for "poor"
+
+            bool scale = psMetadataLookupBool(NULL, subRecipe, "SCALE");        // Scale kernel parameters?
+            float scaleRef = psMetadataLookupF32(NULL, subRecipe, "SCALE.REF"); // Reference for scaling
+            float scaleMin = psMetadataLookupF32(NULL, subRecipe, "SCALE.MIN"); // Minimum for scaling
+            float scaleMax = psMetadataLookupF32(NULL, subRecipe, "SCALE.MAX"); // Maximum for scaling
+            if (!isfinite(scaleRef) || !isfinite(scaleMin) || !isfinite(scaleMax)) {
+                psError(PPSTACK_ERR_CONFIG, false,
+                        "Scale parameters (SCALE.REF=%f, SCALE.MIN=%f, SCALE.MAX=%f) not set in PPSUB recipe.",
+                        scaleRef, scaleMin, scaleMax);
+                return false;
+            }
+
+
+            // These values are specified specifically for stacking
+            const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS");// Stamps filename
+
+            psVector *optWidths = NULL;         // Vector with FWHMs for optimum search
+            if (optimum) {
+                optWidths = psVectorCreate(optWidths, optMin, optMax, optStep, PS_TYPE_F32);
+            }
+
+            pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF
+
+            psStats *bg = psStatsAlloc(PS_STAT_ROBUST_STDEV); // Statistics for background
+            psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
+            if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {
+                psError(PPSTACK_ERR_DATA, false, "Can't measure background for image.");
+                psFree(fake);
+                psFree(optWidths);
+                psFree(conv);
+                psFree(bg);
+                psFree(rng);
+                return false;
+            }
+            float minFlux = NOISE_FRACTION * bg->robustStdev; // Minimum flux level for fake image
+            psFree(rng);
+            psFree(bg);
+
+            // For the sake of stamps, remove nearby sources
+            psArray *stampSources = stackSourcesFilter(options->sourceLists->data[index],
+                                                       footprint); // Filtered list of sources
+
+            bool oldThreads = pmReadoutFakeThreads(true); // Old threading state
+            if (!pmReadoutFakeFromSources(fake, readout->image->numCols, readout->image->numRows,
+                                          stampSources, SOURCE_MASK, NULL, NULL, options->psf,
+                                          minFlux, footprint + size, false, true)) {
+                psError(PPSTACK_ERR_DATA, false, "Unable to generate fake image with target PSF.");
+                psFree(fake);
+                psFree(optWidths);
+                psFree(conv);
+                return false;
+            }
+            pmReadoutFakeThreads(oldThreads);
+
+            fake->mask = psImageCopy(NULL, readout->mask, PS_TYPE_IMAGE_MASK);
+
+            // Add the background into the target image
+            psImage *bgImage = stackBackgroundModel(readout, config); // Image of background
+            psBinaryOp(fake->image, fake->image, "+", bgImage);
+            psFree(bgImage);
+
+	    dumpImage();
+
+            if (threads > 0) {
+                pmSubtractionThreadsInit();
+            }
+
+            // Do the image matching
+            pmSubtractionKernels *kernel = psMetadataLookupPtr(&mdok, readout->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL); // Conv kernel
+            if (kernel) {
+                if (!pmSubtractionMatchPrecalc(NULL, conv, fake, readout, readout->analysis,
+                                               stride, kernelError, covarFrac, maskVal, maskBad, maskPoor,
+                                               poorFrac, badFrac)) {
+                    psError(psErrorCodeLast(), false, "Unable to convolve images.");
+                    psFree(fake);
+                    psFree(optWidths);
+                    psFree(stampSources);
+                    psFree(conv);
+                    if (threads > 0) {
+                        pmSubtractionThreadsFinalize();
+                    }
+                    return false;
+                }
+            } else {
+                // Scale the input parameters
+                psVector *widthsCopy = psVectorCopy(NULL, widths, PS_TYPE_F32); // Copy of kernel widths
+                if (scale && !pmSubtractionParamsScale(&size, &footprint, widthsCopy,
+                                                       options->inputSeeing->data.F32[index],
+                                                       options->targetSeeing, scaleRef, scaleMin, scaleMax)) {
+                    psError(psErrorCodeLast(), false, "Unable to scale kernel parameters");
+                    psFree(fake);
+                    psFree(optWidths);
+                    psFree(stampSources);
+                    psFree(conv);
+                    psFree(widthsCopy);
+                    if (threads > 0) {
+                        pmSubtractionThreadsFinalize();
+                    }
+                    return false;
+                }
+
+                if (!pmSubtractionMatch(NULL, conv, fake, readout, footprint, stride, regionSize, spacing,
+                                        threshold, stampSources, stampsName, type, size, order, widthsCopy,
+                                        orders, inner, ringsOrder, binning, penalty,
+                                        optimum, optWidths, optOrder, optThresh, iter, rej, normFrac,
+                                        sysError, skyErr, kernelError, covarFrac, maskVal, maskBad, maskPoor,
+                                        poorFrac, badFrac, PM_SUBTRACTION_MODE_2)) {
+                    psError(psErrorCodeLast(), false, "Unable to match images.");
+                    psFree(fake);
+                    psFree(optWidths);
+                    psFree(stampSources);
+                    psFree(conv);
+                    psFree(widthsCopy);
+                    if (threads > 0) {
+                        pmSubtractionThreadsFinalize();
+                    }
+                    return false;
+                }
+                psFree(widthsCopy);
+            }
+
+	    dumpImage2();
+
+            psFree(fake);
+            psFree(optWidths);
+            psFree(stampSources);
+
+            if (threads > 0) {
+                pmSubtractionThreadsFinalize();
+            }
+
+            // Replace original images with convolved
+            psFree(readout->image);
+            psFree(readout->mask);
+            psFree(readout->variance);
+            psFree(readout->covariance);
+            readout->image  = psMemIncrRefCounter(conv->image);
+            readout->mask   = psMemIncrRefCounter(conv->mask);
+            readout->variance = psMemIncrRefCounter(conv->variance);
+            readout->covariance = psImageCovarianceTruncate(conv->covariance, COVAR_FRAC);
+
+}
+
+bool saveMatchData () {
+       // Extract the regions and solutions used in the image matching
+        // This stops them from being freed when we iterate back up the FPA
+        psArray *regions = options->regions->data[index] = psArrayAllocEmpty(ARRAY_BUFFER); // Match regions
+        {
+            psString regex = NULL;          // Regular expression
+            psStringAppend(&regex, "^%s$", PM_SUBTRACTION_ANALYSIS_REGION);
+            psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex);
+            psFree(regex);
+            psMetadataItem *item = NULL;// Item from iteration
+            while ((item = psMetadataGetAndIncrement(iter))) {
+                assert(item->type == PS_DATA_REGION);
+                regions = psArrayAdd(regions, ARRAY_BUFFER, item->data.V);
+            }
+            psFree(iter);
+        }
+        psArray *kernels = options->kernels->data[index] = psArrayAllocEmpty(ARRAY_BUFFER); // Match kernels
+        {
+            psString regex = NULL;          // Regular expression
+            psStringAppend(&regex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL);
+            psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex);
+            psFree(regex);
+            psMetadataItem *item = NULL;// Item from iteration
+            while ((item = psMetadataGetAndIncrement(iter))) {
+                assert(item->type == PS_DATA_UNKNOWN);
+                pmSubtractionKernels *kernel = item->data.V; // Kernel used in subtraction
+                kernels = psArrayAdd(kernels, ARRAY_BUFFER, kernel);
+            }
+            psFree(iter);
+        }
+        psAssert((regions)->n == (kernels)->n, "Number of match regions and kernels should match");
+}
+
+bool saveChiSquare() {
+        // Record chi^2
+        {
+            double sum = 0.0;           // Sum of chi^2
+            int num = 0;                // Number of measurements of chi^2
+            psString regex = NULL;      // Regular expression
+            psStringAppend(&regex, "^%s$", PM_SUBTRACTION_ANALYSIS_KERNEL);
+            psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex);
+            psFree(regex);
+            psMetadataItem *item = NULL;// Item from iteration
+            while ((item = psMetadataGetAndIncrement(iter))) {
+                assert(item->type == PS_DATA_UNKNOWN);
+                pmSubtractionKernels *kernels = item->data.V; // Convolution kernels
+                sum += kernels->mean;
+                num++;
+            }
+            psFree(iter);
+            options->matchChi2->data.F32[index] = sum / (psImageCovarianceFactor(readout->covariance) * num);
+        }
+
+}
+
+bool renormKernel() {
+        // Kernel normalisation
+        {
+            double sum = 0.0;           // Sum of chi^2
+            int num = 0;                // Number of measurements of chi^2
+            psString regex = NULL;      // Regular expression
+            psStringAppend(&regex, "^%s$", PM_SUBTRACTION_ANALYSIS_NORM);
+            psMetadataIterator *iter = psMetadataIteratorAlloc(conv->analysis, PS_LIST_HEAD, regex);
+            psFree(regex);
+            psMetadataItem *item = NULL;// Item from iteration
+            while ((item = psMetadataGetAndIncrement(iter))) {
+                assert(item->type == PS_TYPE_F32);
+                float norm = item->data.F32; // Normalisation
+                sum += norm;
+                num++;
+            }
+            psFree(iter);
+            float conv = sum/num;       // Mean normalisation from convolution
+            float stars = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation from stars
+            float renorm =  stars / conv; // Renormalisation to apply
+            psLogMsg("ppStack", PS_LOG_INFO, "Renormalising image %d by %f (kernel: %f, stars: %f)\n",
+                     index, renorm, conv, stars);
+            psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(renorm, PS_TYPE_F32));
+            psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(renorm), PS_TYPE_F32));
+        }
+
+}
Index: /branches/pap/psphot/src/psphotVisual.c
===================================================================
--- /branches/pap/psphot/src/psphotVisual.c	(revision 28002)
+++ /branches/pap/psphot/src/psphotVisual.c	(revision 28003)
@@ -446,4 +446,6 @@
     KapaSetFont (myKapa, "courier", 14);
 
+    section.bg = KapaColorByName ("none"); // XXX probably should be 'none'
+
     float SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM");
 
@@ -538,5 +540,10 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = NAN;
+    graphdata.padYm = NAN;
+    graphdata.padXp = 0.5;
+    graphdata.padYp = 0.5;
     KapaBox (myKapa, &graphdata);
+
     KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM);
     KapaSendLabel (myKapa, "M_yy| (pixels)", KAPA_LABEL_YM);
@@ -547,4 +554,5 @@
     graphdata.style = 2;
     KapaPrepPlot (myKapa, nF, &graphdata);
+
     KapaPlotVector (myKapa, nF, xFaint->data.F32, "x");
     KapaPlotVector (myKapa, nF, yFaint->data.F32, "y");
@@ -562,5 +570,5 @@
     section.dy = 0.25;
     section.x  = 0.00;
-    section.y  = 0.80;
+    section.y  = 0.75;
     section.name = psStringCopy ("MagMyy");
     KapaSetSection (myKapa, &section);
@@ -574,4 +582,8 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = 0.5;
+    graphdata.padYm = NAN;
+    graphdata.padXp = NAN;
+    graphdata.padYp = 0.5;
     strcpy (graphdata.labels, "0210");
     KapaBox (myKapa, &graphdata);
@@ -598,5 +610,5 @@
     section.dx = 0.25;
     section.dy = 0.75;
-    section.x  = 0.80;
+    section.x  = 0.75;
     section.y  = 0.00;
     section.name = psStringCopy ("MagMxx");
@@ -611,4 +623,8 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = NAN;
+    graphdata.padYm = 0.5;
+    graphdata.padXp = 0.5;
+    graphdata.padYp = NAN;
     strcpy (graphdata.labels, "2001");
     KapaBox (myKapa, &graphdata);
@@ -1350,4 +1366,6 @@
     assert (maskVal);
 
+    section.bg  = KapaColorByName ("none"); // XXX probably should be 'none'
+
     KapaClearPlots (myKapa);
     // first section : mag vs CR nSigma
@@ -1586,4 +1604,6 @@
     KapaSetFont (myKapa, "courier", 14);
 
+    section.bg  = KapaColorByName ("none"); // XXX probably should be 'none'
+
     // select the max psfX,Y values for the plot limits
     float Xmin = 1000.0, Xmax = 0.0;
@@ -1754,4 +1774,8 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = NAN;
+    graphdata.padYm = NAN;
+    graphdata.padXp = 0.5;
+    graphdata.padYp = 0.5;
     KapaBox (myKapa, &graphdata);
     KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM);
@@ -1822,4 +1846,8 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = 0.5;
+    graphdata.padYm = NAN;
+    graphdata.padXp = NAN;
+    graphdata.padYp = 0.5;
     strcpy (graphdata.labels, "0210");
     KapaBox (myKapa, &graphdata);
@@ -1870,5 +1898,5 @@
     section.dx = 0.25;
     section.dy = 0.60;
-    section.x  = 0.80;
+    section.x  = 0.75;
     section.y  = 0.00;
     section.name = psStringCopy ("MagMxx");
@@ -1883,4 +1911,8 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = NAN;
+    graphdata.padYm = 0.5;
+    graphdata.padXp = 0.5;
+    graphdata.padYp = NAN;
     strcpy (graphdata.labels, "2001");
     KapaBox (myKapa, &graphdata);
@@ -1930,7 +1962,7 @@
     // fourth section: MagSigma
     section.dx = 0.75;
-    section.dy = 0.15;
+    section.dy = 0.20;
     section.x  = 0.00;
-    section.y  = 0.65;
+    section.y  = 0.60;
     section.name = psStringCopy ("MagSigma");
     KapaSetSection (myKapa, &section);
@@ -1944,4 +1976,8 @@
     KapaSetLimits (myKapa, &graphdata);
 
+    graphdata.padXm = 0.5;
+    graphdata.padYm = NAN;
+    graphdata.padXp = 0.5;
+    graphdata.padYp = 0.5;
     strcpy (graphdata.labels, "0100");
     KapaBox (myKapa, &graphdata);
@@ -2053,4 +2089,9 @@
     psFree (mDEF);
     psFree (sDEF);
+
+    psFree (xLOW);
+    psFree (yLOW);
+    psFree (mLOW);
+    psFree (sLOW);
 
     psFree (xCR);
@@ -2297,29 +2338,28 @@
         if (!source) continue;
         if (!source->extpars) continue;
-        if (!source->extpars->profile) continue;
-        if (!source->extpars->petrosian_80) continue;
-
-        pmSourceRadialProfile *profile = source->extpars->profile;
-        pmSourceExtendedFlux *petrosian = source->extpars->petrosian_80;
+        if (!source->extpars->petProfile) continue;
+
+        float petrosianRadius = source->extpars->petrosianRadius;
+	psEllipseAxes *axes = &source->extpars->axes;
 
         overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
         overlay[Noverlay].x = source->peak->xf;
         overlay[Noverlay].y = source->peak->yf;
-        overlay[Noverlay].dx = 2.0*petrosian->radius;
-        overlay[Noverlay].dy = 2.0*petrosian->radius*profile->axes.minor/profile->axes.major;
-        overlay[Noverlay].angle = profile->axes.theta * PS_DEG_RAD;
+        overlay[Noverlay].dx = 1.0*petrosianRadius;
+        overlay[Noverlay].dy = 1.0*petrosianRadius*axes->minor/axes->major;
+        overlay[Noverlay].angle = axes->theta * PS_DEG_RAD;
         overlay[Noverlay].text = NULL;
         Noverlay ++;
         CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
 
-        overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
-        overlay[Noverlay].x = source->peak->xf;
-        overlay[Noverlay].y = source->peak->yf;
-        overlay[Noverlay].dx = 4.0*petrosian->radius;
-        overlay[Noverlay].dy = 4.0*petrosian->radius*profile->axes.minor/profile->axes.major;
-        overlay[Noverlay].angle = profile->axes.theta * PS_DEG_RAD;
-        overlay[Noverlay].text = NULL;
-        Noverlay ++;
-        CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
+        // overlay[Noverlay].type = KII_OVERLAY_CIRCLE;
+        // overlay[Noverlay].x = source->peak->xf;
+        // overlay[Noverlay].y = source->peak->yf;
+        // overlay[Noverlay].dx = 2.0*petrosianRadius;
+        // overlay[Noverlay].dy = 2.0*petrosianRadius*axes->minor/axes->major;
+        // overlay[Noverlay].angle = axes->theta * PS_DEG_RAD;
+        // overlay[Noverlay].text = NULL;
+        // Noverlay ++;
+        // CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);
     }
 
Index: /branches/pap/pstamp/doc/dsinstall.txt
===================================================================
--- /branches/pap/pstamp/doc/dsinstall.txt	(revision 28003)
+++ /branches/pap/pstamp/doc/dsinstall.txt	(revision 28003)
@@ -0,0 +1,417 @@
+Installing the data store sample implementation
+XXX: This text was found lying around in my workspace. It needs to be
+checked for accuarcy
+
+Overview
+--------
+
+This note describes the installation and operation of the IPP Postage Stamp Server.
+We assume that IPP source for examination and that the user has the standard
+IPP configuration environment set up.
+
+This component of the IPP system is not intended for general distribution to IPP users
+and does not have streamlined installation procedures at this time.
+
+The PSS is a system which responds to requests to retrieve images from an IPP Image Server.
+The images may be either complete images or subsets of images known as "Postage Stamps".
+
+The internal mechanisms of the PSS are also used to service MOPS detectabiltiy
+query requests.
+
+Given this more general utility it should perhaps be called the "IPP Request Server".
+
+
+Data Store
+----------
+The PSS uses the Data Store mechanism to find incoming requests and to 
+provide results to the end user.
+
+A DataStore is simply a web server with URLS that supports an interface
+that allows collections of data called File Sets to be located and accessed.
+
+A Data Store is organized into 3 levels. These are described in the following sections.
+
+Data Store Root - a list of Products
+-------------------------------------
+
+Assume that a datastore is located on the server WEBSERVERHOST.
+An HTTP get to the url http://WEBSERVERHOST/ds/index.txt would give a list of the
+products in the Data Store.
+
+    # productID  |Most recent |Time registered     |type     |Description                     |
+    pstampresults|web204      |2008-10-16T00:35:16Z|psresults|Postage Stamp Results           |
+    pstamprequests|TEST0012    |2008-08-29T03:26:40Z|psrequest|Postage Stamp Requests          |
+    mops-pstamp-results|MOPSSTAMPREQ20080813T214918Z_00|2008-08-13T21:49:42Z|psresults|Postage Stamp Results for MOPS  |
+
+Each line is divided into fields separated by a 'pipe' character | .
+
+Data Store Product - a list of filesets
+---------------------------------------
+
+Similarly the url http://WEBSERVERHOST/ds/pstampresults/index.txt gives the list of filesets
+in the product pstampresults:
+
+    # filesetID|time registered     |type     |
+    TEST0011   |2008-08-29T03:05:03Z|PSRESULTS|
+    TEST0012   |2008-08-29T03:31:36Z|PSRESULTS|
+    web190     |2008-10-15T02:29:11Z|PSRESULTS|
+    web191     |2008-10-15T02:32:16Z|PSRESULTS|
+    web192     |2008-10-15T02:38:50Z|PSRESULTS|
+    web193     |2008-10-15T03:08:57Z|PSRESULTS|
+    web194     |2008-10-15T23:32:11Z|PSRESULTS|
+    web195     |2008-10-15T23:35:39Z|PSRESULTS|
+    web196     |2008-10-15T23:52:40Z|PSRESULTS|
+    web197     |2008-10-15T23:59:05Z|PSRESULTS|
+    web198     |2008-10-16T00:04:17Z|PSRESULTS|
+    web200     |2008-10-16T00:17:46Z|PSRESULTS|
+    web204     |2008-10-16T00:35:16Z|PSRESULTS|
+
+Note that the fileset ID for the latest fileset (web204) in the list appears in the root listing in the last
+section.
+
+The product list protocol accepts a query string which can be used to limit the listing to all filesets
+registered after a given fileset.
+
+For example, http://WEBSERVERHOST/ds/pstampresults/index.txt?web198 yields
+
+    # filesetID|time registered     |type     |
+    web200     |2008-10-16T00:17:46Z|PSRESULTS|
+    web204     |2008-10-16T00:35:16Z|PSRESULTS|
+
+
+File Set - a list of files
+--------------------------
+http://ippds.somwhere.net/ds/pstampresults/web205/index.txt
+
+    # fileID          |bytes   |md5sum                          |type        |
+    results.fits      |28800   |4e2048479e551844e31102a301d50740|table       |
+    # fileID          |bytes   |md5sum                          |type        |chipname|
+    1_1_o4748g0259o.ota01.fits|19840320|19a6233ab966cf3e13b7da8271dead67|chip        |XY01    |
+    1_2_o4748g0259o.ota02.fits|20416320|625bf8198dd7aef7c892af03584ee0ed|chip        |XY02    |
+
+    .... followed by 58 other files in this GPC1 exposure
+
+
+The IPP includes a number of tools for accessing a data store. An introduction to these tools may
+be seen by using the program perldoc.
+
+    dsrootls
+    dsproductls
+    dsfilesetls
+    dsget
+
+
+Installing the IPP Data Store Server Implementation
+---------------------------------------------------
+
+The data store implementation consists of a set of cgi scripts which are
+invoked by an apache web server. The indexes for the Data Store are stored in a mysql
+database. The cgi scripts use DBI perl module to query the database. No database updates
+are performed by the Data Store cgi scripts.
+
+The files for the Data Store Server located in the IPP source tree in the directory
+DataStoreServer (this directory may not be available in the distributed IPP
+tarballs).
+
+Mysql data base configuration
+-----------------------------
+
+The tables for the PSS are part of the regular IPP database tables.
+
+The Data Store implementation has been designed to not require the IPP for its
+operation so the Data Store's tables are not created as part of the IPP database setup.
+
+Currently however, the PostageStamp Server implementation assumes that the data
+store and postage stamp tables are in the same mysql database (this will be
+fixed soon).
+
+To set up the database go to the directory DataStoreServer/scripts and start up mysql.
+
+If you do not already have a current IPP database that you would like to use
+for the Postage Stamp Request tables issue the following commands
+
+    mysql> create database mydatabase;
+    mysql> use mydatabase;
+    mysql> source scripts/tabledefs.sql;
+
+Now exit mysql and run the command
+    pxadmin -create -dbname mydatabase
+
+If you already have a database set up, then just issue the commands
+    mysql> use mydatabase;
+    mysql> source scripts/tabledefs.sql;
+
+Web Server Configuration
+------------------------
+The apache configuration needs to have the following entries added to
+the appropriate configuration file. (Different apache distributions have
+different locations for these files so it's up to the installer to
+figure out where these configuration lines should go).
+
+       <Directory "/DATASTOREDIR/dsroot">
+
+          DirectoryIndex /ds-cgi/dsindex.cgi
+
+          #Options None
+
+          # turn on server side includes
+          Options +Includes
+
+          # files will be processed for server side includes if they have the
+          # executable bit set
+          XBitHack on
+
+          AddType text/plain .txt
+          AddOutputFilter INCLUDES .txt
+
+          AllowOverride None
+
+          Order allow,deny
+          Allow from all
+        </Directory>
+
+        #
+        # Location of the cgi scripts
+        #
+
+        <Directory "/DATASTOREDIR/ds-cgi">
+          Options ExecCGI
+
+
+          Order allow,deny
+          Allow from all
+        </Directory>
+
+        Alias       /ds     /DATASTOREDIR/dsroot/
+        ScriptAlias /ds-cgi /DATASTOREDIR/ds-cgi/
+
+(another sample of this configuration file may be found in 
+    DataStoreServer/web/conf/httpd-datastore.conf
+
+Here we have assumed that the data store cgi scripts will be installed in
+/DATASTOREDIR/ds-cgi and the data store data files will be stored in
+/DATASTOREDIR/dsroot.
+
+To install the cgi scripts
+    cd your_ipp_src_directory
+    cd DataStoreServer
+    scripts/installscripts --dsroot /DATASTOREDIR/dsroot --cgidir /DATASTOREDIR/ds-cgi
+
+The file /DATASTOREDIR/ds-cgi/dsshellconfig is a shell script that sets
+several environment variables that are required by the scripts.
+
+This script should be editied to customize the values for the installation.
+(This file will not be overwritten by subsequent invocations of
+installscripts).
+
+There are some scripts that the Postage Stamp Server uses that need to be
+installed into the IPP build directory. These are not included in the current IPP
+build. To build them invoke the following commands from the DataStoreServer
+directory.
+    psautogen
+    make install
+
+
+Testing the DataStore
+---------------------
+At this point an empty data store should be up and running. This can be tested
+by going to the following url in a web browser
+    http://WEBSERVERHOST/ds/index.txt
+
+If things are working properlly you should see the following output
+
+# productID  |Most recent |Time registered     |type     |Description                     |
+
+If an errror occurs check the web server error log and begin debugging.
+
+The following command may be used to create a test product in the data store
+
+dsprodtool --dbname mydatabase --dsroot   /DATASTOREDIR/dsroot/ \
+     --add testproduct --type psresults --description 'test data store product'
+
+Now if you point to http://WEBSERVERHOST/ds/index.txt with a web browser you
+should see 
+
+# productID  |Most recent |Time registered     |type     |Description                     |
+testproduct  |none        |2008-10-16T20:48:23Z|psresults|test data store product         |
+
+(of course your timestamp will be different).
+
+As a final test we will add a fileset to the data store.
+
+echo this is a file > testfile.txt
+
+echo 'testfile.txt|||text|' | dsreg --dbname mydatabase --dsroot /DATASTOREDIR/dsroot/ \
+    --product testproduct --add testfileset --type PSRESULTS --list - --copy --datapath .
+
+-list - tells dsreg to get the list of files for the fileset from stdin.
+(Usually a file is used).  The input to the command gives the name of the file to be added to the
+fileset, blank entries for size and md5sum, and the file type 'text'. 
+
+Now if you go to http://WEBSERVERHOST/ds/testfileset/index.txt you should see
+the fileset.
+
+If you leave off the index.txt in the urls you will get a more web browser
+friendly html pages with links.
+For example
+    http://WEBSERVERHOST/ds
+
+To delete the test product
+    dsprodtool --dbname mydatabase --dsroot /DATASTOREDIR/dsroot/ --del psresults --rm
+
+Set up the product for the postage stamp results with
+
+    dsprodtool --dbname mydatabase --dsroot /DATASTOREDIR/dsroot/ \
+         --add pstampresults --type psresults --description 'Postage Stamp results'
+
+and a product for requests
+
+    dsprodtool --dbname mydatabase --dsroot /DATASTOREDIR/dsroot/ \
+         --add pstamprequests --type psrequest --description 'Postage Stamp requests'
+
+Postage Stamp Server Set up
+---------------------------
+
+Now we are ready to set up the Postage Stamp Server.
+
+The programs that make up the PSS are controlled by a set of pantasks tasks. 
+There are some configuration variables that must be added to the site.config file.
+
+    # root directory of the data store
+    # this must match the directory used above in the Data Store setup
+    DATA_STORE_ROOT STR /DATASTOREDIR/dsroot
+
+    # default data store product used for results 
+    # (used by the web interface)
+    PSTAMP_DATA_STORE_PRODUCT STR pstampresults
+
+    # This directory is used for downloaded request files and other purposes
+    # it can go anywhere. The permissions on the directory must be such that
+    # that the web server program has permission to write there.
+    PSTAMP_WORKDIR STR /SOMEWHERE/pstamp-work
+
+PSS projects
+------------
+Each Postage stamp request selects images from a particular 'project'. 
+Each project has a row in the table pstampProject has the following columns
+
+    column      example
+    -------------------
+    name        simtest
+    state       enabled
+    dbname      ps_simtest
+    dvodb       NULL      (currently not used)
+    camera      SIMTEST
+    telescope   SimScope
+    need_magic  0
+
+The column dbname contains the name of the database that is used to look up images.
+To create a project use pstamptool. In this example ps_simtest is a database
+refererencing images made by a simtest run.
+
+pstamptool -dbname mydatabase -addproject -name foo -imagedb ps_simtest -inst SIMTEST -telescope SimScope
+
+
+Postage Stamp Request Tables
+----------------------------
+
+Postage Stamp requests are submitted in the form of a FITS binary table. The
+format of this table is described in a document which may be found on the IPP wiki.
+http://kiawe.ifa.hawaii.edu/IPPwiki/index.php/PostageStampServer
+
+Only the first table extension found in the request file is processed. 
+
+Each postage stamp request file submitted to the PSS generates a "Request".
+The name of the request is given by the value for the keyword REQ_NAME in
+the extension's fits header. Each postage stamp request must have a unique REQ_NAME must be unique.
+
+To process the request the PSS parses the request file.
+Each row in a request table contains a request specification. Each request specification
+causes zero or more "Jobs" to be queued for processing. Each Job operates on
+one input image.
+
+When all of the Jobs for a given Request complete, a Postage stamp results
+file is created and it along with the images produced by the jobs are
+registered in a fileset on the output Data Store.
+
+There are two job types specified by the value for the JOB_TYPE keyword in the
+request specification.
+
+    JOB_TYPE = "stamp" creates a "postage stamp" image.
+    JOB_TYPE = "get_image" builds a fileset containing copies of images
+
+There are two programs that may be used to create a postage stamp request.
+pstamprequest creates a request file with a single request specification.
+
+For example
+
+    pstamprequest -req_name REQ_00001 -project simtest /mydirectory/req.fits \
+                  -byexp chip simtest.004.000 null \
+                  -pixcenter 500 500 -pixrange 100 100
+
+creates a request file req.fits containing a request specification for a 100 x 100 pixel 
+postage stamp image centered at (500,500) in the source.
+The source image is chip processed image for one of the object exposures from a simtest run.
+
+Another program that may be used to create a request file is located in
+pstamp/test/pstamp_req_create.  This program takes a text file and creates a multi-row postage
+stamp request.  A couple of example input files may be found in pstamp/test/*.txt
+
+Queueing a PostageStamp Request
+-------------------------------
+The postage stamp server looks for work to do by examining a collection of
+input Data Stores. For example, the MOPS team will have a datastore onto which
+they will submit their postage stamp requests.
+
+There will also be a web based interface. A prototype for this will be
+discussed in a later section of this document.
+
+For testing, we may queue a request by hand using the program pstamptool
+
+    pstamptool -dbname mydatabase -addreq -uri /mydirectory/req.fits
+
+This adds an entry to the table pstampRequests with state = 'new'
+
+Request Processing
+------------------
+
+Postage stamp requests are processed by a set of pantasks tasks.
+
+ Task Status
+  AV Name                Njobs  Ngood Nfail Ntime Command            
+  ++ pstamp.request.find   921    921     0     0 pstamp_queue_requests.pl
+  ++ pstamp.request.run     13     13     0     0 pstamp_parser_run.pl
+  ++ request.finish.load  1839   1839     0     0 pstamptool         
+  ++ request.finish.run     14     14     0     0 request_finish.pl  
+  ++ pstamp.job.load      1840   1840     0     0 pstamptool         
+  ++ pstamp.job.run         30     30     0     0 pstamp_job_run.pl  
+  ++ pstamp.request.load  1566   1566     0     0 pstamptool
+
+pstamp.request.find examines incoming data stores for new requests and adds
+them if found
+
+pstamp.request.load dispatches pending requests for parsing
+
+pstamp.request.run runs the request parser which queues jobs to service the
+request specifications.
+
+pstamp.job.load dispatches pending jobs for processing
+
+pstamp.job.run runs a single job
+
+pstamp.finish.load looks for requests which have no pending jobs
+
+pstamp.finish.run builds the results fileset and registers it on the ouptut
+Data Store.
+
+Output Fileset
+-------------
+A successful request will generate a fileset with the name the REQ_NAME of the
+request in the output Data Store. The output product is determined by the
+source of the request as discussed in the next section. (If the request did
+not come from a data store the product is given by the value of PSTAMP_DATA_STORE_PRODUCT
+in the IPP site.config file.
+
+
+
+
Index: /branches/pap/pstamp/scripts/Makefile.am
===================================================================
--- /branches/pap/pstamp/scripts/Makefile.am	(revision 28002)
+++ /branches/pap/pstamp/scripts/Makefile.am	(revision 28003)
@@ -3,4 +3,5 @@
 
 install_files = \
+	pstamp_cleanup.pl \
 	pstamp_finish.pl \
 	pstamp_insert_request.pl \
@@ -20,4 +21,5 @@
 	pstamp_checkdependent.pl \
 	request_finish.pl \
+	detectability_respond.pl \
 	detect_query_read \
 	detect_response_create \
Index: /branches/pap/pstamp/scripts/detect_query_read
===================================================================
--- /branches/pap/pstamp/scripts/detect_query_read	(revision 28002)
+++ /branches/pap/pstamp/scripts/detect_query_read	(revision 28003)
@@ -78,10 +78,16 @@
                         comment => 'site identifier (MPC observatory code)',
                         value => undef
-              }
+                      },
+ 	'STAGE'    => { 
+	                name => 'STAGE',
+			writetype => TSTRING,
+			comment => 'processing stage to examine',
+			value => undef
+	              }
 };
 
 # key_array insures that the order that the keywords is printed out is
 # the same as the ICD
-my @key_array = qw( QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE );
+my @key_array = qw( QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE STAGE);
 
 # Specification of columns
@@ -144,4 +150,7 @@
         my $name = $header->{$key}->{name};
         my $value = $inHeader->{$name};
+	if (($key eq 'STAGE')&& !(defined($value))) {
+	    $value = 'DIFF';
+	}
         # get rid of quotes and whitespace
         $value =~ s/\'//g;
Index: /branches/pap/pstamp/scripts/detectability_respond.pl
===================================================================
--- /branches/pap/pstamp/scripts/detectability_respond.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/detectability_respond.pl	(revision 28003)
@@ -41,10 +41,12 @@
 my $EXTVER = 1.0;
 my $EXTNAME = 'MOPS_DETECTABILITY_RESPONSE';
-my ($req_id,$req_name,$product,$need_magic,$missing_tools);
-my ($request_file,$output,$dbname,$verbose,$save_temps);
+my ($req_id,$req_name,$product,$need_magic,$missing_tools,$project);
+my ($request_file,$output,$workdir,$dbname,$dbserver,$verbose,$save_temps);
 GetOptions(
-    'input=s'          =>     \$request_file,
+    'input=s'         =>      \$request_file,
     'output=s'        =>      \$output,
+    'workdir=s'       =>      \$workdir,
     'dbname=s'        =>      \$dbname,
+    'dbserver=s'      =>      \$dbserver,
     'verbose'         =>      \$verbose,
     'save-temps'      =>      \$save_temps,
@@ -55,5 +57,5 @@
 	   -exitval => 3,
     ) unless
-    defined $request_file and defined $output and defined $dbname;
+    defined $request_file and defined $output and defined $workdir and defined $dbname;
 
 my $detect_query_read = can_run('detect_query_read') or (warn "Can't find detect_query_read" and $missing_tools = 1);
@@ -71,15 +73,26 @@
 
 my $ipprc = PS::IPP::Config->new();
-#my $tmp_dir = "/data/${host}.0/tmp/";
+
+if (!$dbserver) {
+    $dbserver = metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
+}
+# This is hardcoded in for the moment.
+$project = resolve_project($ipprc,"gpc1",$dbname,$dbserver);
+my $imagedb = $project->{dbname};
+if (!$imagedb) {
+    carp("failed to find imagedb for project: $project");
+}
 
 #
 # Parse input request file using detect_query_read (as it's already written).
 #
-
 my $dqr_command = "$detect_query_read --input $request_file";
 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     run(command => $dqr_command, verbose => $verbose);
 unless ($success) {
-    my_die("Unable to perform $dqr_command error code: $error_code",-1,-1,-1,-1,-1,-1);
+    # This is a problem, because I'm not sure how we handle a failure to read something.
+    # We need to return a $PSTAMP_INVALID_REQUEST, I think, but if we can't read it, 
+    # we can't send that response back.
+    die("Unable to perform $dqr_command error code: $error_code");
 }
 my %query = ();
@@ -119,6 +132,6 @@
 my %image_list_hash;
 for (my $i = 1; $i < $Nrows; $i++) {
-#    print "$i $Nrows $query{CONTENT}{RA1_DEG}[$i] $query{CONTENT}{DEC1_DEG}[$i]\n";
-
+    # This could use the fact that locate_images now accepts position arrays, but
+    # I'll save that for after I get the majority of things working.
     my $image_set_tmp  = find_image_set($query{HEADER}{FPA_ID}[0],$query{HEADER}{STAGE}[0],
 					$query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],
@@ -126,10 +139,21 @@
 					$query{CONTENT}{ROWNUM}[$i],$verbose);
     unless (%$image_set_tmp) {
-	my_die("No images were returned.",$query{HEADER}{QUERY_ID}[0],$query{HEADER}{FPA_ID}[0],
-	       $query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],$query{HEADER}{OBSCODE}[0],
-	       $query{HEADER}{STAGE}[0]);
-    }
-    print "=== $image_set_tmp->{IMAGE}\n    $image_set_tmp->{PSF}\n    $image_set_tmp->{MASK}\n    $image_set_tmp->{WEIGHT}\n    $image_set_tmp->{SKY_COORDINATES}\n    $image_set_tmp->{ROWNUM}\n";
-    # This appends, assuming that if we get an image, we also get the identical psf/mask/weight/etc.
+	# No images were returned, so create a dummy entry that 
+	$image_list_hash{'no_image'}{IMAGE}    = 'no_image';
+	$image_list_hash{'no_image'}{PSF}      = 'no_psf';
+	$image_list_hash{'no_image'}{MASK}     = 'no_mask';
+	$image_list_hash{'no_image'}{WEIGHT}   = 'no_weight';
+	$image_list_hash{'no_image'}{CATALOG}  = 'no_catalog';
+	$image_list_hash{'no_image'}{CLASS_ID} = 'no_class';
+	$image_list_hash{'no_image'}{ERROR}    = $PSTAMP_NO_IMAGE_MATCH;
+	push @{ $image_list_hash{'no_image'}{SKY_COORDINATES} }, "$query{CONTENT}{RA1_DEG}[$i] $query{CONTENT}{DEC1_DEG}[$i]";
+	push @{ $image_list_hash{'no_image'}{ROWNUM} }, $query{CONTENT}{ROWNUM}[$i];
+	next;
+    }
+#     print "=== $image_set_tmp->{IMAGE}\n    $image_set_tmp->{PSF}\n";
+#     print "    $image_set_tmp->{MASK}\n    $image_set_tmp->{WEIGHT}\n";
+#     print "    $image_set_tmp->{SKY_COORDINATES}\n    $image_set_tmp->{ROWNUM}\n";
+
+    # This indexes the results for identical images into the same hash.
     $image_list_hash{$image_set_tmp->{IMAGE}}{IMAGE}    = $image_set_tmp->{IMAGE};
     $image_list_hash{$image_set_tmp->{IMAGE}}{PSF}      = $image_set_tmp->{PSF};
@@ -138,14 +162,19 @@
     $image_list_hash{$image_set_tmp->{IMAGE}}{CATALOG}  = $image_set_tmp->{CATALOG};
     $image_list_hash{$image_set_tmp->{IMAGE}}{CLASS_ID} = $image_set_tmp->{CLASS_ID};
+    $image_list_hash{$image_set_tmp->{IMAGE}}{ERROR}    = $image_set_tmp->{ERROR};
     push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{SKY_COORDINATES} }, $image_set_tmp->{SKY_COORDINATES};
     push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{ROWNUM} }, $image_set_tmp->{ROWNUM};
 }
+
 my $i = 0;
-
 foreach my $k (keys %image_list_hash) {
+    # If we errored out on finding an image, we need to not try to run psphot here.
+    if ($image_list_hash{$k}{ERROR} != 0) {
+	next;
+    }
     # Write coordinates of the requested targets to a file.
-    my ($coordfile,$coordname) = tempfile("/tmp/detect.coords.$i.XXXX", 
+    my ($coordfile,$coordname) = tempfile("${workdir}/detect.coords.$i.XXXX", 
 					    UNLINK => !$save_temps);
-    my ($targetfile,$targetname) = tempfile("/tmp/detect.targets.$i.XXXX", 
+    my ($targetfile,$targetname) = tempfile("${workdir}/detect.targets.$i.XXXX", 
 					    UNLINK => !$save_temps);
 
@@ -153,5 +182,5 @@
 	print $coordfile "$image_list_hash{$k}{SKY_COORDINATES}[$j]\n";
     }
-
+#    print "$k\n";
     # Convert the sky coordinates to image coordinates with ppCoord.
     my $command = "ppCoord -astrom $image_list_hash{$k}{CATALOG} -radec $coordname";
@@ -171,7 +200,7 @@
     }
 
-    
+#     print "psphot $image_list_hash{$k}{PSF}\n";
     # Run psphotForced on the target list.
-    my $tmpdir  = tempdir("detect.$i.XXXX", DIR => "/tmp/", CLEANUP => !$save_temps);
+    my $tmpdir  = tempdir("detect.$i.XXXX", DIR => "${workdir}/", CLEANUP => !$save_temps);
     $image_list_hash{$k}{OUTROOT} = "$tmpdir/detectability.$query{HEADER}{STAGE}[0].$query{HEADER}{FPA_ID}[0]";
     
@@ -185,8 +214,5 @@
 	run(command => $psphot_cmd, verbose => $verbose);
     unless ($success) {
-	my_die("Unable to perform $psphot_cmd. Error_code: $error_code",
-	       $query{HEADER}{QUERY_ID}[0],$query{HEADER}{FPA_ID}[0],
-	       $query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],$query{HEADER}{OBSCODE}[0],
-	       $query{HEADER}{STAGE}[0],$error_code);
+	$image_list_hash{$k}{ERROR} = $PSTAMP_SYSTEM_ERROR;
     }
 }
@@ -196,16 +222,28 @@
 #
 my @rownums = ();
+my @out_errors = ();
 my @psphot_Npix = ();
 my @psphot_Qfact= ();
 my @psphot_flux = ();
+
 foreach my $k (keys %image_list_hash) {
-    my $cmf = "$image_list_hash{$k}{OUTROOT}.$image_list_hash{$k}{CLASS_ID}.cmf";
-    
-    my ($tmp_Npix,$tmp_Qfact,$tmp_flux) = read_cmf_file($cmf,$image_list_hash{$k}{EXTENSION_BASE});
-
-    push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
-    push @psphot_Npix,    @{ $tmp_Npix };
-    push @psphot_Qfact,   @{ $tmp_Qfact };
-    push @psphot_flux,    @{ $tmp_flux };
+    if ($image_list_hash{$k}{ERROR} == 0) {
+	my $cmf = "$image_list_hash{$k}{OUTROOT}.$image_list_hash{$k}{CLASS_ID}.cmf";
+	
+	my ($tmp_Npix,$tmp_Qfact,$tmp_flux) = read_cmf_file($cmf,$image_list_hash{$k}{EXTENSION_BASE});
+	
+	push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
+	push @out_errors,     (map { $image_list_hash{$k}{ERROR} }  @{ $image_list_hash{$k}{ROWNUM} });
+	push @psphot_Npix,    @{ $tmp_Npix };
+	push @psphot_Qfact,   @{ $tmp_Qfact };
+	push @psphot_flux,    @{ $tmp_flux };
+    }
+    else {
+	push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
+	push @out_errors,     (map { $image_list_hash{$k}{ERROR} }  @{ $image_list_hash{$k}{ROWNUM} });
+	push @psphot_Npix,    (map { 0 }  @{ $image_list_hash{$k}{ROWNUM} });
+	push @psphot_Qfact,   (map { 0.0 }  @{ $image_list_hash{$k}{ROWNUM} });
+	push @psphot_flux,    (map { 0.0 }  @{ $image_list_hash{$k}{ROWNUM} });
+    }	
 }
 
@@ -214,20 +252,15 @@
 		    $query{HEADER}{MJD_OBS}[0],$query{HEADER}{filter}[0],
 		    $query{HEADER}{obscode}[0],
-		    \@rownums, \@psphot_Npix, \@psphot_Qfact, \@psphot_flux);
-
+		    \@rownums, \@out_errors, \@psphot_Npix, \@psphot_Qfact, \@psphot_flux);
+# print "Wrote response file $output\n";
 #
 # Add to datastore
 #
-# my $finish_command = "dquery_finish.pl --req_id $req_id --req_name $req_name --product $product";
-# ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-#     run(command => $finish_command, verbose => $verbose);
-# unless ($success) {
-#     warn ("Unable to perform $finish_command error code: $error_code");
-# }
-
+# Files are added to the datastore by dquery_finish.pl
 #
 # Cleanup
 #
 # Since everything is written to temporary files, there should be nothing to cleanup.
+
 #
 # Utilities
@@ -242,5 +275,6 @@
     my $index  = shift;
     my $verbose = shift;
-    
+
+    # This is the set of things that we need in order to run psphotForced
     my $option_mask |= 1;
     $option_mask |= $PSTAMP_SELECT_IMAGE;
@@ -252,8 +286,21 @@
     my $mjd_max = $mjd + 1;
 
+    # Construct a row list. 
+    my @rowList;
+    $rowList[0]->{CENTER_X} = $ra;
+    $rowList[0]->{CENTER_Y} = $dec;
+    $rowList[0]->{ID} = 1;
+    $rowList[0]->{STAGE} = $stage;
+    $rowList[0]->{COORD_MASK} = 0;
+
+    #    print "$stage\n";
     # Call the PStamp code to find the images that contain the target on the given MJD in the specified filter.
-    my @images = locate_images($ipprc,$dbname,"bycoord",$stage,
-			       undef,undef,undef,$option_mask,$need_magic,
-			       $ra,$dec,$mjd_min,$mjd_max,$filter . ".00000",undef,$verbose);  
+    my @images = locate_images($ipprc,$imagedb,
+			        \@rowList,
+			       "bycoord",$stage,
+			       undef,undef,undef,
+			       $option_mask,$need_magic,
+			       # $ra,$dec,
+			       $mjd_min,$mjd_max,$filter . ".00000",undef,$verbose);  
 
     my %image_info  = ();
@@ -270,7 +317,5 @@
 	    }
 	    elsif ($stage eq 'stack') {
-		# Stacks hide the exposure name very well, so I'm
-		# choosing the stack_id as the FPA_ID to match. This
-		# probably needs to be approved somehow.
+		# Stacks hide the exposure name very well, so we can only match against stage_id
 		if (${ $j }{stage_id} ne $FPA_ID) {
 		    next;
@@ -285,8 +330,43 @@
 	    }
 	    # Debug prints of all the components of this image
-  	    foreach my $k (keys %{ $j }) {
- 		print "$i $j $k ${ $j }{$k}\n";
- 	    }
-	    
+#   	    foreach my $k (keys %{ $j }) {
+# 		if ($k eq 'row_index') {
+# 		    print "$i $j $k @{${ $j }{$k} }\n";
+# 		}
+#  		print "$i $j $k ${ $j }{$k}\n";
+#  	    }
+
+	    # Check for existance of the images. Drawn mostly from pstampparse.pl
+	    my $run_state = ${ $j }{state};
+	    my $data_state = ${ $j }{data_state};
+	    $data_state = $run_state if $stage eq 'stack';
+	    my $fault = 0;
+	    if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
+		($run_state eq 'drop') or 
+		($run_state eq 'error_cleaned') or 
+		($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
+		# image is gone and it's not coming back
+		$fault = $PSTAMP_GONE;
+	    }
+	    elsif  (($data_state ne 'full') or ($need_magic and (${ $j }{magicked} < 0))) {
+		if (($stage eq 'stack')||($stage eq 'diff')) {
+		    # updating stacks and diffs isn't implemented
+		    $fault = $PSTAMP_NOT_IMPLEMENTED;
+		}
+		if ($stage eq 'chip') {
+		    my $burntool_state = ${ $j }{burntool_state};
+		    if ($burntool_state and (abs($burntool_state) < 14)) {
+			$fault = $PSTAMP_NOT_AVAILABLE;
+		    }
+		}
+		
+		if ($fault == 0) {
+		    # This bombs us out to dqueryparse, which will then flag a job for this run to be updated.
+		    my_die_for_update($data_state,$query{HEADER}{STAGE}[0],
+				      ${ $j }{stage_id},${ $j }{class_id} || ${ $j }{skycell_id},
+				      $need_magic,$imagedb,$PSTAMP_NOT_AVAILABLE);
+		}
+	    }
+
 	    # This image matches, so we want to save the information into our output structure
 	    $image_info{ROWNUM} = $index;
@@ -295,4 +375,5 @@
 	    $image_info{MASK}   = ${ $j }{mask};
 	    $image_info{WEIGHT} = ${ $j }{weight};
+	    $image_info{ERROR}  = $fault;
 	    $image_info{SKY_COORDINATES} = "$ra $dec";
 	    # To do sky->image coordinate transformations, we need to use the cmf/smf file. If 
@@ -405,4 +486,5 @@
     my $obscode = shift;
     my $rownum_ref = shift;
+    my $out_err_ref = shift;
     my $psphot_Npix_ref = shift;
     my $psphot_Qfact_ref = shift;
@@ -413,5 +495,7 @@
     my $columns = [
 	# matching rownum from detectability original request
-        { name => 'ROWNUM',   type => '20A', writetype => TSTRING }, 
+        { name => 'ROWNUM',   type => 'V', writetype => TULONG }, 
+	# any errors that occurred during processing
+        { name => 'ERROR_CODE',   type => 'V', writetype => TULONG }, 
         # number of pixels used in hypothetical PSF for the query detection
         { name => 'DETECT_N', type => 'V',   writetype => TULONG },
@@ -455,4 +539,5 @@
     for (my $i = 0; $i < $numRows; $i++) {
 	push @{$colData{'ROWNUM'}},      ${ $rownum_ref }[$i];
+	push @{$colData{'ERROR_CODE'}},  ${ $out_err_ref }[$i];
 	push @{$colData{'DETECT_N'}},    ${ $psphot_Npix_ref }[$i];
 	push @{$colData{'DETECT_F'}},    ${ $psphot_Qfact_ref }[$i];
@@ -529,2 +614,16 @@
 
 }
+
+sub my_die_for_update {
+    my $state = shift;
+    my $stage = shift;
+    my $stage_id = shift;
+    my $component = shift;
+    my $need_magic = shift;
+    my $imagedb = shift;
+    my $exit_code = shift;
+
+    print "$state $stage $stage_id $component $need_magic $imagedb\n";
+    print STDERR "$state $stage $stage_id $component $need_magic $imagedb\n";
+    exit($exit_code);
+}
Index: /branches/pap/pstamp/scripts/dquery_finish.pl
===================================================================
--- /branches/pap/pstamp/scripts/dquery_finish.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/dquery_finish.pl	(revision 28003)
@@ -20,5 +20,5 @@
 use PS::IPP::Config qw( :standard );
 
-my ( $req_id, $req_name, $req_file, $product, $out_dir, $dbname, $dbserver, $verbose, $save_temps );
+my ( $req_id, $req_name, $req_file, $product, $outdir, $dbname, $dbserver, $verbose, $save_temps );
 
 GetOptions(
@@ -27,5 +27,5 @@
            'req_file=s' => \$req_file,
            'product=s'  => \$product,
-           'out_dir=s'  => \$out_dir,
+           'outdir=s'   => \$outdir,
 	   'dbname=s'   => \$dbname,
 	   'dbserver=s' => \$dbserver,
@@ -41,5 +41,5 @@
 $err .= "--req_name is required\n" if !$req_name;
 $err .= "--product is required\n" if !$product;
-$err .= "--out_dir is required\n" if !$out_dir;
+$err .= "--outdir is required\n" if !$outdir;
 
 die "$err" if $err;
@@ -76,16 +76,16 @@
     die "product directory does not exist $prod_dir";
 }
-my $out_dir = "$prod_dir/$req_name";
+my $outdir = "$prod_dir/$req_name";
 }
-if (! -e $out_dir ) {
+if (! -e $outdir ) {
     # something must have gone wrong at the parse stage
-    print STDERR "output fileset directory $out_dir does not exist\n" if $verbose;
-    if (! mkdir $out_dir ) {
+    print STDERR "output fileset directory $outdir does not exist\n" if $verbose;
+    if (! mkdir $outdir ) {
         stop_request($req_id, $PS_EXIT_SYS_ERROR, $verbose);
-        die "cannot create output directory $out_dir";
+        die "cannot create output directory $outdir";
     }
-} elsif (! -d $out_dir) {
+} elsif (! -d $outdir) {
     stop_request($req_id, $PS_EXIT_SYS_ERROR, $verbose);
-    die "output fileset directory $out_dir exists but is not a directory";
+    die "output fileset directory $outdir exists but is not a directory";
 }
 
@@ -118,13 +118,20 @@
 
 # XXX: have the jobs produce the reglist as with postage stamp requests
-my ($REGLIST, $reg_list) = tempfile("$out_dir/reqlist.XXXX", UNLINK => !$save_temps);
+my ($REGLIST, $reg_list) = tempfile("$outdir/reqlist.XXXX", UNLINK => !$save_temps);
+
 foreach my $job (@jobs) {
     my $job_id = $job->{job_id};
     my $response_file = "response${job_id}.fits";
-    my $response_path = "$out_dir/$response_file";
+    my $response_path = "$outdir/$response_file";
 
     if (-e $response_path) {
         # the job generated a response file put it into the Data Store
         print $REGLIST "$response_file|||table|\n";
+
+	# do the same if we have an error file.  Should the parse data be uploaded as well?
+	my $err_file = "parse_error.txt";
+	if (-e "$outdir/$err_file") {
+	    print $REGLIST "$err_file|||text|\n";
+	}
     } else  {
         print STDERR "detect_query response file for job $job_id not found\n" if $verbose;
@@ -136,6 +143,7 @@
 if (-s $reg_list) {
     my $command = "$dsreg --add $req_name --product $product --list $reg_list";
-    $command .= " --copy --datapath $out_dir";
+    $command .= " --copy --datapath $outdir";
     $command .= " --type MOPS_DETECTABILITY_RESPONSE";
+    $command .= " --ps0 $req_id";
     $command .= " --dbname $dbname" if $dbname;
 
@@ -158,6 +166,6 @@
     my $verbose = shift;
     
-    my $command = "$pstamptool -updatereq -req_id $req_id -state stop";
-    $command   .= " -fault $fault" if $fault;
+    my $command = "$pstamptool -updatereq -req_id $req_id -set_state stop";
+    $command   .= " -set_fault $fault" if $fault;
     $command   .= " -dbname $dbname" if $dbname;
     $command   .= " -dbserver $dbserver" if $dbserver;
Index: /branches/pap/pstamp/scripts/dqueryparse.pl
===================================================================
--- /branches/pap/pstamp/scripts/dqueryparse.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/dqueryparse.pl	(revision 28003)
@@ -2,16 +2,15 @@
 #
 # parse a MOPS_DETCTABILITY_QUERY table and create a results file
-#
-# Note: this file is currently only a placeholder which creates a fake response file
-# and adds a completed job to the database
 #
 
 use strict;
 use warnings;
-
+use Carp;
 use Getopt::Long qw( GetOptions );
 use Pod::Usage qw( pod2usage );
 use IPC::Cmd 0.36 qw( can_run run );
 
+use PS::IPP::PStamp::RequestFile qw( :standard );
+use PS::IPP::PStamp::Job qw( :standard );
 use PS::IPP::Config qw($PS_EXIT_SUCCESS
 		       $PS_EXIT_UNKNOWN_ERROR
@@ -26,6 +25,7 @@
 		       );
 
-my ($req_file, $req_id, $out_dir, $product, $mode, $dbname, $dbserver, $verbose, $save_temps);
-
+my ($no_update, $imagedb, $label);
+my ($req_file, $req_id, $outdir, $product, $mode, $dbname, $dbserver, $verbose, $save_temps);
+my ($job_id,$rownum); # stuff from the post-update world
 #
 # parse args
@@ -35,5 +35,8 @@
         'file=s'          =>      \$req_file,
         'req_id=s'        =>      \$req_id,
-        'out_dir=s'       =>      \$out_dir,
+        'job_id=s'        =>      \$job_id,
+        'rownum=s'        =>      \$rownum,
+        'outdir=s'       =>      \$outdir,
+        'label=s'         =>      \$label,
         'product=s'       =>      \$product,
         'mode=s'          =>      \$mode,
@@ -44,25 +47,16 @@
 ) or pod2usage(2);
 
-my $err = "";
-
-if (!$req_file) {
-    $err .= "--file is required\n";
-}
-if (!$req_id) {
-    $err .= "--req_id is required\n";
-}
-if (!$out_dir) {
-    $err .="--out_dir is required\n";
-}
-if (!$product) {
-    $err .="--product is required\n";
-}
-
-
-die $err if ($err);
-
+die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "queue_job");
+die "--file or --job_id is required" if !$req_file;
+
+if ($mode ne "list_uri") {
+    die "req_id is required" if !$req_id;
+    die "outdir is required" if !$outdir;
+    die "product is required" if !$product;
+}
 my $missing_tools;
 my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools =1);
-my $fakedresponse = can_run('fakedresponse.pl') or (warn "Can't find fakedresponse.pl" and $missing_tools =1);
+my $detectresponse = can_run('detectability_respond.pl') or 
+    (warn "Can't find detectability_respond.pl" and $missing_tools = 1);
 my $fields = can_run('fields') or (warn "Can't find fields" and $missing_tools =1);
 
@@ -77,6 +71,21 @@
 }
 
+# just deal with these arguments once and for all
+$pstamptool .= " -dbname $dbname" if $dbname;
+$pstamptool .= " -dbserver $dbserver" if $dbserver;
+$detectresponse .= " --dbname $dbname" if $dbname;
+
+$no_update = 1 if $mode eq "list_job";
+
+# Unless we're running as a job, write the parse arguments in case we need to rerun this parsing.
+if (!$job_id) {
+    my $argslist = "$outdir/parse.args";
+    open ARGSLIST, ">$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
+    print ARGSLIST "--label $label --mode $mode --req_id $req_id --product $product --outdir $outdir --file $req_file\n";
+    close ARGSLIST;
+}
+
 # get the query id and check the extname and version from the header
-my $fields_output;
+my $fields_output; 
 {
     my $command = "echo $req_file | $fields -x 0 EXTNAME EXTVER QUERY_ID";
@@ -84,41 +93,29 @@
         run(command => $command, verbose => $verbose);
     
-#   fields doesn't return zero when it succeeds
-#    unless ($success) {
-#        print STDERR @$stderr_buf;
-#    }
     $fields_output = join "", @$stdout_buf;
 }
 my (undef, $extname, $extver, $req_name) = split " ", $fields_output;
 
-die "$req_file is missing one of EXTNAME EXTVER or QUERY_ID" 
+my_die("$req_file is missing one of EXTNAME EXTVER or QUERY_ID", $PS_EXIT_PROG_ERROR)
     if !(defined($extname) and defined($extver) and defined($req_name));
-
-die "$req_file has EXTNAME $extname not MOPS_DETECTABILITY_QUERY table"
-                if $extname ne         "MOPS_DETECTABILITY_QUERY";
-die "$req_file is version $extver expecting 1" if $extver ne 1;
-
-if (0) {
-$out_dir .= "/$req_name";
-}
-if (! -e $out_dir ) {
-    mkdir $out_dir or die "cannot create output directory $out_dir";
-} elsif (! -d $out_dir ) {
-    die "output fileset directory $out_dir exists but is not a directory";
-}
-
-#
-# XXX Eventually we will parse the file here, to look up the list of input images to be processed
-# and queue a job for each image.
-# The request file will be one of the arguments. Each job will look at all rows and create entries
-# in the response file the coordinates that overlap the image.
-#
-# In the meantime we don't parse the file here, pass it to the program fakedresponse.
-# It creates a response file with a line for each row in the request file
-
-my $response_file = "$out_dir/response.fits";
+my_die("$req_file has EXTNAME $extname not MOPS_DETECTABILITY_QUERY table", $PS_EXIT_PROG_ERROR)
+    if $extname ne "MOPS_DETECTABILITY_QUERY";
+my_die("$req_file is version $extver expecting 1", $PS_EXIT_PROG_ERROR)
+    if $extver ne 1;
+
+# Set up the workdir for this query.
+if (! -e $outdir ) {
+    mkdir $outdir or my_die("cannot create output directory $outdir", $PS_EXIT_PROG_ERROR);
+} elsif (! -d $outdir ) {
+    my_die ("output fileset directory $outdir exists but is not a directory", $PS_EXIT_PROG_ERROR);
+}
+
+
+# Pass along the request file to the response generator.
+my $response_file = "$outdir/${req_name}.dresponse.${req_id}.fits";
 my $fault;
+my $data_to_update = '';
 {
-    my $command = "$fakedresponse --input $req_file --output $response_file --workdir $out_dir";
+    my $command = "$detectresponse --input $req_file --output $response_file --workdir $outdir";
     $command .= " --save-temps" if $save_temps;
     $command .= " --verbose" if $verbose;
@@ -127,26 +124,28 @@
         run(command => $command, verbose => $verbose);
     unless ($success) {
-        warn("Unable to perform $command error code: $error_code");
-    }
+        warn("Warn! Unable to perform $command error code: $error_code");
+    }
+    # Use the fault code to see if we can regenerate the missing data.
     $fault = $error_code >> 8;
-}
-
-my $job_id;
+    if ($fault == $PSTAMP_NOT_AVAILABLE) {
+	$data_to_update = (split /\n/, (join "", @$stdout_buf))[-1];	
+    }	
+}
+
 my $result;
-{
-    my $command = "$pstamptool -addjob -req_id $req_id -outputBase $out_dir"; 
-    $command .= " -job_type detect_query -state stop -fault $fault";
+# If we returned correctly with a valid response file, get a job ID
+# for the completed work, and move the response to a standardized name.
+if ($fault == 0) {
+    my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir"; 
+    $command .= " -job_type detect_query -state stop -fault 0";
     $command .= " -rownum 1";
-    $command .= " -dbname $dbname" if $dbname;
-    $command .= " -dbserver $dbserver" if $dbserver;
-
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-        run(command => $command, verbose => $verbose);
-
+
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
     if ($success) {
         $job_id = join "", @$stdout_buf;
         chomp $job_id;
         if ($job_id && -e $response_file) {
-            rename $response_file, "$out_dir/response${job_id}.fits";
+            rename $response_file, "$outdir/response${job_id}.fits";
         }
         $result = 0;
@@ -156,18 +155,95 @@
     }
 }
-
-
+else {
+    # Failed to run correctly, which means that we need to queue a job and flag data for updating.
+    # Get the dependency id for the data we're requesting be updated.
+    my $dep_id = queue_update_run($req_id,$job_id,$outdir,$label,$data_to_update);
+
+    # Link this request to a job and link that job to any dependency
+    my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir"; 
+    $command .= " -job_type detect_query -state run -fault 0";
+    $command .= " -rownum 1";
+    $command .= " -dep_id $dep_id" if $dep_id;
+
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
+
+    if ($success) {
+        $job_id = join "", @$stdout_buf;
+        chomp $job_id;
+        if ($job_id && -e $response_file) {
+	    # We shouldn't have a response file at this stage.
+            rename $response_file, "$outdir/response${job_id}.fits";
+        }
+        $result = 0;
+    } else {
+        warn("Unable to perform $command error code: $error_code");
+        $result = $error_code >> 8;
+    }
+}
+
+# This does not set the request state to stop.  That will happen with the request_finish.pl script, 
+# which will notice that we've inserted the stopped job and decide we're finished. Easy enough.
 {
-    my $command = "$pstamptool -updatereq -req_id $req_id -name $req_name -outProduct $product";
-    $command .= " -fault $result" if $result;
-    $command .= " -dbname $dbname" if $dbname;
-    $command .= " -dbserver $dbserver" if $dbserver;
+    my $command = "$pstamptool -updatereq -req_id $req_id -set_name $req_name -set_outProduct $product";
+    $command .= " -set_fault $result" if $result;
 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
         run(command => $command, verbose => $verbose);
     unless ($success) {
-        die "$command failed";
+        my_die("$command failed",$PS_EXIT_UNKNOWN_ERROR);
     }
 }
  
 exit 0;
+
+
+# If we have to queue an update run, do so and create a new dependent
+sub queue_update_run {
+    my ($req_id, $job_id, $outdir, $label, $data_to_update) = @_;
+
+    my ($state, $stage, $stage_id, $component, $need_magic, $imagedb) = split /\s+/, $data_to_update;
+    
+    if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) {
+	# We should have received one of these states, so if not, signal that we have a problem.
+	my_die("$stage $stage_id is in unexpected state $state", $PS_EXIT_PROG_ERROR);
+    }
+    my $dep_id;
+    my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb -component $component ";
+    $command .= " -outdir $outdir";
+    $command .= " -need_magic" if $need_magic;
+
+    my $rlabel = "dq_ud_" . $label if $label;
+    $command .= " -rlabel $rlabel" if $rlabel;
+
+    if (!$no_update) {
+	my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	    run(command => $command, verbose => $verbose);
+	unless ($success) {
+	    my_die("$command failed", $PS_EXIT_UNKNOWN_ERROR);
+	}
+	my $output = join "", @$stdout_buf;
+	chomp $output;
+	$dep_id = $output;
+
+	my_die("pstamptool -getdependent returned invalid dep_id", $PS_EXIT_PROG_ERROR) if !$dep_id;
+    } 
+    else {
+	print STDERR "skipping $command\n";
+	$dep_id = 42;
+    }
+
+    return($dep_id);
+}
+	
+    
+
+sub my_die {
+    my $msg = shift;
+    my $fault = shift;
+
+    carp $msg;
+
+    # we don't fault the request here pstamp_parser_run.pl handles that if necessary
+    exit $fault;
+}
Index: /branches/pap/pstamp/scripts/pstamp_checkdependent.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_checkdependent.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_checkdependent.pl	(revision 28003)
@@ -21,4 +21,9 @@
 use Carp;
 
+# XXX: put this in a module somewhere
+my $IPP_DIFF_MODE_WARP_WARP   = 1;
+my $IPP_DIFF_MODE_WARP_STACK  = 2;
+my $IPP_DIFF_MODE_STACK_WARP  = 3;
+my $IPP_DIFF_MODE_STACK_STACK = 4;
 
 my ($dep_id, $stage, $stage_id, $component, $imagedb, $rlabel, $need_magic);
@@ -30,5 +35,5 @@
     'stage_id=i'    =>  \$stage_id,
     'component=s'   =>  \$component,
-    'imagedb=s'     =>  \$imagedb,      # dbname for images
+    'imagedb=s'     =>  \$imagedb,      # dbname for images.
     'rlabel=s'      =>  \$rlabel,
     'need_magic'    =>  \$need_magic,
@@ -48,4 +53,5 @@
 my $warptool = can_run('warptool') or (warn "Can't find warptool" and $missing_tools = 1);
 my $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1);
+my $stacktool = can_run('stacktool') or (warn "Can't find stacktool" and $missing_tools = 1);
 my $magicdstool = can_run('magicdstool') or (warn "Can't find magicdstool" and $missing_tools = 1);
 my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools = 1);
@@ -55,9 +61,10 @@
 }
 
+# Append imagedb to the ippTools
 $chiptool    .= " -dbname $imagedb";
 $warptool    .= " -dbname $imagedb";
 $difftool    .= " -dbname $imagedb";
+$stacktool   .= " -dbname $imagedb";
 $magicdstool .= " -dbname $imagedb";
-
 
 my $ipprc = PS::IPP::Config->new();
@@ -66,5 +73,4 @@
     $dbserver =  metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
 }
-
 
 
@@ -86,5 +92,5 @@
 } else {
     if ($stage eq "chip") {
-        $cmd = "$chiptool -processedimfile -chip_id $stage_id -class_id $component";
+        $cmd = "$chiptool -processedimfile -allfiles -chip_id $stage_id -class_id $component";
     } elsif ($stage eq "warp") {
         $cmd = "$warptool -warped -warp_id $stage_id -skycell_id $component";
@@ -96,17 +102,24 @@
 }
 
-my $components = runToolAndParse($cmd, $verbose);
-
-my $n = scalar @$components;
-my_die("Unexpected number of components found $n", $PS_EXIT_PROG_ERROR) if ($n != 1);
+my $it = runToolAndParseExpectOne($cmd, $verbose);
+
+my_die("no components found", $PS_EXIT_PROG_ERROR) if ( !$it);
 
 # Got "it"
-my $it = $components->[0];
-
+
+my $magic_ok = 0;
+if ($stage eq 'diff') {
+    if ($it->{diff_mode} == $IPP_DIFF_MODE_STACK_STACK) {
+        # stack stack diffs don't need magic, but since the warps need to have the chips destreaked
+        # in order to be processed se set need_magic in the database for all runs
+        # Now the diffs themselves don't need to be destreaked so
+        $magic_ok = 1;
+    }
+}
 my $status = 0;
 if (($it->{state} eq 'full') or ($it->{state} eq 'update') and ($whole_run or ($it->{data_state} eq 'full'))
-        and (!$need_magic or $it->{magicked} > 0)) {
-
-    # This Dependency is satisfied. all done
+        and (!$need_magic or $magic_ok or $it->{magicked} > 0)) {
+
+    # This Dependency is satisfied. All done!
     my $command = "$pstamptool -updatedependent -set_state full -dep_id $dep_id";
     $command .= " -dbname $dbname" if $dbname;
@@ -125,4 +138,6 @@
         ($whole_run or ($it->{data_state} eq 'cleaned'))) {
 
+    # Update has not been queued for this component yet.  
+
     # XXX: if $whole_run this is going to repeatedly call -setimfiletoupdate. This will be a no-op
     # but is wasteful.
@@ -130,6 +145,5 @@
     # need to queue the updates
     if ($stage eq 'chip') {
-        # queue_update_chip takes an array so that queue_update_warp can pass a set of
-        # chips to it
+        # queue_update_chip takes an array so that queue_update_warp can pass it set of chips
         my $chips = [$it];
         $status = queue_update_chip($it->{chip_id}, $whole_run, $chips, $rlabel, $need_magic);
@@ -142,11 +156,30 @@
     }
 } else {
+    # update for this component has been queued by hasn't completed yet or the state is an error state
+    # XXX: in this state we aren't checking the dependents anymore. If something goes wrong this
+    # will never complete. Consider calling the 'queue_update' functions again just to check. They are relatively cheap
+
+
     print "${stage}Run $stage_id state is $it->{state} $component data_state is $it->{data_state}\n";
 
     # detect states that cannot be updated and update the job state
-    # XXX: we should be more assertive here and check for the specific states where we can continue
+    # XXX: Perhaps I should be more assertive here and check for the specific states that we know
+    # that we can continue.
+
     my $state = $it->{state};
     my $job_fault = 0;
-    if (($state =~ /scrub/) or ($state =~ /purge/)) {
+
+    # temporary hack to deal with data with old burntool tables. This check is now done by pstampparse.pl
+    # so runs in this state should not get queued
+    if ($stage eq 'chip') {
+        my $burntool_state = $it->{burntool_state};
+        if ($burntool_state and (abs($burntool_state) < 14)) {
+            print STDERR "chip $it->{chip_id} $it->{class_id} has burntool_state $burntool_state. Not avaiable.\n";
+            $job_fault = $PSTAMP_NOT_AVAILABLE;
+        }
+    }
+    if ($state eq 'error_cleaned') {
+        $job_fault = $PSTAMP_NOT_AVAILABLE;
+    } elsif (($state =~ /scrub/) or ($state =~ /purge/)) {
         # jobs must have changed state since depenency was made
         print STDERR "Dependency cannot be satisfied\n";
@@ -156,4 +189,8 @@
         my_die ("Unexpected state for ${stage}Run $stage_id $state", $PS_EXIT_PROG_ERROR);
     }
+    if (!$job_fault and ($stage eq 'chip')) {
+        # chip processing is done, start destreaking.
+        $job_fault = queue_update_magicDSRun($stage, $stage_id, $rlabel, $need_magic, $it->{raw_magicked}, $it->{dsRun_state});
+    }
     if ($job_fault) {
         faultJobs($state, $stage, $stage_id, $job_fault);
@@ -171,4 +208,5 @@
     my $need_magic = shift; 
 
+
     my $dsRun_state;
     my $raw_all_magicked = 1; # this gets cleared if any of the inputs aren't destreaked
@@ -178,5 +216,7 @@
             $raw_all_magicked &= ($chip->{raw_magicked} > 0);
 
-            if ($chip->{data_state} ne 'update') {
+            if ($chip->{state} =~ /error/) {
+                faultJobs('stop', undef, undef, $PSTAMP_GONE);
+            } elsif (($chip->{data_state} ne 'update') and ($chip->{data_state} ne 'full')) {
                 my $command = "$chiptool -setimfiletoupdate -chip_id $chip_id -class_id $chip->{class_id}";
                 $command .= " -set_label $rlabel" if $rlabel;
@@ -213,7 +253,364 @@
     }
 
+    my $status = queue_update_magicDSRun('chip', $chip_id, $rlabel, $need_magic, $raw_all_magicked, $dsRun_state);
+
+    return $status;
+}
+
+sub queue_update_warp {
+    # check status of input chips. If state is not updatable set error code for job
+
+    # if chipProcessedImfile.state is cleaned call queue_update_chip
+
+    # need to code warptool -setskyfiletoupdate
+    my $metadata = shift;
+    my $whole_run = shift;  # if true queue entire run for update
+    my $rlabel = shift;     # if defined a new label for the chipRun
+    my $need_magic = shift; 
+
+    my $raw_all_magicked = 1; # this gets cleared if any of the inputs aren't destreaked
+
+    my $warp_id = $metadata->{warp_id};
+    my $state = $metadata->{state};
+    if ($state =~ /error/) {
+        print STDERR "warpRun $warp_id has state $state faulting jobs\n";
+        faultJobs('stop', undef, undef, $PSTAMP_GONE);
+        exit 0;
+    }
+
+    if (!$whole_run) {
+        my $skycell = $metadata;
+        my $skycell_id = $skycell->{skycell_id};
+
+        my $command = "$warptool -scmap -warp_id $warp_id -skycell_id $skycell_id";
+        my $data = runToolAndParse($command, $verbose);
+        my_die("failed to find warpSkyCelllMap for warpRun $warp_id skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR)
+            if !$data or scalar @$data == 0;
+
+        my $chips_ready = 1;
+        my @chipsToUpdate;
+        my $chip_id;
+        foreach my $chip (@$data) {
+            $chip_id = $chip->{chip_id};
+            if (($chip->{data_state} ne 'full') or ($need_magic and ($chip->{magicked} <= 0))) {
+                $chips_ready = 0;
+                push @chipsToUpdate, $chip;
+            } else {
+                # this chip is good to go
+            }
+        }
+
+        if ($chips_ready) {
+            # the reason we defer setting the warp to update is so that we can handle error conditions at previous
+            # stages more easily.
+            my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id -skycell_id $skycell->{skycell_id}";
+            $command .= " -set_label $rlabel" if $rlabel;
+
+            if (!$no_update) {
+                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                            run(command => $command, verbose => $verbose);
+                unless ($success) {
+                    my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
+                }
+            } else {
+                print "skipping $command\n";
+            }
+        } elsif (scalar @chipsToUpdate > 0) {
+            return queue_update_chip($chip_id, 0, \@chipsToUpdate, $rlabel, $need_magic);
+        }
+    } else {
+        my $warpRun = $metadata;
+        my $command = "$chiptool -listrun -chip_id $warpRun->{chip_id}";
+        my $data = runToolAndParse($command, $verbose);
+        my_die("failed to find chipRun $warpRun->{chip_id} for warpRun $warp_id", $PS_EXIT_UNKNOWN_ERROR)
+            if !$data or scalar @$data != 1;
+
+        my $chipRun = $data->[0];
+
+        my $chipRunState = $chipRun->{state};
+        if (($chipRunState =~ /purge/) or ($chipRunState =~ /scrub/)) {
+            print STDERR "warpRun $warp_id depends on chipRun $chipRun->{chip_id} which is in state $chipRunState\n";
+            faultJobs('stop', 'warp', $warp_id, $PSTAMP_GONE);
+            return 0;
+        }
+        my $warpRunState = $warpRun->{state};
+        if (($chipRunState eq 'full') and (! $need_magic or ($chipRun->{magicked} > 0)) and ($warpRunState eq 'cleaned')) {
+            # The inputs and outputs are ready. Queue the warpRun for update.
+
+            # providing no -skycell_id arguments changes all skyfiles with data_state = 'cleaned' to 'update'
+            my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id";
+            $command .= " -set_label $rlabel" if $rlabel;
+
+            if (!$no_update) {
+                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                            run(command => $command, verbose => $verbose);
+                unless ($success) {
+                    my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
+                }
+            } else {
+                print "skipping $command\n";
+            }
+        } elsif ($chipRunState eq 'cleaned' or 
+            (($chipRun->{state} eq 'full') and ($need_magic and ($chipRun->{magicked} < 0) and ($chipRun->{dsRun_state} ne 'new')))) {
+            my $data = [$chipRun];
+            return queue_update_chip($chipRun->{chip_id}, 1, $data, $rlabel, $need_magic);
+        }
+    }
+
+    # return value may be the return status of script so zero is good
+    return 0;
+}
+sub queue_update_diff {
+    my $metadata = shift;
+    my $whole_run = shift;  # if true queue entire run for update
+    my $rlabel = shift;     # if defined a new label for the chipRun
+    my $need_magic = shift; 
+
+    my $diff_id   = $metadata->{diff_id};
+    my $diff_mode = $metadata->{diff_mode};
+    if (!$whole_run) {
+        my $skycell = $metadata;
+        my $skycell_id = $skycell->{skycell_id};
+
+        if ($diff_mode == $IPP_DIFF_MODE_WARP_STACK ) {
+            # check the state of the template stack
+            my $command = "$stacktool -sumskyfile -stack_id $skycell->{stack2}";
+            my $stack = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack2}", $PS_EXIT_UNKNOWN_ERROR) if !$stack;
+
+            if ($stack->{state} ne 'full') {
+                print STDERR "template stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
+                # this faults all jobs depending on this dep_id
+                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
+                return $PSTAMP_GONE;
+            }
+
+            # now check the warp
+            $command = "$warptool -warped -warp_id $skycell->{warp1} -skycell_id $skycell_id";
+            my $warp = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find warpSkyfile for warpRun $skycell->{warp1} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp;
+
+            if ($warp->{data_state} ne 'full') {
+                return queue_update_warp($warp, 0, $rlabel, $need_magic);
+            }
+            # warps are ready fall through and queue the diff update
+        } elsif ($diff_mode eq $IPP_DIFF_MODE_WARP_WARP) {
+            my $command = "$warptool -warped -warp_id $skycell->{warp1} -skycell_id $skycell_id";
+            my $warp1 = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find warpSkyfile for warpRun $skycell->{warp1} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp1;
+
+            my $warps_ready = 1;
+            my $status = 0;
+            if ($warp1->{data_state} ne 'full') {
+                $warps_ready = 0;
+                $status = queue_update_warp($warp1, 0, $rlabel, $need_magic);
+                if ($status) {
+                    return $status;
+                }
+            }
+            $command = "$warptool -warped -warp_id $skycell->{warp2} -skycell_id $skycell_id";
+            my $warp2 = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find warpSkyfile for warpRun $skycell->{warp2} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp2;
+
+            if ($warp2->{data_state} ne 'full') {
+                $warps_ready = 0;
+                $status = queue_update_warp($warp2, 0, $rlabel, $need_magic);
+            }
+
+            if (!$warps_ready) {
+                # don't queue the diff update yet
+                return $status;
+            }
+
+        } elsif ($diff_mode == $IPP_DIFF_MODE_STACK_STACK ) {
+            # check the state of the input stack
+            my $command = "$stacktool -sumskyfile -stack_id $skycell->{stack2}";
+            my $stack1 = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack2}", $PS_EXIT_UNKNOWN_ERROR) if !$stack1;
+
+            if ($stack1->{state} ne 'full') {
+                print STDERR "input stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
+                # this faults all jobs depending on this dep_id
+                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
+                return $PSTAMP_GONE;
+            }
+            # check the state of the template stack
+            $command = "$stacktool -sumskyfile -stack_id $skycell->{stack2}";
+            my $stack2 = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack2}", $PS_EXIT_UNKNOWN_ERROR) if !$stack2;
+
+            if ($stack2->{state} ne 'full') {
+                print STDERR "template stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
+                # this faults all jobs depending on this dep_id
+                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
+                return $PSTAMP_GONE;
+            }
+
+            # inputs are ready fall through and queue the diff update
+        } elsif ($diff_mode == $IPP_DIFF_MODE_STACK_WARP ) {
+            # check the state of the input stack
+            my $command = "$stacktool -sumskyfile -stack_id $skycell->{stack1}";
+            my $stack = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack1}", $PS_EXIT_UNKNOWN_ERROR) if !$stack;
+
+            if ($stack->{state} ne 'full') {
+                print STDERR "input stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
+                # this faults all jobs depending on this dep_id
+                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
+                return $PSTAMP_GONE;
+            }
+
+            # now check the template warp
+            $command = "$warptool -warped -warp_id $skycell->{warp2} -skycell_id $skycell_id";
+            my $warp = runToolAndParseExpectOne($command, $verbose);
+            my_die("failed to find warpSkyfile for warpRun $skycell->{warp2} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp;
+
+            if ($warp->{data_state} ne 'full') {
+                return queue_update_warp($warp, 0, $rlabel, $need_magic);
+            }
+            # warps are ready fall through and queue the diff update
+        } else {
+            my_die("unexpected diff_mode found: $diff_mode", $PS_EXIT_PROG_ERROR);
+        }
+
+        my $command = "$difftool -setskyfiletoupdate -diff_id $diff_id -skycell_id $skycell_id";
+        $command .= " -set_label $rlabel" if $rlabel;
+
+        if (!$no_update) {
+            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                        run(command => $command, verbose => $verbose);
+            unless ($success) {
+                my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
+            }
+        } else {
+            print "skipping $command\n";
+        }
+    } else {
+        # XXX todo whole_run
+        return $PS_EXIT_PROG_ERROR;
+    }
+
+    # return value is a unix style exit status so zero is good
+    return 0;
+}
+
+
+# run a command that produces metadata output and parse the results into an array of objects
+sub runToolAndParse {
+    my $command = shift;
+    my $verbose = shift;
+
+    my ($program) = split " ", $command;
+    $program = basename($program);
+
+    print "Running $command\n" if !$verbose;
+    my $start_tool = DateTime->now->mjd;
+    # run the command and parse the output
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                run(command => $command, verbose => $verbose);
+    unless ($success) {
+        print STDERR @$stderr_buf if !$verbose;
+        return undef;
+    }
+
+    my $now = DateTime->now->mjd;
+    my $dtime_tool = (DateTime->now->mjd - $start_tool) * 86400.;
+    print "Time to run $program: $dtime_tool\n";
+
+    my $buf = join "", @$stdout_buf;
+    if (!$buf) {
+        return undef;
+    }
+
+    my $start_parse = DateTime->now->mjd;
+
+    my $mdcParser = PS::IPP::Metadata::Config->new;
+    my $results = parse_md_fast($mdcParser, $buf)
+        or my_die ("Unable to parse metadata config doc", $PS_EXIT_UNKNOWN_ERROR);
+
+    my $dtime_parse = (DateTime->now->mjd - $start_parse) * 86400.;
+    print "Time to parse results from $program: $dtime_parse\n";
+
+    return $results;
+}
+
+# run an command returning metadata where we expect 1 entry
+sub runToolAndParseExpectOne {
+    my $command = shift;
+    my $verbose = shift;
+
+    my $data = runToolAndParse($command, $verbose);
+
+    if (!$data) {
+        return undef;
+    }
+
+    my $n = scalar @$data;
+    if ($n > 1) {
+        my_die("Unexpected number of components $n returned by $command", $PS_EXIT_PROG_ERROR);
+    }
+
+    return $data->[0];
+}
+
+# splits meta data config input stream into single units to work around the pathalogically
+# slow parser. This is similar to and adapted from code in various ippScripts.
+sub parse_md_fast {
+    my $mdcParser = shift;
+    my $input = shift;
+    my $output = ();
+
+    my @whole = split /\n/, $input;
+    my @single = ();
+
+    my $n;
+    while ( ($n = @whole) > 0) {
+        my $value = shift @whole;
+        push @single, $value;
+        if ($value =~ /^\s*END\s*$/) {
+	    push @single, "\n";
+
+            my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or
+                print STDERR "Unable to parse metdata config doc" and return undef;
+            push @$output, $list->[0];
+
+            @single = ();
+        }
+    }
+    return $output;
+}
+
+sub faultJobs {
+    my ($state, $stage, $stage_id, $job_fault) = @_;
+
+    my $command = "$pstamptool -updatejob -set_state stop -set_fault $job_fault -dep_id $dep_id";
+    $command .= " -dbname $dbname" if $dbname;
+    $command .= " -dbserver $dbserver" if $dbserver;
+    if (!$no_update) {
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                    run(command => $command, verbose => $verbose);
+        unless ($success) {
+            my_die("failed to set pstampJob.fault for dep_id: $dep_id",
+                $PS_EXIT_UNKNOWN_ERROR);
+        }
+    } else {
+        print "skipping $command\n";
+    }
+}
+
+sub queue_update_magicDSRun {
+    my $stage = shift;
+    my $stage_id = shift;
+    my $rlabel  = shift;
+    my $need_magic = shift;
+    my $input_magicked = shift;
+    my $dsRun_state = shift;
+
+    # XXX: this code assumes that destreaking is handled at the chip stage
+    my_die ("queue_update_magicDSRun only works for stage chip", $PS_EXIT_PROG_ERROR) if $stage ne 'chip';
+
     # if called from queue_update_warp dsRun_state is unknown. Go find it.
     if (!$dsRun_state) {
-        my $command = "$chiptool -listrun -chip_id $chip_id";
+        my $command = "$chiptool -listrun -chip_id $stage_id";
         my $data = runToolAndParse($command, $verbose);
         my $chipRun = $data->[0];
@@ -222,5 +619,5 @@
 
     # if the input file is already magicked no need to queue destreaking for this chipRun
-    if ($need_magic and !$raw_all_magicked) {
+    if ($need_magic and !$input_magicked) {
         if ($dsRun_state eq 'cleaned') {
             my $command = "$magicdstool -updaterun -set_state new -stage $stage -stage_id $stage_id";
@@ -236,4 +633,7 @@
                 print "skipping $command\n";
             }
+        } elsif ($dsRun_state eq 'failed_revert') {
+            print "magicDSRun.state = $dsRun_state for chipRun $stage_id is in state failed_revert cannot update";
+            faultJobs('stop', undef, undef, $PSTAMP_NOT_AVAILABLE);
         } else {
             print "magicDSRun.state = $dsRun_state for chipRun $stage_id";
@@ -242,177 +642,14 @@
         }
     }
-
-    # return value may be the return status of script so zero is good
     return 0;
 }
 
-sub queue_update_warp {
-    # check status of input chips. If state is not updatable set error code for job
-
-    # if chipProcessedImfile.state is cleaned call queue_update_chip
-
-    # need to code warptool -setskyfiletoupdate
-    my $metadata = shift;
-    my $whole_run = shift;  # if true queue entire run for update
-    my $rlabel = shift;     # if defined a new label for the chipRun
-    my $need_magic = shift; 
-
-    my $raw_all_magicked = 1; # this gets cleared if any of the inputs aren't destreaked
-
-    my $warp_id = $metadata->{warp_id};
-    if (!$whole_run) {
-        my $skycell = $metadata;
-        my $skycell_id = $skycell->{skycell_id};
-
-        my $command = "$warptool -scmap -warp_id $warp_id -skycell_id $skycell_id";
-        my $data = runToolAndParse($command, $verbose);
-        my_die("failed to find warpSkyCelllMap for warpRun $warp_id skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR)
-            if !$data or scalar @$data == 0;
-
-        my $good_to_go = 1;
-        my @chipsToUpdate;
-        my $chip_id;
-        foreach my $chip (@$data) {
-            $chip_id = $chip->{chip_id};
-            if (($chip->{data_state} ne 'full') or ($need_magic and ($chip->{magicked} <= 0))) {
-                $good_to_go = 0;
-                push @chipsToUpdate, $chip;
-            } else {
-                # this chip is good to go
-            }
-        }
-
-        if ($good_to_go) {
-            my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id -skycell_id $skycell->{skycell_id}";
-            $command .= " -set_label $rlabel" if $rlabel;
-
-            if (!$no_update) {
-                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                            run(command => $command, verbose => $verbose);
-                unless ($success) {
-                    my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
-                }
-            } else {
-                print "skipping $command\n";
-            }
-        } elsif (scalar @chipsToUpdate > 0) {
-            return queue_update_chip($chip_id, 0, \@chipsToUpdate, $rlabel, $need_magic);
-        }
-    } else {
-        my $warpRun = $metadata;
-        my $command = "$chiptool -listrun -chip_id $warpRun->{chip_id}";
-        my $data = runToolAndParse($command, $verbose);
-        my_die("failed to find chipRun $warpRun->{chip_id} for warpRun $warp_id", $PS_EXIT_UNKNOWN_ERROR)
-            if !$data or scalar @$data != 1;
-
-        my $chipRun = $data->[0];
-
-        my $chipRunState = $chipRun->{state};
-        if (($chipRunState =~ /purge/) or ($chipRunState =~ /scrub/)) {
-            print STDERR "warpRun $warp_id depends on chipRun $chipRun->{chip_id} which is in state $chipRunState\n";
-            faultJobs('stop', 'warp', $warp_id, $PSTAMP_GONE);
-            return 0;
-        }
-        my $warpRunState = $warpRun->{state};
-        if (($chipRunState eq 'full') and (! $need_magic or ($chipRun->{magicked} > 0)) and ($warpRunState eq 'cleaned')) {
-            # The inputs and outputs are ready. Queue the warpRun for update.
-
-            # providing no -skycell_id arguments changes all skyfiles with data_state = 'cleaned' to 'update'
-            my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id";
-            $command .= " -set_label $rlabel" if $rlabel;
-
-            if (!$no_update) {
-                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                            run(command => $command, verbose => $verbose);
-                unless ($success) {
-                    my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
-                }
-            } else {
-                print "skipping $command\n";
-            }
-        } elsif ($chipRunState eq 'cleaned' or 
-            (($chipRun->{state} eq 'full') and ($need_magic and ($chipRun->{magicked} < 0) and ($chipRun->{dsRun_state} ne 'new')))) {
-            my $data = [$chipRun];
-            return queue_update_chip($chipRun->{chip_id}, 1, $data, $rlabel, $need_magic);
-        }
-    }
-
-    # return value may be the return status of script so zero is good
-    return 0;
-}
-sub queue_update_diff {
-    return 0;
-}
-
-
-# run a command that produces metadata output and parse the results into an array of objects
-sub runToolAndParse {
-    my $command = shift;
-    my $verbose = shift;
-
-    my ($program) = split " ", $command;
-    $program = basename($program);
-
-    print "Running $command\n" if !$verbose;
-    my $start_tool = DateTime->now->mjd;
-    # run the command and parse the output
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
-    unless ($success) {
-        print STDERR @$stderr_buf if !$verbose;
-        return undef;
-    }
-
-    my $now = DateTime->now->mjd;
-    my $dtime_tool = (DateTime->now->mjd - $start_tool) * 86400.;
-    print "Time to run $program: $dtime_tool\n";
-
-    my $buf = join "", @$stdout_buf;
-    if (!$buf) {
-        return undef;
-    }
-
-    my $start_parse = DateTime->now->mjd;
-
-    my $mdcParser = PS::IPP::Metadata::Config->new;
-    my $results = parse_md_fast($mdcParser, $buf)
-        or my_die ("Unable to parse metadata config doc", $PS_EXIT_UNKNOWN_ERROR);
-
-    my $dtime_parse = (DateTime->now->mjd - $start_parse) * 86400.;
-    print "Time to parse results from $program: $dtime_parse\n";
-
-    return $results;
-}
-
-# splits meta data config input stream into single units to work around the pathalogically
-# slow parser. This is similar to and adapted from code in various ippScripts.
-sub parse_md_fast {
-    my $mdcParser = shift;
-    my $input = shift;
-    my $output = ();
-
-    my @whole = split /\n/, $input;
-    my @single = ();
-
-    my $n;
-    while ( ($n = @whole) > 0) {
-        my $value = shift @whole;
-        push @single, $value;
-        if ($value =~ /^\s*END\s*$/) {
-	    push @single, "\n";
-
-            my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or
-                print STDERR "Unable to parse metdata config doc" and return undef;
-            push @$output, $list->[0];
-
-            @single = ();
-        }
-    }
-    return $output;
-}
-sub faultJobs {
-    my ($state, $stage, $stage_id, $job_fault) = @_;
-
-    my $command = "$pstamptool -updatejob -state stop -fault $job_fault -dep_id $dep_id";
+sub my_die
+{
+    my $msg = shift;
+    my $fault = shift;
+    carp $msg;
+
+    my $command = "$pstamptool -updatedependent -set_fault $fault -dep_id $dep_id";
     $command .= " -dbname $dbname" if $dbname;
     $command .= " -dbserver $dbserver" if $dbserver;
@@ -421,19 +658,10 @@
                     run(command => $command, verbose => $verbose);
         unless ($success) {
-            my_die("failed to set pstamJob.fault for dep_id: $dep_id",
-                $PS_EXIT_UNKNOWN_ERROR);
+            carp "$cmd failed";
         }
     } else {
         print "skipping $command\n";
     }
-}
-
-sub my_die
-{
-    my $msg = shift;
-    my $fault = shift;
-
-    carp $msg;
-
-    return $fault;
-}
+
+    exit $fault;
+}
Index: /branches/pap/pstamp/scripts/pstamp_cleanup.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_cleanup.pl	(revision 28003)
+++ /branches/pap/pstamp/scripts/pstamp_cleanup.pl	(revision 28003)
@@ -0,0 +1,201 @@
+#!/bin/env perl
+###
+### pstamp_cleanup.pl
+### delete all data associated with a postage stamp request
+###  
+### This script should probably be called request_cleanup.pl since it handles more than postage stamp requests
+###
+
+use warnings;
+use strict;
+
+use Sys::Hostname;
+use Getopt::Long qw( GetOptions );
+use File::Basename qw( basename dirname);
+use File::Copy;
+use POSIX qw( strftime );
+use Carp;
+use IPC::Cmd 0.36 qw( can_run run );
+
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::Stats;
+use PS::IPP::Metadata::List qw( parse_md_list );
+
+use PS::IPP::Config qw( :standard );
+
+my $req_id;
+my $uri;
+my $name;
+my $outdir;
+my $reqType;
+my $redirect_output;
+my $product;
+my $label;
+my $verbose;
+my $dbname;
+my $dbserver;
+my $no_update;
+
+GetOptions(
+    'req_id=s'          =>  \$req_id,
+    'name=s'            =>  \$name,
+    'outdir=s'          =>  \$outdir,
+    'reqType=s'           =>  \$reqType,
+    'product=s'         =>  \$product,
+    'uri=s'             =>  \$uri,
+    'outdir=s'          =>  \$outdir,
+    'redirect-output'   =>  \$redirect_output,
+    'verbose'           =>  \$verbose,
+    'dbname=s'          =>  \$dbname,
+    'dbserver=s'        =>  \$dbserver,
+    'no-update'         =>  \$no_update,
+);
+
+if ($verbose) {
+    my $host = hostname();
+    print "\n\n";
+    print "Starting script $0 on $host\n\n";
+}
+
+my $missing_tools;
+
+my $pstamptool  = can_run('pstamptool')  or (warn "Can't find pstamptool"  and $missing_tools = 1);
+my $dsreg = can_run('dsreg') or (warn "Can't find dsreg" and $missing_tools = 1);
+
+if ($missing_tools) {
+    warn("Can't find required tools.");
+    exit ($PS_EXIT_CONFIG_ERROR);
+}
+
+
+die("--req_id --name --product and --outdir are required") if !defined($req_id) or !defined($product) or !defined($name) or !defined $outdir;
+
+my $ipprc = PS::IPP::Config->new(); # IPP Configuration
+
+my $pstamp_workdir = metadataLookupStr($ipprc->{_siteConfig}, 'PSTAMP_WORKDIR');
+exit ($PS_EXIT_CONFIG_ERROR) unless defined $pstamp_workdir; # lookup failure outputs a message
+
+if (!$dbserver) {
+    $dbserver =  metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
+}
+
+my_die("Cleanup not yet supported for reqType: $reqType", $req_id, $PS_EXIT_UNKNOWN_ERROR)
+    if ($reqType ne "pstamp") and ($reqType ne "NULL");
+
+my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
+
+if ($product ne 'NULL' and $name ne 'NULL') {
+    my $command = "$dsreg --product $product --del $name --rm --force";
+
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
+    unless ($success) {
+        my_die("Unable to perform $command error code: $error_code", $req_id, $PS_EXIT_UNKNOWN_ERROR);
+    }
+}
+
+# now go find the workdir for this request 
+# XXX: we finally *have* to store this in the database
+$outdir = undef if $outdir eq "NULL";
+
+if ($outdir) {
+    delete_workdir($outdir);
+} else {
+    if ($uri ne 'NULL') {
+        # use the URI to find the workdir
+        $outdir = dirname($uri);
+        if (index($outdir, $pstamp_workdir) == 0) {
+            print "pstamp workdir for req_id $req_id is $outdir\n";
+            delete_workdir($outdir);
+        } else {
+            print "no outdir found for $req_id\n";
+        }
+    }
+    if (!$outdir) {
+        # gotta go look for it in the subdirectories of $pstamp_workdir
+        my $command = "find $pstamp_workdir -maxdepth 2 -type d -name $req_id";
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            my $rc = $error_code >> 8;
+            my_die("Unable to perform $command error code: $error_code", $req_id, $rc);
+        }
+        if ($stdout_buf) {
+            # for historical reasons (a bug) there may be more than one outdir
+            my @outdirs = split "\n", join "", $stdout_buf;
+            foreach $outdir (@outdirs) {
+                chomp $outdir;
+                delete_workdir($outdir);
+            }
+        } else {
+            print "no outdir found for $req_id\n";
+        }
+    }
+}
+
+
+{
+    my $command = "$pstamptool -updatereq -req_id $req_id -set_state cleaned";
+    $command   .= " -dbname $dbname" if $dbname;
+    $command   .= " -dbserver $dbserver" if $dbserver;
+    unless ($no_update) {
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            die("Unable to perform $command error code: $error_code");
+        }
+    } else {
+        print "skipping $command\n";
+    }
+}
+
+exit 0;
+
+
+sub delete_workdir {
+    my $dir = shift;
+
+    if (!-e $dir) {
+        print "outdir $dir does not exist\n";
+        return 0;
+    }
+    if (!-d $dir) {
+        print "outdir $dir is not a directory\n";
+        return 0;
+    }
+
+    my $command = "rm -r $dir";
+    unless ($no_update) {
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            my $rc = $error_code >> 8;
+            my_die("Unable to perform $command return status: $rc", $req_id, $rc);
+        }
+    } else {
+        print "skipping $command\n";
+    }
+    return 0;
+}
+
+sub my_die {
+    my $msg = shift;
+    my $req_id = shift;
+    my $fault = shift;
+
+    carp($msg);
+
+    my $command = "$pstamptool -updatereq -req_id $req_id  -set_fault $fault";
+    $command   .= " -dbname $dbname" if $dbname;
+    $command   .= " -dbserver $dbserver" if $dbserver;
+    unless ($no_update) {
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            die("Unable to perform $command error code: $error_code");
+        }
+    } else {
+        print "skipping $command\n";
+    }
+    exit $fault;
+}
Index: /branches/pap/pstamp/scripts/pstamp_dorequest.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_dorequest.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_dorequest.pl	(revision 28003)
@@ -106,5 +106,5 @@
 {
     ## TODO: what about request status
-    my $command = "$pstamptool -updatereq -req_id $request_id -state stop"; 
+    my $command = "$pstamptool -updatereq -req_id $request_id -set_state stop"; 
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
         run(command => $command, verbose => $verbosity);
Index: /branches/pap/pstamp/scripts/pstamp_finish.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_finish.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_finish.pl	(revision 28003)
@@ -25,5 +25,7 @@
 use PS::IPP::PStamp::Job qw( :standard );
 
-my ( $req_id, $req_name, $req_file, $out_dir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output);
+my %imagedb_cache;
+
+my ( $req_id, $req_name, $req_file, $outdir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output);
 
 # the char to the right of the bar may be used as a single - alias for the longer name
@@ -34,5 +36,5 @@
            'req_file=s'     => \$req_file,
            'product=s'      => \$product,
-           'out_dir=s'      => \$out_dir,
+           'outdir=s'       => \$outdir,
 	   'dbname=s'       => \$dbname,
 	   'dbserver=s'     => \$dbserver,
@@ -44,10 +46,13 @@
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
 
-die "usage: --req_id id --req_name name --req_file file --product product --out_dir output_directory [--dbname dbname --verbose]\n"
-    if !$req_id or !$req_name or !$req_file or !$product or !$out_dir;
+die "usage: --req_id id --req_name name --req_file file --product product --outdir output_directory [--dbname dbname --verbose]\n"
+    if !$req_id or !$req_name or !$req_file or !$product or !$outdir;
+
+die "outdir is NULL\n" if $outdir eq "NULL";
 
 my $ipprc = PS::IPP::Config->new(); # IPP Configuration
 if ($redirect_output) {
-    my $logDest = "$out_dir/psfinish.$req_id.log";
+    # XXX: what happens here if the directory does not exist? We check below
+    my $logDest = "$outdir/psfinish.$req_id.log";
     $ipprc->redirect_output($logDest);
 }
@@ -70,9 +75,7 @@
 
 if ($product eq "NULL") {
+    # nothing more to do
     stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
 }
-
-my $outputDataStoreRoot = metadataLookupStr($ipprc->{_siteConfig}, 'DATA_STORE_ROOT');
-exit ($PS_EXIT_CONFIG_ERROR) unless defined $outputDataStoreRoot; # lookup failure outputs a message
 
 my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
@@ -82,20 +85,20 @@
     my $fileset = $req_name;
 
-    print STDERR "product: $product  REQ_NAME: $req_name $out_dir\n" if $verbose;
-
-    if (!-e $out_dir) {
+    print STDERR "product: $product  REQ_NAME: $req_name $outdir\n" if $verbose;
+
+    if (!-e $outdir) {
         # something must have gone wrong parsing the request
-        print STDERR  "output directory $out_dir does not exist\n";
-
-        if (!mkdir $out_dir) {
-            print STDERR "cannot create output directory $out_dir";
+        print STDERR  "output directory $outdir does not exist\n";
+
+        if (!mkdir $outdir) {
+            print STDERR "cannot create output directory $outdir";
             stop_request_and_exit($req_id, $PS_EXIT_UNKNOWN_ERROR);
         }
 
 
-    } elsif (! -d $out_dir ) {
+    } elsif (! -d $outdir ) {
         # XXX TODO: fault the request so we pstamp_finish doesn't keep trying to process the
         # request
-        print STDERR "output directory $out_dir exists but is not a directory";
+        print STDERR "output directory $outdir exists but is not a directory";
         stop_request_and_exit($req_id, $PS_EXIT_UNKNOWN_ERROR);
     }
@@ -116,24 +119,24 @@
     }
 
-    # at this point we need to find out what kind of request type it is and
-    # split the processing depending on the request type
-    # the only processing required for a detectabilty query is to build the output fileset.
-
-    # the following is for a postage stamp request
-
-    my ($rlf, $reglist_name) = tempfile ("$out_dir/reglist.XXXX", UNLINK => !$save_temps);
+    # start building the list of files to be placed in the output fileset
+    my ($rlf, $reglist_name) = tempfile ("$outdir/reglist.XXXX", UNLINK => !$save_temps);
+
+    # results file
     print $rlf "results.fits|||table|\n";
-    print $rlf "results.mdc|||txt|\n";
+    # human readable representation of the results file
+    print $rlf "results.mdc|||text|\n";
 
     my $err_file = "parse_error.txt";
-    if (-e "$out_dir/$err_file" ) {
+    if (-e "$outdir/$err_file" ) {
         print $rlf "$err_file|||text|\n";
     }
 
-    my ($tdf, $table_def_name) = tempfile ("$out_dir/tabledef.XXXX", UNLINK => !$save_temps);
-
+    # The results table definition file
+    my ($tdf, $table_def_name) = tempfile ("$outdir/tabledef.XXXX", UNLINK => !$save_temps);
 
     # data for the header
     print $tdf "$req_name|$req_id|\n";
+
+    # get the list of jobs generated for this request
     my @jobs;
     {
@@ -151,10 +154,13 @@
                 print STDERR "Request $req_id produced no jobs.\n"
             }
-            # This should not happen. A fake job should be queued
+            # This should not happen. A fake job should have been entered
             stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
         } else {
+if (0) {
             my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
 
             my $jobs = parse_md_list($metadata);
+}
+            my $jobs = parse_md_fast($mdcParser, $output);
 
             @jobs = @$jobs;
@@ -163,5 +169,4 @@
 
     my $exp_info;
-    my $last_exp_id = -1;
     foreach my $job (@jobs) {
         my $job_id = $job->{job_id};
@@ -172,8 +177,7 @@
 
         if (($fault eq $PSTAMP_DUP_REQUEST) and ($req_name eq "NULL")) {
-            # this request had a duplicate request name. We can't put the results
-            # on the data store since the product name is already used
-            # maybe we could be more clever about this and choose a fileset name
-            stop_request_and_exit($req_id, $fault);
+            # this request had a duplicate request name yet the parser didn't give
+            # it an "ERROR style name.
+            stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
         }
         my ($row, $req_info, $project) = get_request_info($rows, $rownum);
@@ -188,13 +192,22 @@
         }
 
-        if ($exp_id ne $last_exp_id) {
+        my $job_params = get_job_parameters($job);
+        my $stage = "";
+        if ($job_params) {
+            $stage = $job_params->{stage};
+        }
+
+        if ($stage ne 'stack') {
             # get the metadata for the exposure (if any i.e. stack) 
             # returns an appropriate string if !$exp_id
-            $exp_info = get_exposure_info($image_db, $exp_id);
-            $last_exp_id = $exp_id;
+            $exp_info = get_exposure_info($job_params, $image_db, $exp_id);
+        } else {
+            my $filter = $job_params->{filter};
+            $filter = "0" if !$filter;
+            $exp_info = "0|0|0|$filter|0|0";
         }
 
         if (($job_type eq "stamp") || ($job_type eq "get_image") || ($job_type eq "none")) {
-            my $jreglist = "$out_dir/reglist$job_id";
+            my $jreglist = "$outdir/reglist$job_id";
             if (open JRL, "<$jreglist") {;
                 # process the reglist file to get the list of files produced by this job
@@ -213,7 +226,7 @@
                     # If not found check the PHU. If that doesn't work just set them to zero.
                     # XXX do this more cleanly
-                    my (undef, $ra_deg, $dec_deg) = split " ", `echo $out_dir/$img_name | fields -x 0 RA_DEG DEC_DEG`;
+                    my (undef, $ra_deg, $dec_deg) = split " ", `echo $outdir/$img_name | fields -x 0 RA_DEG DEC_DEG`;
                     if (!defined $ra_deg) {
-                        (undef, $ra_deg, $dec_deg) = split " ", `echo $out_dir/$img_name | fields RA_DEG DEC_DEG`;
+                        (undef, $ra_deg, $dec_deg) = split " ", `echo $outdir/$img_name | fields RA_DEG DEC_DEG`;
                     }
                     $ra_deg = 0.0 if (!$ra_deg);
@@ -246,5 +259,5 @@
     # make the results file
     {
-        my $command = "$pstamp_results --input $table_def_name --output $out_dir/results.fits";
+        my $command = "$pstamp_results --input $table_def_name --output $outdir/results.fits";
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
             run(command => $command, verbose => $verbose);
@@ -254,5 +267,5 @@
         } else {
             # dump a textual representation
-            my $command = "$pstampdump $out_dir/results.fits > $out_dir/results.mdc";
+            my $command = "$pstampdump $outdir/results.fits > $outdir/results.mdc";
             my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
                 run(command => $command, verbose => $verbose);
@@ -266,6 +279,7 @@
         # register the fileset
         my $command = "$dsreg --list $reglist_name --add $fileset --product $product --type PSRESULTS";
-        $command .= " --link --datapath $out_dir --ps0 $req_id";
-        $command .= " --dbname $dbname" if $dbname;
+        $command .= " --link --datapath $outdir --ps0 $req_id";
+# XXX: let dsreg and config handle resolving dbname and dbserver
+#        $command .= " --dbname $dbname" if $dbname;
 
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -280,5 +294,5 @@
     # set the request's state to stop
     {
-        my $command = "$pstamptool -updatereq -req_id $req_id -state stop -fault $request_fault";
+        my $command = "$pstamptool -updatereq -req_id $req_id -set_state stop -set_fault $request_fault";
         $command   .= " -dbname $dbname" if $dbname;
         $command   .= " -dbserver $dbserver" if $dbserver;
@@ -296,5 +310,5 @@
     my $fault  = shift;
 
-    my $command = "$pstamptool -updatereq -req_id $req_id -state stop -fault $fault";
+    my $command = "$pstamptool -updatereq -req_id $req_id -set_state stop -set_fault $fault";
     $command   .= " -dbname $dbname" if $dbname;
     $command   .= " -dbserver $dbserver" if $dbserver;
@@ -333,5 +347,5 @@
     $data_group = "null" if !$data_group;
 
-    # This is ugly, error prone and hard to change.
+    # XXX: This is ugly, error prone and hard to change.
     # Create a results file module and provide a list of the names (we have the data in the columns)
     my $rowinfo = "$row->{PROJECT}|$row->{JOB_TYPE}|$row->{REQ_TYPE}|$row->{IMG_TYPE}|";
@@ -344,55 +358,128 @@
 }
 
+sub get_job_parameters {
+    my $job = shift;
+    if (!$job->{outputBase}) {
+        print "get_job_parameters: $job->{job_id} has no outputBase\n";
+        return undef;
+    }
+    my $params_file = $job->{outputBase} . '.mdc';
+    if (! -e $params_file ) {
+        print "get_job_parameters: $job->{job_id} has no parameters file\n";
+        return undef;
+    }
+    open IN, "<$params_file" or die "unable to open $params_file";
+    my $data = join "", (<IN>);
+    close IN;
+    if (! $data ) {
+        print "get_job_parameters: parameters file is empty\n";
+        return undef;
+    }
+    my $metadata = $mdcParser->parse($data) or die("Unable to parse metdata config doc");
+
+    # no need to use parse_md_fast here
+    my $results = parse_md_list($metadata);
+    if (scalar @$results != 1) {
+        print STDERR "get_job_params: failed to parse_md_list\n";
+        return undef;
+    }
+    return $results->[0];
+}
+
 sub get_exposure_info {
+    my $job_params = shift;
     my $image_db= shift;
     my $exp_id = shift;
 
-    if (!$exp_id or !$image_db) {
-        # no exposure id just return zeros
-        # XXX: we could put a value in for filter, but we don't have a good place to find it
-
-        #"$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
-        return "0|0|0|0|0|0";
-    }
-
-    my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
-    if ($missing_tools) {
-        warn("Can't find required tools.");
-        exit ($PS_EXIT_CONFIG_ERROR);
-    }
-
-    my $command = "$regtool -processedexp -dbname $image_db -exp_id $exp_id";
-
-    # run the tool and parse the output
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
-    unless ($success) {
-        # not sure if we should die here
-        die "cannot get exposure information for $exp_id from image database $image_db";
-    }
-    my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
-
-    my $output = join "", @$stdout_buf;
-    if (!$output) {
-        print STDERR "no output returned from $command\n" if $verbose;
-        return undef;
-    }
-    my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
-
-    my $exposures = parse_md_list($metadata);
-    my $numExp = @$exposures;
-
-    die "unexpected number of exposures $numExp found for exp_id: $exp_id in DB: $image_db" if $numExp != 1;
+    my ($dateobs, $ra, $decl, $filter, $exp_time, $exp_name);
+
+    $dateobs  = $job_params->{dateobs};
+    $ra       = $job_params->{ra};
+    $decl     = $job_params->{decl};
+    $filter   = $job_params->{filter};
+    $exp_time = $job_params->{exp_time};
+    $exp_name = $job_params->{exp_name};
+
+    unless (defined $dateobs and defined $ra and defined $decl and defined $filter and defined $exp_time and defined $exp_name) {
+        # job params don't have all of the values that we need (most likely this is a diff stage job)
+        # go look up the exposure if we have one
+        if (!$exp_id or !$image_db) {
+            # no exposure id just return zeros
+            # XXX: we could put a value in for filter, but we don't have a good place to find it
+
+            #"$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
+            return "0|0|0|0|0|0";
+        }
+
+        my $exp;
+        # get cache of exposures for this image_db
+        my $exp_cache = $imagedb_cache{$image_db};
+        if (defined $exp_cache) {
+            $exp = $exp_cache->{$exp_id};
+        }
+
+        unless (defined $exp) {
+
+            my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
+            if ($missing_tools) {
+                warn("Can't find required tools.");
+                exit ($PS_EXIT_CONFIG_ERROR);
+            }
+
+            my $command = "$regtool -processedexp -dbname $image_db -exp_id $exp_id";
+
+            # run the tool and parse the output
+            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                        run(command => $command, verbose => $verbose);
+            unless ($success) {
+                # not sure if we should die here
+                die "cannot get exposure information for $exp_id from image database $image_db";
+            }
+            my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
+
+            my $output = join "", @$stdout_buf;
+            if (!$output) {
+                print STDERR "no output returned from $command\n" if $verbose;
+                return undef;
+            }
+if (0) {
+            my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
+
+            my $exposures = parse_md_list($metadata);
+}
+            my $exposures = parse_md_fast($mdcParser, $output);
+            my $numExp = @$exposures;
+
+            die "unexpected number of exposures $numExp found for exp_id: $exp_id in DB: $image_db" if $numExp != 1;
+
+            $exp = $exposures->[0];
+
+            unless (defined $exp_cache) {
+                my %new_exp_cache;
+                $exp_cache = \%new_exp_cache;
+                $imagedb_cache{$image_db} = $exp_cache;
+            }
+            $exp_cache->{$exp_id} = $exp;
+        } else {
+            print "found $exp_id in cache\n";
+        }
+        
+        #my $info = "$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
+        $dateobs  = $exp->{dateobs};
+        $ra       = $exp->{ra};
+        $decl     = $exp->{decl};
+        $filter   = $exp->{filter};
+        $exp_time = $exp->{exp_time};
+        $exp_name = $exp->{exp_name};
+    }
+
+    die "failed to find exp_info for $exp_id" unless (defined $dateobs and defined $ra and defined $decl and defined $filter and defined $exp_time and defined $exp_name);
     
-    my $exp = $exposures->[0];
-
-    #my $info = "$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
-
     use constant RADIANS_TO_DEGREES => 90. / atan2(1, 0);
-    my $ra_deg   = $exp->{ra} * RADIANS_TO_DEGREES;
-    my $decl_deg = $exp->{decl} * RADIANS_TO_DEGREES;
-    my $mjd_obs = dateobs_to_mjd($exp->{dateobs});
-
-    my $info = "$mjd_obs|$ra_deg|$decl_deg|$exp->{filter}|$exp->{exp_time}|$exp->{exp_name}";
+    my $ra_deg   = $ra * RADIANS_TO_DEGREES;
+    my $decl_deg = $decl * RADIANS_TO_DEGREES;
+    my $mjd_obs = dateobs_to_mjd($dateobs);
+
+    my $info = "$mjd_obs|$ra_deg|$decl_deg|$filter|$exp_time|$exp_name";
             
     return $info;
Index: /branches/pap/pstamp/scripts/pstamp_get_image_job.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_get_image_job.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_get_image_job.pl	(revision 28003)
@@ -87,5 +87,5 @@
 }
 
-my $out_dir = dirname($output_base);
+my $outdir = dirname($output_base);
 my $prefix = basename($output_base) . "_";
 my $results_file = $output_base . ".bundle_results";
@@ -102,5 +102,5 @@
     my $command = "$dist_bundle --camera $camera --stage $stage --stage_id $stage_id";
     $command .= " --component $component";
-    $command .= " --path_base $path_base --outdir $out_dir --results_file $results_file";
+    $command .= " --path_base $path_base --outdir $outdir --results_file $results_file";
     $command .= " --prefix $prefix";
     $command .= " --magicked" if $magicked;
@@ -139,5 +139,5 @@
 }
 
-my $reglist = "$out_dir/reglist$job_id";
+my $reglist = "$outdir/reglist$job_id";
 if (! open(REGLIST, ">$reglist") ) {
     my_die("failed to open registration list: $reglist", $PS_EXIT_UNKNOWN_ERROR);
Index: /branches/pap/pstamp/scripts/pstamp_job_run.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_job_run.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_job_run.pl	(revision 28003)
@@ -74,4 +74,5 @@
 my $ppstamp    = can_run('ppstamp') or (warn "Can't find ppstamp" and $missing_tools = 1);
 my $pstamp_get_image_job    = can_run('pstamp_get_image_job.pl') or (warn "Can't find pstamp_get_image_job.pl" and $missing_tools = 1);
+my $dqueryparse = can_run('dqueryparse.pl') or (warn "Can't find dqueryparse.pl" and $missing_tools = 1);
 
 if ($missing_tools) {
@@ -83,12 +84,19 @@
 my $jobStatus;
 if ($jobType eq "stamp") {
-    my $argslist = "$outputBase.args";
-    open ARGSLIST, "<$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
-    my $argString = <ARGSLIST>;
-    close ARGSLIST;
-    chomp $argString;
+    my $params = read_params_file($outputBase);
+
+    my $argString;
+    $argString = $params->{job_args};
 
     # XXX: should we do any other sanity checking?
-    my_die("arglist file $argslist is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
+    my_die("argument list is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
+
+    # XXX: remove -astrom from argString and add it here
+
+    $argString .= " -file $params->{image}";
+    $argString .= " -mask $params->{mask}";
+    if ($options & $PSTAMP_SELECT_VARIANCE) {
+        $argString .= " -variance $params->{weight}";
+    }
 
     my $command = "$ppstamp $outputBase $argString";
@@ -119,7 +127,7 @@
         my %extensions = ( $PSTAMP_SELECT_IMAGE  => "fits", 
                            $PSTAMP_SELECT_MASK   => "mk.fits",
-                           $PSTAMP_SELECT_WEIGHT => "wt.fits");
-
-        my $output_mask = $options & ($PSTAMP_SELECT_IMAGE | $PSTAMP_SELECT_MASK | $PSTAMP_SELECT_WEIGHT);
+                           $PSTAMP_SELECT_VARIANCE => "wt.fits");
+
+        my $output_mask = $options & ($PSTAMP_SELECT_IMAGE | $PSTAMP_SELECT_MASK | $PSTAMP_SELECT_VARIANCE);
 
         foreach my $key (keys (%extensions)) {
@@ -139,5 +147,5 @@
         }
 
-        get_other_outputs($F, $outputBase, $options);
+        get_other_outputs($F, $outputBase, $options, $params);
 
         close $F;
@@ -165,5 +173,30 @@
     }
 } elsif ($jobType eq "detect_query") {
-    my_die("detect_query jobs not supported yet", $job_id,$PS_EXIT_CONFIG_ERROR);
+    # detect_query jobs are basically holders to note that we need a file updated before we can continue.
+    # Load the argument list that dqueryparse should have created the first time it ran, so we know how to
+    # run it again the same way.
+    my $argslist = "$outputBase/parse.args";
+    open ARGSLIST, "<$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
+    my $argString = <ARGSLIST>;
+    close ARGSLIST;
+    chomp $argString;
+
+    # XXX: should we do any other sanity checking?
+    my_die("arglist file $argslist is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
+
+    my $command = "$dqueryparse --job_id $job_id $argString";
+    $command .= " --dbname $dbname" if $dbname;
+    $command .= " --dbserver $dbserver" if $dbserver;
+    $command .= " --verbose" if $verbose;
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => $verbose);
+
+    # Although dqueryparse can potentially force more updates (and more jobs), it should still return success.
+    if ($success) {
+	$jobStatus = $PS_EXIT_SUCCESS;
+    } else {
+	$jobStatus = $error_code >> 8;
+	my_die("dqueryparse.pl failed with error code: $jobStatus", $job_id, $jobStatus);
+    }
 } else {
     my_die("unknown jobType $jobType found", $job_id, $PS_EXIT_PROG_ERROR);
@@ -172,6 +205,6 @@
 # mark the job stopped in the database
 {
-    my $command = "$pstamptool -updatejob -job_id $job_id -state stop"; 
-    $command .= " -fault $jobStatus" if $jobStatus;
+    my $command = "$pstamptool -updatejob -job_id $job_id -set_state stop"; 
+    $command .= " -set_fault $jobStatus" if $jobStatus;
     $command .= " -dbname $dbname" if $dbname;
     $command .= " -dbserver $dbserver" if $dbserver;
@@ -212,9 +245,12 @@
     my $output_base = shift;
     my $options = shift;
+    my $params = shift;
 
     if ($options & ( $PSTAMP_SELECT_CMF | $PSTAMP_SELECT_PSF | $PSTAMP_SELECT_BACKMDL)) {
-        my $comp = read_params_file($output_base);
-
-        my $stage = $comp->{stage};
+        if (!$params) {
+            $params = read_params_file($output_base);
+        }
+
+        my $stage = $params->{stage};
 
         # raw files don't have any other data products
@@ -225,8 +261,8 @@
         # detected in pstampparse so that the user can be notified with 
         # a message in parse_error.txt ("warp do not have a background model")
-        my $cmf_file = $comp->{cmf} if ($options & $PSTAMP_SELECT_CMF);
-        my $psf_file = $comp->{psf} if ($options & $PSTAMP_SELECT_PSF);
-        my $backmdl_file = $comp->{backmdl} if ($options & $PSTAMP_SELECT_BACKMDL);
-        my $pattern_file = $comp->{pattern} if ($options & $PSTAMP_SELECT_BACKMDL);
+        my $cmf_file = $params->{cmf} if ($options & $PSTAMP_SELECT_CMF);
+        my $psf_file = $params->{psf} if ($options & $PSTAMP_SELECT_PSF);
+        my $backmdl_file = $params->{backmdl} if ($options & $PSTAMP_SELECT_BACKMDL);
+        my $pattern_file = $params->{pattern} if ($options & $PSTAMP_SELECT_BACKMDL);
 
         my $outdir = dirname($output_base);
@@ -250,5 +286,5 @@
             copy_and_register_file($f, $backmdl_file, $outdir, $prefix);
         }
-        if (0) {
+       if (0) {
         # don't enable this yet
         if ($pattern_file) {
@@ -256,5 +292,5 @@
             copy_and_register_file($f, $pattern_file, $outdir, $prefix);
         }
-        }
+       }
     }
 }
@@ -317,7 +353,7 @@
         my $command = "$pstamptool -updatejob";
         $command .= " -job_id $job_id";
-        $command .= " -fault $exit_code";
+        $command .= " -set_fault $exit_code";
         # XXX: fix pstamptool to not require -state when -fault with nonzero value is provided
-        $command .= " -state run";
+        $command .= " -set_state run";
         $command .= " -dbname $dbname" if defined $dbname;
         $command .= " -dbserver $dbserver" if defined $dbserver;
Index: /branches/pap/pstamp/scripts/pstamp_parser_run.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_parser_run.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_parser_run.pl	(revision 28003)
@@ -28,4 +28,6 @@
 my $redirect_output;
 my $product;
+my $outdir;
+my $label;
 my $verbose;
 my $dbname;
@@ -36,4 +38,6 @@
     'uri=s'             =>  \$uri,
     'product=s'         =>  \$product,
+    'outdir=s'          =>  \$outdir,
+    'label=s'           =>  \$label,
     'redirect-output'   =>  \$redirect_output,
     'verbose'           =>  \$verbose,
@@ -79,21 +83,25 @@
 }
 
-# workdir is where all of the files generated for this request are placed
-# NOTE: this location needs to be kept in sync with the web interface ( request.php )
-my $datestr = strftime "%Y%m%d", gmtime;
-my $datedir = "$pstamp_workdir/$datestr";
-if (! -e $datedir ) {
-    mkdir $datedir or my_die( "failed to create working directory $datedir for request id $req_id", $req_id,
+if (!$outdir or ($outdir eq "NULL")) {
+    # outdir is where all of the files generated for this request are placed
+    # NOTE: this location needs to be kept in sync with the web interface ( request.php )
+    my $datestr = strftime "%Y%m%d", gmtime;
+    my $datedir = "$pstamp_workdir/$datestr";
+    if (! -e $datedir ) {
+        mkdir $datedir or my_die( "failed to create working directory $datedir for request id $req_id", $req_id,
+            $PS_EXIT_CONFIG_ERROR);
+    }
+
+    $outdir = "$datedir/$req_id";
+}
+
+if (! -e $outdir ) {
+    mkdir $outdir or my_die("failed to create working directory $outdir for request id $req_id", $req_id,
         $PS_EXIT_CONFIG_ERROR);
 }
-
-my $workdir = "$datedir/$req_id";
-if (! -e $workdir ) {
-    mkdir $workdir or my_die("failed to create working directory $workdir for request id $req_id", $req_id,
-        $PS_EXIT_CONFIG_ERROR);
-}
+    
 
 if ($redirect_output) {
-    my $logDest = "$workdir/psparse.$req_id.log";
+    my $logDest = "$outdir/psparse.$req_id.log";
     $ipprc->redirect_output($logDest);
 }
@@ -106,5 +114,5 @@
 
 my $fn = basename($uri);
-my $new_uri = "$workdir/$fn";
+my $new_uri = "$outdir/$fn";
 if ($uri =~ /^http:/) {
     # if the uri is an http uri download the file 
@@ -116,10 +124,11 @@
     }
 } elsif ($uri ne $new_uri) {
-    # put a link to the file into the workdir
+    # copy the request file into outdir
     if (-e $new_uri) {
+        # file exists already delete it incase the previous copy is bogus
         unlink $new_uri or my_die("failed to unlink $new_uri", $req_id, $PS_EXIT_UNKNOWN_ERROR);
     }
     if (! copy $uri, $new_uri) {
-        my_die ("failed to copy request file $uri to workdir $workdir", $req_id, $PS_EXIT_UNKNOWN_ERROR);
+        my_die ("failed to copy request file $uri to workdir $outdir", $req_id, $PS_EXIT_UNKNOWN_ERROR);
     }
 }
@@ -146,8 +155,10 @@
         if ($request_type eq "PS1_PS_REQUEST") {
             $reqType = 'pstamp';
-            $parse_cmd = $pstampparse;
+            $parse_cmd = "$pstampparse";
+            $parse_cmd .= " --label $label" if $label;
         } elsif ($request_type eq "MOPS_DETECTABILITY_QUERY") {
             $reqType = 'dquery';
-            $parse_cmd = $dqueryparse;
+            $parse_cmd = "$dqueryparse";
+	    $parse_cmd .= " --label $label" if $label;
         } else {
             print STDERR "Unknown request type $request_type found in $uri";
@@ -169,7 +180,7 @@
     # that they sent us a request file that we don't understand
 
-    my $command = "$pstamptool -updatereq -req_id $req_id -state run";
-    $command   .= " -reqType unknown";
-    $command   .= " -fault $PS_EXIT_DATA_ERROR";
+    my $command = "$pstamptool -updatereq -req_id $req_id -set_state run";
+    $command   .= " -set_reqType unknown";
+    $command   .= " -set_fault $PS_EXIT_DATA_ERROR";
     $command   .= " -dbname $dbname" if $dbname;
     $command   .= " -dbserver $dbserver" if $dbserver;
@@ -182,5 +193,5 @@
 }
 
-$parse_cmd .= " --mode queue_job --req_id $req_id --product $product --out_dir $workdir --file $uri";
+$parse_cmd .= " --mode queue_job --req_id $req_id --product $product --outdir $outdir --file $uri";
 $parse_cmd .= " --dbname $dbname" if $dbname;
 $parse_cmd .= " --dbserver $dbserver" if $dbserver;
@@ -190,5 +201,5 @@
 my $fault;
 {
-    my $error_file_name = "$workdir/parse_error.txt";
+    my $error_file_name = "$outdir/parse_error.txt";
     # get rid of any error file from previous attempt to parse this request
     unlink $error_file_name if (-e $error_file_name);
@@ -215,5 +226,5 @@
     unless ($success) {
         $fault = $error_code >> 8;
-        $newState = "stop";
+#        $newState = "stop";
     }
 }
@@ -223,8 +234,9 @@
 #
 {
-    my $command = "$pstamptool -updatereq -req_id $req_id -state $newState";
-    $command   .= " -reqType $reqType" if $reqType;
-    $command   .= " -uri $new_uri" if $new_uri;
-    $command   .= " -fault $fault" if $fault;
+    my $command = "$pstamptool -updatereq -req_id $req_id -set_state $newState";
+    $command   .= " -set_outdir $outdir";
+    $command   .= " -set_reqType $reqType" if $reqType;
+    $command   .= " -set_uri $new_uri" if $new_uri;
+    $command   .= " -set_fault $fault" if $fault;
     $command   .= " -dbname $dbname" if $dbname;
     $command   .= " -dbserver $dbserver" if $dbserver;
@@ -265,5 +277,5 @@
     carp($msg);
 
-    my $command = "$pstamptool -updatereq -req_id $req_id  -fault $fault";
+    my $command = "$pstamptool -updatereq -req_id $req_id  -set_fault $fault";
     $command   .= " -dbname $dbname" if $dbname;
     $command   .= " -dbserver $dbserver" if $dbserver;
Index: /branches/pap/pstamp/scripts/pstamp_request_file
===================================================================
--- /branches/pap/pstamp/scripts/pstamp_request_file	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstamp_request_file	(revision 28003)
@@ -187,5 +187,11 @@
         for (my $i = 0; $i < scalar @colNames; $i++) {
             my $writeType = $colWriteType[$i];
-            $outFits->write_col( $writeType, $i + 1, 1, 1, $numRows, $colData->[$i], $status );
+            my $data = $colData->[$i];
+            if ($writeType == TULONG) {
+                die "invalid integer data found in column $i\n" unless validIntegers($data);
+            } elsif ($writeType == TDOUBLE) {
+                die "invalid numeric data found in column $i\n" unless validNumbers($data);
+            }
+            $outFits->write_col( $writeType, $i + 1, 1, 1, $numRows, $data, $status );
             check_fitsio( $status );
         }
@@ -312,4 +318,42 @@
 }
 
+sub checkValid {
+    my $aref = shift;
+    my $float = shift;
+
+    return 0 if !defined $aref;
+
+    my $valid = 0;
+    my $row = 0;
+    foreach my $val (@$aref) {
+        $row++;
+        if ($float) {
+            if (!($val =~  /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)) {
+                $valid = 0;
+                print STDERR "Error on row $row: '$val' is not a valid number\n";
+                last;
+            }
+        } else {
+            if ($val =~ /\D/) {
+                $valid = 0;
+                print STDERR "Error on row $row: '$val' is not a valid integer\n";
+                last;
+            }
+        }
+        $valid = 1;
+    }
+
+    return $valid;
+}
+sub validIntegers {
+    return checkValid(@_, 0);
+}
+
+sub validNumbers
+{
+    return checkValid(@_, 1);
+}
+
+
 sub printhelp
 {
Index: /branches/pap/pstamp/scripts/pstampparse.pl
===================================================================
--- /branches/pap/pstamp/scripts/pstampparse.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/pstampparse.pl	(revision 28003)
@@ -17,4 +17,5 @@
 use Carp;
 use POSIX;
+use Time::HiRes qw(gettimeofday);
 
 my $verbose;
@@ -24,6 +25,7 @@
 my $request_file_name;
 my $mode = "list_uri";
-my $out_dir;
+my $outdir;
 my $product;
+my $label;
 my $save_temps;
 my $no_update;
@@ -32,6 +34,7 @@
     'file=s'    =>  \$request_file_name,
     'req_id=s'  =>  \$req_id,
-    'out_dir=s' =>  \$out_dir,
+    'outdir=s'  =>  \$outdir,
     'product=s' =>  \$product,
+    'label=s'   =>  \$label,
     'mode=s'    =>  \$mode,
     'dbname=s'  =>  \$dbname,
@@ -42,10 +45,10 @@
 );
 
-die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "list_job") or ($mode eq "queue_job");
+die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "queue_job");
 die "--file is required"     if !defined($request_file_name);
 
 if ($mode ne "list_uri") {
     die "req_id is required"   if !$req_id;
-    die "out_dir is required"  if !$out_dir;
+    die "outdir is required"  if !$outdir;
     die "product is required"  if !$product;
 }
@@ -64,5 +67,4 @@
 my $pstamptool  = can_run('pstamptool')  or (warn "Can't find pstamptool"  and $missing_tools = 1);
 my $pstampdump  = can_run('pstampdump') or (warn "Can't find pstampdump" and $missing_tools = 1);
-my $dvoImagesAtCoords  = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" and $missing_tools = 1);
 my $fields  = can_run('fields') or (warn "Can't find fields" and $missing_tools = 1);
 
@@ -127,6 +129,6 @@
     # update the database with the request name. This will be used as the
     # the output data store's product name
-    my $command = "$pstamptool -updatereq -req_id $req_id  -name $req_name";
-    $command .= " -outProduct $product";
+    my $command = "$pstamptool -updatereq -req_id $req_id  -set_name $req_name";
+    $command .= " -set_outProduct $product";
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
         run(command => $command, verbose => $verbose);
@@ -145,4 +147,5 @@
 my $rows;
 {
+    my $start_request_file = gettimeofday();
     my $command = "$pstampdump $request_file_name";
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -152,11 +155,17 @@
     }
     if (@$stdout_buf) {
-        my $table =  $mdcParser->parse(join "", @$stdout_buf) or
-            my_die("Unable to parse metdata config doc", $PS_EXIT_UNKNOWN_ERROR);
-        $rows = parse_md_list($table);
-    }
-
-}
-
+        $rows = parse_md_fast($mdcParser, join "", @$stdout_buf);
+    }
+    my $dtime_request_file = gettimeofday() - $start_request_file;
+    print "Time to read and parse request file: $dtime_request_file\n";
+
+}
+
+#
+# Loop over rows in the request file collecting consecutive rows that have the "same images of interest"
+# in the sense that their selection parameters will yield the same "Runs".
+# Process the groups of rows together to reduce lookup time and to potentially make multiple
+# stamps from the same ppstamp process.
+#
 my @rowList;
 my $num_jobs = 0;
@@ -165,30 +174,90 @@
 my $need_magic;
 foreach my $row (@$rows) {
-    # XXX: TODO: sanity check all parameters
-
-    # If we encounter an error for a particular row add a job with the proper fault code.
-    # If we encounter an error in this loop we shouldn't really just die.
-    # We only do that now in the case of I/O or DB errors or the like.
-
-    my $rownum   = $row->{ROWNUM};
-    my $job_type = $row->{JOB_TYPE};
-    
-    # parameters that select the images of interest
-    my $project  = $row->{PROJECT};
-
-    # note: resolve_project avoids running pstamptool every time by remembering the
-    # last project resolved
-    my $proj_hash = resolve_project($ipprc, $project, $dbname, $dbserver);
-    if (!$proj_hash) {
-        print STDERR "project $project not found\n"  if $verbose;
-        insertFakeJobForRow($row, 1, $PSTAMP_UNKNOWN_PRODUCT);
+    # santiy check the paramaters
+    if (!checkRow($row)) {
+        # when it enconters an error checkRow adds a fake job with an appropriate error code to the database
         $num_jobs++;
         next;
     }
+    # initialize counter for "job number"
+    $row->{job_num} = 0;
+    $row->{error_code} = 0;
+
+    if (scalar @rowList == 0) {
+        push @rowList, $row;
+        next;
+    }
+
+    my $firstRow = $rowList[0];
+    if (same_images_of_interest($firstRow, $row)) {
+        # add this row to the list and move on
+        push @rowList, $row;
+        next;
+    }
+
+    # the images of interest for this new row doesn't match the list. 
+    # process the list ...
+    $num_jobs += processRows(\@rowList);
+
+    # and reset the list to contain just the new row
+    @rowList = ($row);
+}
+
+# out of rows process the list
+if (scalar @rowList > 0) {
+    $num_jobs += processRows(\@rowList);
+}
+
+if (($mode eq "queue_job") and ($num_jobs eq 0)) {
+    print STDERR "no jobs created for $req_name\n" if $verbose;
+    insertFakeJobForRow(undef, 0, $PSTAMP_INVALID_REQUEST);
+}
+
+exit 0;
+
+sub checkRow {
+        
+    my $row = shift;
+
+    # If we encounter an error for a particular row add a job with the proper fault code.
+
+    my $rownum   = $row->{ROWNUM};
+    if (!validID($rownum)) {
+        print STDERR "$rownum is not a valid ROWNUM\n";
+        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+        return 0;
+    }
+    my $job_type = $row->{JOB_TYPE};
+    if (($job_type ne "stamp") and ($job_type ne "get_image")) {
+        print STDERR "$job_type is not a valid JOB_TYPE\n";
+        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+        return 0;
+    }
+    
     my $req_type = $row->{REQ_TYPE};
-    $stage       = $row->{IMG_TYPE};
-    my $id      = $row->{ID};
+    if (($req_type ne "byid") and ($req_type ne "bycoord") and ($req_type ne "byexp") and
+        ($req_type ne "byskycell") and ($req_type ne "bydiff")) {
+        print STDERR "$req_type is not a valid REQ_TYPE\n";
+        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+        return 0;
+    }
+    if ($job_type eq 'get_image') {
+        unless ($req_type eq 'byid' or $req_type eq 'byexp') {
+            print STDERR "REQ_TYPE must be 'byid' or 'byexp' for JOB_TYPE 'get_image'\n";
+            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+            return 0;
+        }
+    }
+
+
     my $component = $row->{COMPONENT};
-    my $tess_id = $row->{TESS_ID};
+    if (!defined $component or (lc($component) eq "null") or (lc($component) eq "all")) {
+        if ($job_type eq 'get_image') {
+            $row->{COMPONENT} = 'all';
+        } else {
+            $row->{COMPONENT} = $component = "";
+        }
+    }
+    $row->{TESS_ID} = "" if !defined $row->{TESS_ID};
 
     my $filter  = $row->{REQFILT};
@@ -196,9 +265,19 @@
         if (length($filter) == 1) {
             # allow single character filter cuts to work
-            $filter .= '%';
+            $row->{REQFILT} .= '%';
         }
     }
     my $mjd_min = $row->{MJD_MIN};
+    if (defined($mjd_min) and !validNumber($mjd_min)) {
+        print STDERR "$mjd_min is not a valid MJD_MIN\n";
+        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+        return 0;
+    }
     my $mjd_max = $row->{MJD_MAX};
+    if (defined($mjd_max) and !validNumber($mjd_max)) {
+        print STDERR "$mjd_max is not a valid MJD_MAX\n";
+        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+        return 0;
+    }
     my $data_group = $row->{DATA_GROUP};
     if (!defined $data_group) {
@@ -209,9 +288,7 @@
     }
         
-    my $x       = $row->{CENTER_X};
-    my $y       = $row->{CENTER_Y};
-
-    # XXX things don't work if bit zero of option mask is not set;
+    # req_finish doesn't work if bit zero of option mask is not set;
     $row->{OPTION_MASK} |= 1;
+
     my $option_mask= $row->{OPTION_MASK};
     my $inverse = ($option_mask & $PSTAMP_SELECT_INVERSE) ? 1 : 0;
@@ -222,124 +299,148 @@
     my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
 
-    my $search_component = (!defined($component) or ($component eq "null")) ? "" : $component;
-    
-    if (!$skycenter and !$search_component) {
-        print STDERR "COMPONENT must be specified for pixel coordinate ROI center\n" if $verbose;
+    if (!$skycenter and !$component) {
+        print STDERR "COMPONENT must be specified for pixel coordinate ROI center\n";
         insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
-        $num_jobs++;
-        next;
-    }
-
-    # user requested us to search all components. Set to ""
-    $search_component = "" if $search_component eq "all";
-
+        return 0;
+    }
+
+    my $stage = $row->{IMG_TYPE};
     if (!check_image_type($stage)) {
-        print STDERR "invalid IMG_TYPE for row $rownum\n" if $verbose;
+        print STDERR "invalid IMG_TYPE for row $rownum\n";
         insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
-        $num_jobs++;
-        next;
+        return 0;
     }
 
     if ((($job_type eq "stamp") or ($req_type eq "bycoord")) and ! validROI($row)) {
-        print STDERR "invalid ROI for row $rownum\n" if $verbose;
+        print STDERR "invalid ROI for row $rownum\n";
         insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
-        $num_jobs++;
-        next;
+        return 0;
     }
 
     if (($req_type eq "byexp") and ($stage eq "stack")) {
-        print STDERR "byexp not implemented for stack stage. row: $rownum\n" if $verbose;
+        print STDERR "byexp not implemented for stack stage. row: $rownum\n";
         insertFakeJobForRow($row, 1, $PSTAMP_NOT_IMPLEMENTED);
-        $num_jobs++;
-        next;
-    }
-
-    
+        return 0;
+    }
+
     # $mode list_uri is a debugging mode (it may used by the http interface)
     # if this happens just croak
-    my_die("job_type is list_uri but mode is $mode", $PS_EXIT_PROG_ERROR) if ($job_type eq "list_uri") and ($mode ne "list_uri");
-
+   # my_die("job_type is list_uri but mode is $mode", $PS_EXIT_PROG_ERROR) if ($job_type eq "list_uri") and ($mode ne "list_uri");
+
+
+    if ($req_type eq "bycoord") {
+        if (!$skycenter) {
+            print STDERR "center must be specified in sky coordintes for bycoord";
+            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+            return 0;
+        }
+    }
+
+    if (($req_type eq "byid") or ($req_type eq "bydiff")) {
+        if (!validID($row->{ID})) {
+            print STDERR "ID must be a positive integer for req_type $req_type\n";
+            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
+            return 0
+        }
+    }
+
+    return 1;
+}
+
+sub processRows {
+    my $rowList = shift;
+    my $num_jobs = 0;
+
+    # all rows in the list are compatible
+    my $row = $rowList->[0];
+
+    my $project  = $row->{PROJECT};
+
+    # note: resolve_project avoids running pstamptool every time by remembering the
+    # last project resolved
+    my $proj_hash = resolve_project($ipprc, $project, $dbname, $dbserver);
+    if (!$proj_hash) {
+        print STDERR "project $project not found\n" ;
+        foreach $row (@$rowList) {
+            insertFakeJobForRow($row, 1, $PSTAMP_UNKNOWN_PRODUCT);
+            $num_jobs++;
+        }
+        return $num_jobs;
+    }
+    my $req_type  = $row->{REQ_TYPE};
+    $stage        = $row->{IMG_TYPE};
+    my $id        = $row->{ID};
+    my $component = $row->{COMPONENT};
+    my $tess_id   = $row->{TESS_ID};
+
+    my $filter    = $row->{REQFILT};
+    my $mjd_min   = $row->{MJD_MIN};
+    my $mjd_max   = $row->{MJD_MAX};
+    my $data_group = $row->{DATA_GROUP};
+
+    my $rownum     = $row->{ROWNUM};
+    my $job_type   = $row->{JOB_TYPE};
+    my $option_mask= $row->{OPTION_MASK};
+    
     my $image_db   = $proj_hash->{dbname};
     my $camera     = $proj_hash->{camera};
-    $need_magic = $proj_hash->{need_magic};
+    $need_magic    = $proj_hash->{need_magic};
 
     # Temporary hack so that MOPS can get at non-magicked data
-#    if ($product and ($product eq "mops-pstamp-results")) {
-#        $need_magic = 0;
-#    }
-
-    # For "stamp" and "list_uri" jobs collect rows with the same images of interest in a list so that they
-    # can be looked up together.
-    if (@rowList) {
-        my $firstRow = $rowList[0];
-        if (($firstRow->{JOB_TYPE} ne "get_image") and same_images_of_interest($firstRow, $row)) {
-
-            # add this row to the list and move on
-            push @rowList, $row;
-
-            next;
-
-        } else {
-            # this row has different selectors
-            # queue the jobs for the ones we've collected
-            $num_jobs += queueJobs($mode, \@rowList, $imageList);
-            @rowList = ();
-        }
-    }
-
-    # look up images for the current row
-    if ($req_type eq "bycoord") {
-        if (!$skycenter) {
-            print STDERR "center must be specified in sky coordintes for bycoord" if $verbose;
-            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
-            $num_jobs++;
-            next;
-        }
-    }
-    if (($req_type eq "byid") or ($req_type eq "bydiff")) {
-        if (!validID($id)) {
-            print STDERR "ID must be a positive integer for req_type $req_type\n" if $verbose;
-            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
-            $num_jobs++;
-            next;
-        }
-    }
+    my $allow_mops_unmagicked = 1;
+    if ($allow_mops_unmagicked) {
+        if ($product and (($product eq "mops-pstamp-results") or
+                          ($product eq "mops-pstamp-results2"))) {
+            $need_magic = 0;
+        }
+    }
+
+    $need_magic = 0 if $stage eq 'stack';
+    
+    my $numRows = scalar @$rowList;
+
+    print "Collected $numRows rows beginning with row $rownum. $req_type $stage $id $tess_id $component\n";
+    
     # Call PS::IPP::PStamp::Job locate_images subroutine to get the images for this
     # request specification. An array reference is returned.
-    $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $tess_id, $search_component,
-                $option_mask, $need_magic, $x, $y, $mjd_min, $mjd_max, $filter, $data_group, $verbose);
-
-    if (!$imageList or !@$imageList) {
-        print STDERR "no matching images found for row $rownum\n" if $verbose;
-        # note in this case queueJobs inserts the fake job for these rows
-    }
+    my $start_locate = gettimeofday();
+
+    # XXX: perhaps we should get rid of most of this argument list.
+    # Now that we are passing down compatible rows all of the
+    # information required is contained there
+
+    $imageList = locate_images($ipprc, $image_db, \@rowList, $req_type, $stage, $id, $tess_id, $component,
+                $option_mask, $need_magic, $mjd_min, $mjd_max, $filter, $data_group, $verbose);
+
+    my $dtime_locate = gettimeofday() - $start_locate;
+    print "Time to locate_images for row $rownum $dtime_locate\n";
+
+    # handle this XXX: what did I mean by this comment
     $row->{need_magic} = $need_magic;
-    push @rowList, $row;
-}
-
-if (@rowList) {
+
     $num_jobs += queueJobs($mode, \@rowList, $imageList);
-}
-
-if (($mode eq "queue_job") and ($num_jobs eq 0)) {
-    print STDERR "no jobs created for $req_name\n" if $verbose;
-    insertFakeJobForRow(undef, 0, $PSTAMP_INVALID_REQUEST);
-}
-
-# PAU
-
-exit 0;
-
-
-sub queueJobsForRow
+
+    # if a row slipped through with no jobs add one
+    foreach my $row (@rowList) {
+        if ($row->{job_num} == 0) {
+            print "row $row->{ROWNUM} produced no jobs\n";
+            print STDERR "row $row->{ROWNUM} produced no jobs\n";
+            my $error_code = $row->{error_code};
+            $error_code =  $PSTAMP_NO_IMAGE_MATCH if !$error_code;
+            insertFakeJobForRow($row, ++$row->{job_num}, $error_code);
+        }
+    }
+
+    return $num_jobs;
+}
+
+sub queueJobForImage
 {
     my $row = shift;
     my $stage = shift;
-    my $imageList = shift;
-    my $have_skycells = shift;
+    my $image = shift;
     my $need_magic = shift;
     my $mode = shift;
 
-    my $num_jobs = 0;
     my $rownum = $row->{ROWNUM};
     my $option_mask = $row->{OPTION_MASK};
@@ -365,28 +466,227 @@
     }
 
+    my $component = $image->{component};
+
+    my $job_num = ++($row->{job_num});
+
+    my $imagefile = $image->{image};
+    if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
+        # XXX: should we add a faulted job so the client can know what happened if no images come back?
+        # The test for destreaked is made in locate_images now so this code never runs. This leads to no feedback
+        # to users, but speeds up processing significantly
+        print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
+
+        # for now assume yes.
+
+        insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
+        return 1;
+    } elsif ($stage eq "stack") {
+        # unconvolved stack images weren't available prior to some point in time.
+        # XXX: handle this more correctly by examining the stack run's config dump file.
+        # It looks like # the feature was turned on sometime around November 11, 2009. stackRun 30067 is the lowest
+        # one that I found with an unconvolved image.
+        my $MIN_GPC1_STACK_ID_WITH_UNCONVOLVED_IMAGES = 30067;
+        if ($row->{unconvolved} and ($row->{PROJECT} eq 'gpc1') and 
+            ($image->{stack_id} < $MIN_GPC1_STACK_ID_WITH_UNCONVOLVED_IMAGES)) {
+            print STDERR "Unconvolved stack image is not available for stackRun.stack_id: $image->{stack_id}\n";
+            insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_AVAILABLE);
+            return 1;
+        }
+    }
+    my $exp_id = $image->{exp_id};
+            
+    my $args = $roi_string ? $roi_string : "";
+    if ($stage eq "raw" or $stage eq "chip") {
+        $args .= " -class_id $component" if $component;
+    }
+
+    # add astrometry file for raw and chip images if one is available
+    if (($stage eq "chip") || ($stage eq "raw")) {
+        $args .= " -astrom $image->{astrom}" if $image->{astrom};
+    }
+
+    $image->{job_args} = $args;
+
+    my $base = basename($image->{image});
+    if (! $base =~ /.fits$/ ) {
+        my_die("unexpected image file name found $image->{image}", $PS_EXIT_PROG_ERROR);
+    }
+    $base =~ s/.fits$//;
+            
+    my $output_base = "$outdir/${rownum}_${job_num}_${base}";
+    write_params($output_base, $image);
+
+    my $newState = "run";
+    my $fault = 0;
+    my $dep_id;
+
+    # XXX: this code is repeated in queueGetImageJobs we should encapsulate it in a subroutine and share it
+    if ($stage ne 'raw') {
+        # updates for stack stage not supported yet
+        my $allow_wait_for_update = ($stage ne 'stack');
+        my $run_state = $image->{state};
+        my $data_state = $image->{data_state};
+        $data_state = $run_state if $stage eq 'stack';
+        if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
+            ($run_state eq 'drop') or 
+            ($run_state eq 'error_cleaned') or ($data_state eq 'error_cleaned') or
+            ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
+            # image is gone and it's not coming back
+            $newState = 'stop';
+            $fault = $PSTAMP_GONE;
+        } elsif (($data_state ne 'full') or ($need_magic and ($image->{magicked} < 0))) {
+            if ($stage eq 'chip') {
+                my $burntool_state = $image->{burntool_state};
+                if ($burntool_state and (abs($burntool_state) < 14)) {
+                    $newState = 'stop';
+                    $fault = $PSTAMP_NOT_AVAILABLE;
+                }
+            } 
+            if (!$allow_wait_for_update) {
+                print STDERR "wait for update not supported for stage $stage yet\n";
+                $newState = 'stop';
+                $fault = $PSTAMP_NOT_AVAILABLE;
+            }
+            if (!$fault) {
+                # wait for update unless the customer asks us not to
+                if (($option_mask & $PSTAMP_NO_WAIT_FOR_UPDATE)) {
+                    $newState = 'stop';
+                    $fault = $PSTAMP_NOT_AVAILABLE;
+                } elsif (!$image->{magicked}) {
+                    $newState = 'stop';
+                    $fault = $PSTAMP_NOT_DESTREAKED;
+                } else {
+                    # cause the image to be re-made
+                    # set up to queue an update run
+                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{imagedb}, 
+                        $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic);
+                }
+            }
+        }
+    }
+
+    my $command = "$pstamptool -addjob  -req_id $req_id -job_type $row->{JOB_TYPE}"
+                    . " -outputBase $output_base -rownum $rownum -state $newState -options $option_mask";
+    $command .= " -fault $fault" if $fault;
+    $command .= " -exp_id $exp_id" if $exp_id;
+    $command .= " -dep_id $dep_id" if $dep_id;
+
+    if (!$no_update) {
+        # mode eq "queue_job"
+        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+            run(command => $command, verbose => $verbose);
+        unless ($success) {
+            print STDERR @$stderr_buf;
+            # XXX TODO: now what? Should we mark the error state for the request?
+            # should we keep going for other uris? If so how do we report that some
+            # of the work that the request wanted isn't going to get done
+            my_die("failed to queue job for request $req_id", $PS_EXIT_UNKNOWN_ERROR);
+        }
+    } else {
+        print "skipping command: $command\n";
+    }
+
+    return 1;
+}
+
+# queue jobs for a collection of request specifications that have the same Images of Interest
+sub queueJobs
+{
+    my $mode = shift;
+    my $rowList = shift;
+    my $imageList = shift;
+
+    my $firstRow = $rowList[0];
+    my $stage    = $firstRow->{IMG_TYPE};
+    my $job_type = $firstRow->{JOB_TYPE};
+    my $need_magic = $firstRow->{need_magic};
+
+    my $num_jobs = 0;
+
+    if ($mode eq "list_uri") {
+        foreach my $image (@$imageList) {
+            print "$image->{image}\n";
+        }
+    } elsif ($job_type eq "get_image") {
+        my $n = scalar @$rowList;
+
+        my_die( "error: unexpected number of rows for get_image request: $n", $PS_EXIT_PROG_ERROR) if $n != 1;
+
+        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
+
+    } else {
+        if (!$imageList or (scalar @$imageList eq 0)) {
+            # We didn't find any images for this set of rows. Insert a fake job to carry
+            # the status back to the requestor.
+            foreach my $row (@$rowList) {
+                my $error_code = $row->{error_code};
+                $error_code = $PSTAMP_NO_IMAGE_MATCH if !$error_code;
+                insertFakeJobForRow($row, ++$row->{job_num}, $error_code);
+                $num_jobs++;
+            }
+            return $num_jobs;
+        }
+
+        foreach my $image (@$imageList) {
+            # get the array of row indices that touch this image
+            my $row_index = $image->{row_index};
+            if (!$row_index or scalar @$row_index == 0) {
+                # XXX should this happen? Why did something get returned.
+                print "image ${stage}_id: $image->{stage_id} component: $image->{component} matched no rows\n";
+                next;
+            }
+            # XXX: TODO: eventually we may change ppstamp to be able to make multiple stamps per invocation
+
+            foreach my $i (@$row_index) {
+                my $row = $rowList->[$i];
+
+                $num_jobs += queueJobForImage($row, $stage, $image, $need_magic, $mode);
+            }
+        }
+    }
+
+    return $num_jobs;
+}
+
+sub queueGetImageJobs
+{
+    my $row = shift;
+    my $imageList = shift;
+    my $stage = shift;
+    my $need_magic = shift;
+    my $mode = shift;
+
+    my $num_jobs = 0;
+    my $rownum = $row->{ROWNUM};
+    my $option_mask = $row->{OPTION_MASK};
+
+    # For dist_bundle we need
+    #  --camera from $image
+    #  --stage 
+    #  --stage_id from $image
+    #  --component from $image
+    #  --path_base 
+    #  --outdir global to this script
+
     # loop over images
-    my $job_num = 0;
     foreach my $image (@$imageList) {
-        my $component;
-        if ($have_skycells) {
-            $component = $image->{skycell_id};
-        } else {
-            $component = $image->{class_id};
-        }
-
-        # skip this component if it is not in the list for this row
-        next if ! $components->{$component};
-
-        $job_num++;
+        my $stage_id = $image->{stage_id};
+        my $component = $image->{component};
+
+        # skip faulted components for now. Should we even be here?
+        if ($image->{fault} > 0) {
+            printf STDERR "skipping faulted component for $stage $stage_id $component\n" if $verbose;
+            next;
+        }
+
+        my $job_num = ++($row->{job_num});
 
         my $imagefile = $image->{image};
         if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
-            # XXX: should we add a faulted job so the client can know what happened if no images come back?
-            # The test for destreaked is made in locate_images now so this code never runs. This leads to no feedback
-            # to users, but speeds up processing significantly
+            # we only get here if req_type is (byid or byexp). For other types the test for magicked is performed
+            # in locate_images because it's much more efficient to do the test in the database.
+            # For these two modes we fall through to here in order to give feedback to the requestor as
+            # to why the request failed to queue jobs.
             print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
-
-            # for now assume yes.
-
             insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
             $num_jobs++;
@@ -396,46 +696,5 @@
         my $exp_id = $image->{exp_id};
             
-        my $args = $roi_string ? $roi_string : "";
-        if ($stage eq "raw" or $stage eq "chip") {
-            $args .= " -class_id $component" if $component;
-        }
-
-        # add astrometry file for raw and chip images if one is available
-        if (($stage eq "chip") || ($stage eq "raw")) {
-            $args .= " -astrom $image->{astrom}" if $image->{astrom};
-        }
-
-        $image->{job_args} = $args;
-
-        # XXX: we can get rid of the following everything that we need is
-        # in the params file
-
-        $args .= " -file $imagefile";
-
-        if (($option_mask & $PSTAMP_SELECT_MASK) &&  $image->{mask} ) {
-            $args .= " -mask $image->{mask}";
-        }
-        if (($option_mask & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {
-            $args .= " -variance $image->{weight}";
-        }
-
-        my $base = basename($image->{image});
-        if (! $base =~ /.fits$/ ) {
-            my_die("unexpected image file name found $image->{image}", $PS_EXIT_PROG_ERROR);
-        }
-        $base =~ s/.fits$//;
-            
-        # XXX: TODO use filerule for this. I don't have a camera defined here
-        if (($stage eq 'chip') and ($image->{camera} eq 'GPC1')) {
-            $base = "${base}.${component}";
-        }
-
-        my $output_base = "$out_dir/${rownum}_${job_num}_${base}";
-        my $argslist = "${output_base}.args";
-
-        # copy the argument list to a file
-        open ARGSLIST, ">$argslist" or my_die("failed to open $argslist", $PS_EXIT_UNKNOWN_ERROR);
-        print ARGSLIST "$args\n";
-        close ARGSLIST or my_die("failed to close $argslist", $PS_EXIT_UNKNOWN_ERROR);
+        my $output_base = "$outdir/${rownum}_${job_num}";
 
         write_params($output_base, $image);
@@ -454,7 +713,7 @@
                 $newState = 'stop';
                 $fault = $PSTAMP_GONE;
-            } elsif (($data_state ne 'full') or ($run_state ne 'full' )) {
-                # don't wait for update unless the caller asks us to
-                if (!($option_mask & $PSTAMP_WAIT_FOR_UPDATE)) {
+            } elsif (($data_state ne 'full') or ($need_magic and ($image->{magicked} < 0))) {
+                # wait for update unless the customer asks us to not to
+                if ($option_mask & $PSTAMP_NO_WAIT_FOR_UPDATE) {
                     $newState = 'stop';
                     $fault = $PSTAMP_NOT_AVAILABLE;
@@ -462,6 +721,6 @@
                     # cause the image to be re-made
                     # set up to queue an update run
-                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{image_db}, 
-                        $run_state, $stage, $image->{stage_id}, $need_magic);
+                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{imagedb}, 
+                        $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic);
                 }
             }
@@ -475,256 +734,5 @@
         $command .= " -dep_id $dep_id" if $dep_id;
 
-        if ($mode eq "list_job") { 
-            # this is a debugging mode, just print the pstamptool that would have run
-            # this is sort of like the mode -noupdate that some other tools support
-            print "$command\n";
-        } elsif (!$no_update) {
-            # mode eq "queue_job"
-            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                run(command => $command, verbose => $verbose);
-            unless ($success) {
-                print STDERR @$stderr_buf;
-                # XXX TODO: now what? Should we mark the error state for the request?
-                # should we keep going for other uris? If so how do we report that some
-                # of the work that the request wanted isn't going to get done
-                my_die("failed to queue job for request $req_id", $PS_EXIT_UNKNOWN_ERROR);
-            }
-        } else {
-            print "skipping command: $command\n";
-        }
-    }
-    if ( $num_jobs == 0 ) {
-        print STDERR "no jobs for row $rownum\n" if $verbose;
-        insertFakeJobForRow($row, 1, $PSTAMP_NO_OVERLAP);
-        $num_jobs = 1;
-    }
-    return $num_jobs;
-}
-
-# queue jobs for a collection of request specifications that have the same Images of Interest
-sub queueJobs
-{
-    my $mode = shift;
-    my $rowList = shift;
-    my $imageList = shift;
-
-    my $firstRow = $rowList[0];
-    my $stage    = $firstRow->{IMG_TYPE};
-    my $job_type = $firstRow->{JOB_TYPE};
-    my $need_magic = $firstRow->{need_magic};
-
-    my $num_jobs = 0;
-
-    if ($mode eq "list_uri") {
-        foreach my $image (@$imageList) {
-            print "$image->{image}\n";
-        }
-    } elsif ($job_type eq "get_image") {
-        my $n = scalar @$rowList;
-
-        my_die( "error: unexpected number of rows for get_image request: $n", $PS_EXIT_PROG_ERROR) if $n != 1;
-
-        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
-
-    } else {
-        if (!$imageList or (scalar @$imageList eq 0)) {
-            # we didn't find any images for this set of rows. Insert a fake job to carry
-            # the status back to the requestor
-            foreach my $row (@$rowList) {
-                insertFakeJobForRow($row, 1, $PSTAMP_NO_IMAGE_MATCH);
-                $num_jobs++;
-            }
-            return $num_jobs;
-        }
-
-        my $have_skycells;
-        if (($stage eq "raw") or ($stage eq "chip")) {
-            $have_skycells = 0;
-        } else {
-            $have_skycells = 1;
-        }
-        
-        my $thisRun;
-
-        my $npoints = 0;
-        my ($pointsList, $pointsListName);
-        if (scalar @$imageList > 1) {
-            ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps);
-            foreach my $row (@$rowList) {
-                $row->{components} = {};
-                if ($row->{skycenter}) {
-                    print $pointsList "$row->{ROWNUM} $row->{CENTER_X} $row->{CENTER_Y}\n";
-                    $npoints++;
-                } else {
-                    # this row's center is in pixel coordinates add all images to the component list for this row
-                    foreach my $i (@$imageList) {
-                        my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id};
-                        my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR)
-                                if !$component;
-                        $row->{components}->{$component} = 1;
-                    }
-                }
-            }
-            close $pointsList;
-        } else {
-            # only one image. Avoid the expense of dvoImagesAtCoords. 
-            # queue the job and let ppstamp figure out if the center is valid for the image
-            # the resulting result code will be the same.
-            foreach my $row (@$rowList) {
-                $row->{components} = {};
-                my $i = $imageList->[0];
-                my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id};
-                my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR) if !$component;
-                $row->{components}->{$component} = 1;
-            }
-        }
-
-        my $tess_dir_abs;
-        my $last_tess_id = "";
-        while ($thisRun = getOneRun($stage, $imageList)) {
-            if ($npoints) {
-                my_die( "pointsListName is not defined", $PS_EXIT_PROG_ERROR) if !$pointsListName;
-                # we collected a set of sky coordinates above.
-                # filter the images so that only those that contain the centers of the ROIs are processed
-                my $command = "$dvoImagesAtCoords -coords $pointsListName";
-                if ($have_skycells) {
-                    my $tess_id = $thisRun->[0]->{tess_id};
-                    if ($tess_id ne $last_tess_id) {
-                        $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id );
-                        $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs );
-                        $last_tess_id = $tess_id;
-                    }
-                    $command .= " -D CATDIR $tess_dir_abs";
-                } else {
-                    my $astrom = $thisRun->[0]->{astrom};
-                    my_die( "no astrometry file found", $PS_EXIT_UNKNOWN_ERROR) if !$astrom;
-                    my $astrom_resolved = $ipprc->file_resolve($astrom);
-                    $command .= " -astrom $astrom_resolved";
-                }
-                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-                    run(command => $command, verbose => $verbose);
-                unless ($success) {
-                    # don't fail if the program exited normally and exit status was PSTAMP_NO_OVERLAP
-                    # That just means that the coordinate didn't match any image/skycell
-                    if (!WIFEXITED($error_code) || (WEXITSTATUS($error_code) ne $PSTAMP_NO_OVERLAP)) {
-                        print STDERR @$stderr_buf;
-                        my $rc = WIFEXITED($error_code) ? WEXITSTATUS($error_code) : $PS_EXIT_SYS_ERROR;
-                        my_die( "dvoImagesAtCoords failed: $rc", $rc);
-                    }
-                }
-                # now we have a list of row numbers and components
-                # eventually we might want to multiple stamp requests for the same image
-                # into the same ppstamp job but not yet. For now we will queue a new
-                my @lines = split "\n", join "", @$stdout_buf;
-                foreach my $line (@lines) {
-                    # parse the line, ignoring the ra and dec
-                    my ($rownum, undef, undef, $component) = split " ", $line;
-
-                    # I guess since we need this function we should be using a hash for rowList 
-                    my $row = findRow($rownum, $rowList);
-                    $row->{components}->{$component} = 1;
-                }
-            }
-            
-            foreach my $row (@$rowList) {
-                $num_jobs += queueJobsForRow($row, $stage, $thisRun, $have_skycells, $need_magic, $mode);
-            }
-        }
-    }
-    return $num_jobs;
-}
-
-#        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
-sub queueGetImageJobs
-{
-    my $row = shift;
-    my $imageList = shift;
-    my $stage = shift;
-    my $need_magic = shift;
-    my $mode = shift;
-
-    my $num_jobs = 0;
-    my $rownum = $row->{ROWNUM};
-    my $option_mask = $row->{OPTION_MASK};
-
-    # For dist_bundle we need
-    #  --camera from $image
-    #  --stage 
-    #  --stage_id from $image
-    #  --component from $image
-    #  --path_base 
-    #  --outdir global to this script
-
-    # loop over images
-    my $job_num = 0;
-    foreach my $image (@$imageList) {
-        my $stage_id = $image->{stage_id};
-        my $component = $image->{component};
-
-        # skip faulted components for now. Should we even be here?
-        if ($image->{fault} > 0) {
-            printf STDERR "skipping faulted component for $stage $stage_id $component\n" if $verbose;
-            next;
-        }
-
-        $job_num++;
-
-        my $imagefile = $image->{image};
-        if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
-            # we only get here if req_type is (byid or byexp). For other types the test for magicked is performed
-            # in locate_images because it's much more efficient to do the test in the database.
-            # For these two modes we fall through to here in order to give feedback to the requestor as
-            # to why the request failed to queue jobs.
-            print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
-            insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
-            $num_jobs++;
-
-            next;
-        }
-        my $exp_id = $image->{exp_id};
-            
-        my $output_base = "$out_dir/${rownum}_${job_num}";
-
-        write_params($output_base, $image);
-
-        my $newState = "run";
-        my $fault = 0;
-        my $dep_id;
-
-        if ($stage ne 'raw') {
-            my $run_state = $image->{state};
-            my $data_state = $image->{data_state};
-            $data_state = $run_state if $stage eq "stack";
-            if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
-                ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
-                # image is gone and it's not coming back
-                $newState = 'stop';
-                $fault = $PSTAMP_GONE;
-            } elsif (($data_state ne 'full') or ($run_state ne 'full' )) {
-                # don't wait for update unless the caller asks us to
-                if (!($option_mask & $PSTAMP_WAIT_FOR_UPDATE)) {
-                    $newState = 'stop';
-                    $fault = $PSTAMP_NOT_AVAILABLE;
-                } else {
-                    # cause the image to be re-made
-                    # set up to queue an update run
-                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{image_db}, 
-                        $run_state, $stage, $image->{stage_id}, $need_magic);
-                }
-            }
-        }
-
-        $num_jobs++;
-        my $command = "$pstamptool -addjob  -req_id $req_id -job_type $row->{JOB_TYPE}"
-                        . " -outputBase $output_base -rownum $rownum -state $newState -options $option_mask";
-        $command .= " -fault $fault" if $fault;
-        $command .= " -exp_id $exp_id" if $exp_id;
-        $command .= " -dep_id $dep_id" if $dep_id;
-
-        if ($mode eq "list_job") { 
-            # this is a debugging mode, just print the pstamptool that would have run
-            # this is sort of like the mode -noupdate that some other tools support
-            print "$command\n";
-        } elsif (!$no_update) {
+        if (!$no_update) {
             # mode eq "queue_job"
             my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -776,9 +784,5 @@
                         . " -rownum $rownum -state stop -fault $fault";
 
-    if ($mode eq "list_job") { 
-        # this is a debugging mode, just print the pstamptool that would have run
-        # this is sort of like the mode -noupdate that some other tools support
-        print "$command\n";
-    } elsif (!$no_update) {
+    if (!$no_update) {
         # mode eq "queue_job"
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -796,74 +800,25 @@
 }
 
-sub get_run_id
-{
-    my $stage = shift;
-    my $image = shift;
-
-    if ($stage eq "raw") {
-        return $image->{exp_id};
-    } elsif ($stage eq "chip") {
-        return $image->{chip_id};
-    } elsif ($stage eq "warp") {
-        return $image->{warp_id};
-    } elsif ($stage eq "stack") {
-        return $image->{stack_id};
-    } elsif ($stage eq "diff") {
-        return $image->{diff_id};
-    } else {
-        my_die("unenexpected stage: $stage found", $PS_EXIT_PROG_ERROR);
-    }
-}
-
-# extract components from the imageList that have the same run id and return the list
-sub getOneRun {
-    my $stage = shift;
-    my $imageList = shift;
-
-    # return if array is empty
-    return undef if ! @$imageList;
-
-    my $last_run_id = 0;
-    my @runList;
-    while ($imageList->[0]) {
-        my $run_id = get_run_id($stage, $imageList->[0]);
-
-        last if ($last_run_id and ($run_id ne $last_run_id));
-
-        my $image = shift @$imageList;
-        $image->{stage} = $stage;
-        push @runList, $image;
-        $last_run_id = $run_id;
-    }
-    return \@runList;
-}
-
 sub same_images_of_interest {
     my $r1 = shift;
     my $r2 = shift;
 
-    return 0 if (($r1->{REQ_TYPE} eq "bycoord") or ($r2->{REQ_TYPE} eq "bycoord"));
-    return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
-    return 0 if ($r1->{JOB_TYPE} ne $r2->{JOB_TYPE});
+    return 0 if (($r1->{REQ_TYPE} eq "bycoord")   or ($r2->{REQ_TYPE} eq "bycoord"));
+    return 0 if (($r1->{JOB_TYPE} eq "get_image") or ($r2->{JOB_TYPE} eq "get_image"));
     return 0 if ($r1->{REQ_TYPE} ne $r2->{REQ_TYPE});
     return 0 if ($r1->{IMG_TYPE} ne $r2->{IMG_TYPE});
     return 0 if ($r1->{ID}       ne $r2->{ID});
     return 0 if ($r1->{TESS_ID}  ne $r2->{TESS_ID});
+    return 0 if ($r1->{COMPONENT}  ne $r2->{COMPONENT});
     return 0 if ($r1->{REQFILT}  ne $r2->{REQFILT});
     return 0 if ($r1->{DATA_GROUP}    ne $r2->{DATA_GROUP});
     return 0 if ($r1->{MJD_MIN}  ne $r2->{MJD_MAX});
     return 0 if ($r1->{MJD_MAX}  ne $r2->{MJD_MAX});
+    return 0 if ($r1->{OPTION_MASK}  ne $r2->{OPTION_MASK});
+    return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
     return 0 if ($r1->{inverse}  ne $r2->{inverse});
     return 0 if ($r1->{unconvolved}  ne $r2->{unconvolved});
-
-    if (defined($r1->{COMPONENT})) {
-        return 0 if !defined $r2->{COMPONENT} or ($r1->{COMPONENT} ne $r2->{COMPONENT});
-    } elsif (defined($r2->{COMPONENT})) {
-        # if first row has no component all of the images will be retrieved, so
-        # the fact that this row has a component is ok. Fall through to return 1
-        # XXX Nope this doesn't work. It is consistent with the other logic in some way
-        # that i haven't fully thought through
-        return 0;
-    }
+    # don't combine requests in pixel coordinates
+    return 0 if (($r1->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS) || ($r2->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS));
 
     return 1;
@@ -911,5 +866,11 @@
 sub queue_update_run 
 {
-    my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $need_magic) = @_;
+    my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $component, $need_magic) = @_;
+
+    # XXX: The update process for warp and subsequent stages requires 
+    # destreaking to run because the -pending queries require it when magicked > 0
+    # queries. 
+    # The case of stack-stack diffs is taken care of in pstamp_checkdependent
+    $need_magic = 1 if $imagedb eq 'gpc1';
 
     if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) {
@@ -918,6 +879,13 @@
 
     my $dep_id;
-    my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb";
-    $command .= " -no_magic" if !$need_magic;
+    my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb -component $component -outdir $outdir";
+    $command .= " -need_magic" if $need_magic;
+
+    # compute rlabel for the run.
+    # XXX: This bit of policy shouldn't be buried so deeply in the code
+    # For now use one that implies 'postage stamp server' 'update' 'request_label"
+    my $rlabel = "ps_ud_" . $label if $label;
+    $command .= " -rlabel $rlabel" if $rlabel;
+
     if (!$no_update) {
         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -929,4 +897,6 @@
         chomp $output;
         $dep_id = $output;
+        #
+        # XXX: need to fault the request or something
         my_die("pstamptool -getdependent returned invalid dep_id", $PS_EXIT_PROG_ERROR) if !$dep_id;
     } else {
@@ -936,6 +906,6 @@
     
     $$r_dep_id = $dep_id;
-    $r_fault = 0;
-    $r_jobState = 'blocked';
+    $$r_fault = 0;
+    $$r_jobState = 'run';
 }
 
@@ -990,4 +960,4 @@
     # we don't fault the request here pstamp_parser_run.pl handles that if necessary
 
-    return $fault;
-}
+    exit $fault;
+}
Index: /branches/pap/pstamp/scripts/request_finish.pl
===================================================================
--- /branches/pap/pstamp/scripts/request_finish.pl	(revision 28002)
+++ /branches/pap/pstamp/scripts/request_finish.pl	(revision 28003)
@@ -21,5 +21,5 @@
 use PS::IPP::Config qw( :standard );
 
-my ( $req_id, $req_name, $req_file, $req_type, $out_dir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output );
+my ( $req_id, $req_name, $req_file, $req_type, $outdir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output );
 
 GetOptions(
@@ -28,5 +28,5 @@
            'req_file=s' => \$req_file,
            'req_type=s' => \$req_type,
-           'out_dir=s'  => \$out_dir,
+           'outdir=s'  => \$outdir,
            'product=s'  => \$product,
 	   'dbname=s'   => \$dbname,
@@ -46,15 +46,15 @@
 $err .= "--req_name is required\n" if !$req_name;
 $err .= "--product is required\n" if !$product;
-# $err .= "--out_dir is required\n" if !$out_dir;
+# $err .= "--outdir is required\n" if !$outdir;
 
 die "$err" if $err;
 
 
-if (!$out_dir) {
-    $out_dir = dirname($req_file);
+if (!$outdir) {
+    $outdir = dirname($req_file);
 }
 
 if ($redirect_output) {
-    my $logDest = "$out_dir/reqfinish.$req_id.log";
+    my $logDest = "$outdir/reqfinish.$req_id.log";
     my $ipprc = PS::IPP::Config->new();
     $ipprc->redirect_output($logDest);
@@ -79,5 +79,5 @@
 }
 if ($finish_cmd) {
-    my $command = $finish_cmd . " --req_id $req_id --req_name $req_name --req_file $req_file --product $product --out_dir $out_dir";
+    my $command = $finish_cmd . " --req_id $req_id --req_name $req_name --req_file $req_file --product $product --outdir $outdir";
     $command   .= " --dbname $dbname" if $dbname;
     $command   .= " --dbserver $dbserver" if $dbserver;
Index: /branches/pap/pstamp/src/ppstampMakeStamp.c
===================================================================
--- /branches/pap/pstamp/src/ppstampMakeStamp.c	(revision 28002)
+++ /branches/pap/pstamp/src/ppstampMakeStamp.c	(revision 28003)
@@ -36,13 +36,13 @@
     double d_before = check->sky->d;
     psLogMsg("ppstampMakeStamp", 2, "Before fit  Center Pixel RA: %f   DEC: %f (degrees)\n",
-	     r_before * PS_DEG_RAD, d_before * PS_DEG_RAD);
+             r_before * PS_DEG_RAD, d_before * PS_DEG_RAD);
 
     if (outFPA->toSky->type != PS_PROJ_TAN) {
-	// we need to make astrometry terms for the output which are centered on the output chip center,
-	// but we keep the original plate scale
-	psFree(outFPA->toSky);
-	outFPA->toSky = psProjectionAlloc (r_before, d_before, inFPA->toSky->Xs, inFPA->toSky->Ys, PS_PROJ_TAN);
-
-	if (!pmAstromLinearizeToSky(inFPA, inChip, outFPA, outChip, roi)) {
+        // we need to make astrometry terms for the output which are centered on the output chip center,
+        // but we keep the original plate scale
+        psFree(outFPA->toSky);
+        outFPA->toSky = psProjectionAlloc (r_before, d_before, inFPA->toSky->Xs, inFPA->toSky->Ys, PS_PROJ_TAN);
+
+        if (!pmAstromLinearizeToSky(inFPA, inChip, outFPA, outChip, roi)) {
             psFree(check);
             psError(PS_ERR_UNKNOWN, false, "Failed to linearize astrometry\n");
@@ -56,7 +56,7 @@
 
         psLogMsg("ppstampMakeStamp", 2, "After fit:  Center Pixel RA: %f   DEC: %f (degrees)\n",
-		 r_after * PS_DEG_RAD, d_after * PS_DEG_RAD);
-        psLogMsg("ppstampMakeStamp", 2, "Error in fit to astrometry %.2f    %.2f (arcseconds)\n", 
-		 (r_after - r_before) *  PS_DEG_RAD * 3600, (d_after - d_before) * PS_DEG_RAD * 3600);
+                 r_after * PS_DEG_RAD, d_after * PS_DEG_RAD);
+        psLogMsg("ppstampMakeStamp", 2, "Error in fit to astrometry %.2f    %.2f (arcseconds)\n",
+                 (r_after - r_before) *  PS_DEG_RAD * 3600, (d_after - d_before) * PS_DEG_RAD * 3600);
 
         // XXX: should we fail if the fit is bad ??
@@ -238,7 +238,6 @@
         return PS_EXIT_DATA_ERROR;
     }
-    char *fpaName = psMetadataLookupStr(NULL, input->fpa->concepts, "FPA.OBS"); // Name of FPA
     pmFPAview *outview = pmFPAviewAlloc(0);
-    pmFPAAddSourceFromView(output->fpa, fpaName, outview, output->format);
+    pmFPAAddSourceFromView(output->fpa, outview, output->format);
 
     outview->chip = 0;
Index: /branches/pap/pstamp/src/ppstampMosaic.c
===================================================================
--- /branches/pap/pstamp/src/ppstampMosaic.c	(revision 28002)
+++ /branches/pap/pstamp/src/ppstampMosaic.c	(revision 28003)
@@ -24,6 +24,5 @@
     pmChip  *inChip = pmFPAviewThisChip(view, input->fpa);
     if (!mChip->hdu && !mChip->parent->hdu) {
-        const char *name = psMetadataLookupStr(&status, input->fpa->concepts, "FPA.OBS"); // Name of FPA
-        pmFPAAddSourceFromView(mosaic->fpa, name, mosaicView, mosaic->format);
+        pmFPAAddSourceFromView(mosaic->fpa, mosaicView, mosaic->format);
     }
     psFree(mosaicView);
Index: /branches/pap/pstamp/test/detect_query_create
===================================================================
--- /branches/pap/pstamp/test/detect_query_create	(revision 28002)
+++ /branches/pap/pstamp/test/detect_query_create	(revision 28003)
@@ -16,4 +16,5 @@
      $output,			# Name of output table
      $query_id, 
+     $nostage,
      );
 
@@ -22,4 +23,5 @@
 	   'output|o=s'   => \$output,
 	   'query_id|q=s'  => \$query_id,
+           'nostage'      => \$nostage,
 ) or pod2usage( 2 );
 
@@ -61,4 +63,11 @@
         }
 ];
+unless(defined($nostage)) {
+    push @{ $header },        { name =>  'STAGE',
+				writetype => TSTRING,
+				comment => 'processing stage to examine',
+				value => undef
+    };
+}
 
 # Specification of columns to write
Index: /branches/pap/pswarp/src/pswarp.c
===================================================================
--- /branches/pap/pswarp/src/pswarp.c	(revision 28002)
+++ /branches/pap/pswarp/src/pswarp.c	(revision 28003)
@@ -86,5 +86,5 @@
 
         // Write out summary statistics
-        if (stats) {
+        if (stats && statsFile) {
             psMetadataAddF32(stats, PS_LIST_TAIL, "DT_WARP", 0, "Time for warp completion",
                              psTimerMark("pswarp"));
Index: /branches/pap/pswarp/src/pswarpDefine.c
===================================================================
--- /branches/pap/pswarp/src/pswarpDefine.c	(revision 28002)
+++ /branches/pap/pswarp/src/pswarpDefine.c	(revision 28003)
@@ -124,7 +124,6 @@
     }
 
-    const char *name = psMetadataLookupStr(NULL, input->fpa->concepts, "FPA.OBS"); ///< Name of FPA
     view->chip = view->cell = view->readout = -1;
-    pmFPAAddSourceFromView(output->fpa, name, view, output->format);
+    pmFPAAddSourceFromView(output->fpa, view, output->format);
 
     psFree (view);
Index: /branches/pap/tools/checkexp
===================================================================
--- /branches/pap/tools/checkexp	(revision 28003)
+++ /branches/pap/tools/checkexp	(revision 28003)
@@ -0,0 +1,208 @@
+#!/usr/bin/env perl
+# 
+# query the summit data store and the gpc1 database to get information as to
+# the status of summit copy and registration for "today's" exposures.
+# Optionally start and end dates may be applied.
+#
+
+use strict;
+use warnings;
+
+use DBI;
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+use PS::IPP::Config 1.0.1 qw( :standard );
+
+my $ipprc =  PS::IPP::Config->new(); # IPP Configuration
+my $siteConfig = $ipprc->{_siteConfig};
+
+my $startDate;
+my $endDate;
+my $verbose;
+my $dbname = "gpc1";
+
+GetOptions(
+           'start|s=s'    => \$startDate,
+           'end|e=s'      => \$endDate,
+           'dbname|d=s'   => \$dbname,
+           'verbose|v'    => \$verbose,
+) or pod2usage( 0 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+#pod2usage( -msg => "Required options: --start",
+#           -exitval => 3)
+#    unless defined $startDate;
+
+my $dbh  = getDBHandle($ipprc, $dbname);
+
+# if startDate not provided use today
+if (!$startDate) {
+    my ($sec, $min, $hour, $mday, $month, $year) = gmtime;
+    $year += 1900;
+    $month += 1;
+    $startDate = sprintf "%4d-%02d-%02d", $year, $month, $mday;
+}
+
+
+# find all exposures in summitExp
+my $query = "SELECT exp_name, summitExp.dateobs AS registered, rawExp.dateobs, summitExp.imfiles,
+        summitExp.fault AS summit_fault, 
+        pzDownloadExp.state AS download_state, count(pzDownloadImfile.class_id) AS download_count,
+        newExp.state AS newExp_state, newExp.exp_id
+        FROM summitExp LEFT JOIN pzDownloadExp USING(exp_name) 
+            LEFT JOIN pzDownloadImfile USING(exp_name) 
+            LEFT JOIN newExp ON exp_name = tmp_exp_name 
+            LEFT JOIN rawExp USING(exp_id, exp_name) ";
+
+if ($startDate) {
+    $query .= "  WHERE date(summitExp.dateobs) >= '$startDate'";
+    $query .= " AND date(summitExp.dateobs) <= '$endDate'" if $endDate;
+}
+
+$query .= " GROUP BY exp_name ORDER BY summitExp.dateobs";
+
+print "Summit Copy and Registration Status\n\n";
+my $scode = system "~bills/bin/croot";
+if ($scode) {
+    print STDERR "croot failed with $scode\n";
+    exit 1;
+}
+print "\n";
+
+my $se_stmt = $dbh->prepare($query);
+$se_stmt->execute();
+
+my @summit_exps;
+my @summit_faults;
+my @download_faults;
+my @register_faults;
+
+my $last_exp_name;
+my $last_exp_id;
+my $last_new_exp_name = "";
+my $last_new_exp_id = "";
+my $first_exp_id;
+my $first_exp_name;
+while (my $se_ref = $se_stmt->fetchrow_hashref()) {
+    push @summit_exps, $se_ref;
+
+    my $exp_name = $se_ref->{exp_name};
+    my $summit_fault = $se_ref->{summit_fault};
+    my $download_state = $se_ref->{download_state};
+    my $new_state = $se_ref->{newExp_state};
+    my $exp_id = $se_ref->{exp_id};
+    my $imfiles = $se_ref->{imfiles};
+    my $dateobs = $se_ref->{dateobs};
+    if ($summit_fault) {
+        push @summit_faults, $se_ref;
+    } elsif ( !$download_state or $download_state eq 'run' ) {
+        push @download_faults, $se_ref;
+    } elsif ( !$new_state or $new_state eq 'run' ) {
+        push @register_faults, $se_ref;
+    }
+    if (!$first_exp_name) {
+        $first_exp_id = $exp_id ? $exp_id : "null";
+        $first_exp_name = $exp_name;
+    }
+    if ($exp_name) {
+        $last_exp_name = $exp_name;
+        $last_exp_id = $exp_id ? $exp_id : "not done";
+        if ($last_exp_id ne "not done") {
+            $last_new_exp_id = $exp_id;
+            $last_new_exp_name = $exp_name;
+        }
+    }
+}
+
+my $numSummitExp = scalar @summit_exps;
+my $numSummitFaults = scalar @summit_faults;
+my $numDownloadFaults = scalar @download_faults;
+my $numRegisterFaults = scalar @register_faults;
+
+print "$numSummitExp summit exposures since $startDate";
+print " up to $endDate" if $endDate;
+print "\n";
+
+exit 0 if $numSummitExp == 0;
+
+if ($numSummitFaults) {
+  print "$numSummitFaults summit faults\n";
+  if ($verbose) {
+    print  "  exp_name         registered      fault\n";
+          # c4951g0003d   2009-04-30 12:39:34   110
+    foreach my $s (@summit_faults) {
+        printf "%-12s %20s %5d\n", $s->{exp_name}, $s->{registered}, $s->{summit_fault};
+    }
+  }
+}
+if ($numDownloadFaults) {
+  print "\n$numDownloadFaults incomplete downloads\n";
+  if ($verbose) {
+    print " exp_name    summit_imfiles downloaded imfiles  faulted\n";
+    my $stmt = $dbh->prepare("SELECT exp_name, count(fault) as fault_count  FROM pzDownloadImfile WHERE exp_name = ? AND fault > 0");
+    foreach my $p (@download_faults) {
+        $stmt->execute($p->{exp_name});
+        my $ref = $stmt->fetchrow_hashref();
+        printf "%-12s     %3d          %3d                %3d\n", 
+            $p->{exp_name} ? $p->{exp_name} : "null", 
+            $p->{imfiles} ? $p->{imfiles} : 0,
+            $p->{download_count} ? $p->{download_count} : 0,
+            $ref->{fault_count} ? $ref->{fault_count} : 0;
+    }
+  }
+}
+if ($numRegisterFaults) {
+ print "\n$numRegisterFaults exposures copied but not registered\n";
+ if ($verbose) {
+    my $stmt = $dbh->prepare("SELECT exp_id, count(class_id) as fault_count FROM rawImfile where exp_name = ? and fault > 0");
+    print " exp_name           exp_id  fault_count\n";
+         # c4895g0607o         57173       1
+
+    foreach my $r (@register_faults) {
+        my $exp_name = $r->{exp_name};
+        $stmt->execute($exp_name);
+        my $ref = $stmt->fetchrow_hashref();
+        my $exp_id = $ref->{exp_id};
+        $exp_id = "null" if !defined $exp_id;
+        
+        my $fault_count = $ref->{fault_count};
+        $fault_count = "null" if !defined $fault_count;
+        printf "%-12s %12s     %3d\n", $exp_name, $exp_id, $fault_count;
+    }
+  }
+}
+
+print "\n";
+
+print "first exposure:  $first_exp_name $first_exp_id\n";
+print "last copied:     $last_new_exp_name $last_new_exp_id\n"
+            if $last_new_exp_id ne $last_exp_id;
+print "last exposure:   $last_exp_name $last_exp_id\n";
+
+exit 0;
+
+
+sub getDBHandle {
+    my $ipprc = shift;
+    my $dbname = shift;
+    if (!$dbname) {
+        $dbname = metadataLookupStr($siteConfig, 'DBNAME');
+        if (($dbname eq 'XXX') or ($dbname eq "NONE")) {
+            $dbname = 'gpc1';
+        }
+    }
+    my $dbuser   = metadataLookupStr($siteConfig, 'DBUSER');
+    my $dbpass   = metadataLookupStr($siteConfig, 'DBPASSWORD');
+    my $dbserver = metadataLookupStr($siteConfig, 'DBSERVER');
+    exit ($PS_EXIT_CONFIG_ERROR) unless defined $dbserver and $dbname and $dbuser and $dbpass;
+
+
+    die "database enviornment not set up" unless defined($dbserver) and defined($dbuser)
+        and defined($dbpass) and defined($dbname);
+
+    my $dsn = "DBI:mysql:host=$dbserver;database=$dbname";
+
+    my $dbh = DBI->connect($dsn, $dbuser, $dbpass) or die "Cannot connect to server\n";
+
+    return $dbh;
+}
Index: /branches/pap/tools/czartool.pl
===================================================================
--- /branches/pap/tools/czartool.pl	(revision 28003)
+++ /branches/pap/tools/czartool.pl	(revision 28003)
@@ -0,0 +1,340 @@
+#!/usr/bin/perl -w
+
+use warnings;
+use strict;
+use PS::IPP::Config 1.01 qw( :standard );
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+use IPC::Cmd 0.36 qw( can_run run );
+use DBI;
+use constant DB_SOCKET => '/var/run/mysqld/mysqld.sock';
+use File::Temp qw(tempfile);
+
+my @states = ("full", "new", "drop", "wait", "fault");
+my $db = connectToDb();
+
+if (!$db) {die;}
+
+my @stdscienceLabels = `getLabels.pl -s stdscience`;
+my @distributionLabels = `getLabels.pl -s distribution`;
+
+checkAllLabels("new");
+printInstructions();
+
+poll();
+$db->disconnect();
+
+###########################################################################
+#
+# Prints simple instructions
+#
+###########################################################################
+sub printInstructions {
+
+    print "\n### Enter: (s)ervers (f)ull (n)ew (d)rop (w)ait (q)uit (l)abel, or label number from table above: ";
+}
+
+###########################################################################
+#
+# Polls waiting for input from user 
+#
+###########################################################################
+sub poll {
+
+    my $key;
+    system "stty cbreak < /dev/tty > /dev/tty 2>&1";
+    while (($key=getc) ) {
+        last if $key eq "q";
+
+        if ($key eq "s") {checkServers();}
+        elsif ($key eq "f") {checkAllLabels("full");}
+        elsif ($key eq "n") {checkAllLabels("new");}
+        elsif ($key eq "d") {checkAllLabels("drop");}
+        elsif ($key eq "w") {checkAllLabels("wait");}
+        elsif ($key eq "l") {labelDetails();}
+        elsif ($key eq "u") {serverStatus("stdscience");}
+        elsif ($key =~ m/[0-9]/) {my $key2=getc; checkOneLabel($stdscienceLabels[$key.$key2]);}
+        printInstructions();
+
+    };
+    system "stty -cbreak < /dev/tty > /dev/tty 2>&1";
+}
+
+###########################################################################
+#
+# Connects to the database
+#
+###########################################################################
+sub connectToDb {
+
+    my $dbname = 'gpc1';
+    my $dbserver = 'ippdb01';
+    my $dbuser = 'ippuser';
+    my $dbpass = 'ippuser';
+    my $db = DBI->connect(
+            "DBI:mysql:database=${dbname};host=${dbserver};mysql_socket=" .
+            DB_SOCKET(),${dbuser},${dbpass},
+            {
+            RaiseError => 1, AutoCommit => 1}
+            ) or die "Unable to connect to database $DBI::errstr\n";
+
+    return $db;
+}
+
+###########################################################################
+#
+# Compares two arrays and stores the differences
+#
+###########################################################################
+sub getArrayDifferences {
+
+    my @array1 = @{$_[0]};
+    my @array2 = @{$_[1]};
+
+    my @isect;
+    my @diff;
+    my %count;
+
+    my $item;
+    foreach $item (@array1, @array2) {$count{$item}++;}
+
+    foreach $item (keys %count) {
+        if ($count{$item} == 2) {
+            push @isect, $item;
+        } else {
+            push @diff, $item;
+        }
+    }
+
+    return \@diff;
+}
+
+###########################################################################
+#
+# Prints the status of a given pantasks server
+#
+###########################################################################
+sub serverStatus {
+    my ($server) = @_;
+
+    my @cmdOut = `echo "status;quit" | pantasks_client -c ~ipp/$server/ptolemy.rc 2>&1`;
+    my $line;
+    foreach $line (@cmdOut) {
+
+        chomp($line);
+    
+        print "$line\n";
+    }
+}
+
+###########################################################################
+#
+# Checks all servers to see if they are alive and running
+#
+###########################################################################
+sub checkServers {
+
+    my @servers = ("addstar", "cleanup", "detrend", "distribution", "pstamp", "publishing", "registration", "replication", "stdscience", "summitcopy");
+    printf("\n+-----------------------------------------------+\n");
+    printf("|                      Servers                  |\n");
+    printf("+--------------+---------+----------------------+\n");
+    printf("|    server    |  alive? |  Scheduler running?  |\n");
+    printf("+--------------+---------+----------------------+\n");
+    my $server;
+    foreach $server (@servers) {
+
+        my @results = `checkServer.pl -s $server`;
+
+        printf("| %12s ", $server);
+        chomp($results[0]);
+        chomp($results[1]); 
+        printf("|   %3s   |         %3s          |\n", $results[0], $results[1]);
+    }
+
+    printf("+--------------+---------+----------------------+\n");
+}
+
+###########################################################################
+#
+# Takes label name or number
+#
+###########################################################################
+sub labelDetails {
+
+    print "\nPlease enter the label name, or number from table above: ";
+    my $input = <STDIN>;
+    chomp($input);
+    if ($input =~ m/^([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$/) {
+       return checkOneLabel($stdscienceLabels[$input]);
+    }
+
+    checkOneLabel($input);
+}
+
+###########################################################################
+#
+# Checks one label and prints results in a table
+#
+###########################################################################
+sub checkOneLabel {
+    my ($label) = @_;
+
+    chomp($label);
+
+    printf("\n+-------------------------------------------------------------------------------------+\n");
+    printf("|                        %32s                             |\n", $label);
+    printf("+------------+-------+-------+-------+-------+-------+-------+-------+--------+-------+\n");
+    printf("|   state    |  chip |  cam  |  fake | warp  | stack |  diff | magic |destreak|  dist |\n");
+    printf("+------------+-------+-------+-------+-------+-------+-------+-------+--------+-------+\n");
+
+    my $state;
+    my $i=0;
+    foreach $state (@states) {
+
+        chomp($label);
+        printf("| %10s ", $state);
+        printf("| %5d ", checkLabel($label, "chipRun", $state, "chip"));
+        printf("| %5d ", checkLabel($label, "camRun", $state, "cam"));
+        printf("| %5d ", checkLabel($label, "fakeRun", $state, "fake"));
+        printf("| %5d ", checkLabel($label, "warpRun", $state, "warp"));
+        printf("| %5d ", checkLabel($label, "stackRun", $state, "stack"));
+        printf("| %5d ", checkLabel($label, "diffRun", $state, "diff"));
+        printf("| %5d ", checkLabel($label, "magicRun", $state, "magic"));
+        printf("| %6d ", checkLabel($label, "magicDSRun", $state, "magicDS"));
+        printf("| %5d ", checkLabel($label, "distRun", $state, "dist"));
+        printf("|\n");
+        $i++;
+    }
+
+    printf("+------------+-------+-------+-------+-------+-------+-------+-------+--------+-------+\n");
+
+}
+
+###########################################################################
+#
+# Checks all labels for a particular state and prints results in a table
+#
+###########################################################################
+sub checkAllLabels {
+    my ($state) = @_;
+#print time, $/;
+    printf("\n+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n");
+    printf("|                                                                           %10s (any faults are shown in parentheses)                                                  |\n", $state);
+    printf("+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+\n");
+    printf("| no  |              label               | distributing? |    chip    |    cam     |    fake    |    warp    |   stack    |    diff    |   magic    |  destreak  |    dist    |\n");
+    printf("+-----+----------------------------------+---------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+\n");
+
+    my $stdsLabel;
+    my $distLabel;
+    my $i=0;
+    my $distributing;
+    foreach $stdsLabel (@stdscienceLabels) {
+
+    $distributing = 0;
+        foreach $distLabel (@distributionLabels) {
+            chomp($stdsLabel);
+            if ($stdsLabel eq $distLabel) { $distributing = 1; last;}
+
+
+        }
+        chomp($stdsLabel);
+        printf("| %3d ", $i);
+        printf("| %32s ", $stdsLabel);
+        printf("| %10s    ", $distributing ? "yes" : "NO" );
+        printf("| %10s ", getStateAndFaults($stdsLabel, "chipRun", $state, "chip"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "camRun", $state, "cam"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "fakeRun", $state, "fake"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "warpRun", $state, "warp"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "stackRun", $state, "stack"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "diffRun", $state, "diff"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "magicRun", $state, "magic"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "magicDSRun", $state, "magicDS"));
+        printf("| %10s ", getStateAndFaults($stdsLabel, "distRun", $state, "dist"));
+        printf("|\n");
+        $i++;
+    }
+
+    printf("+-----+----------------------------------+---------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+\n");
+
+}
+
+###########################################################################
+#
+# Returns state and fault-count (if new) as a string
+#
+###########################################################################
+sub getStateAndFaults {
+    my ($label, $table, $state, $stage) = @_;
+
+    my $new = checkLabel($label, $table, $state, $stage);
+
+    if ($state ne "new") {return $new;}
+
+    my $faults = countFaults($label,$table,$stage);
+
+    if ($faults < 1) {return $new;}
+
+    return $new."(".$faults.")";
+}
+
+###########################################################################
+#
+# Returns count of exposures with this state for this label
+#
+###########################################################################
+sub checkLabel {
+    my ($label, $table, $state, $stage) = @_;
+
+    if ($state eq "fault") {return countFaults($label, $table, $stage);}
+
+    my $query = $db->prepare(<<SQL);
+    SELECT count(state)  
+        FROM $table 
+        WHERE label LIKE '$label' 
+        AND state = '$state'
+
+SQL
+
+        $query->execute;
+    return scalar $query->fetchrow_array();
+}
+
+###########################################################################
+#
+# Returns count of faults for this stage and label
+#
+###########################################################################
+sub countFaults {
+    my ($label, $table, $stage) = @_;
+
+    my $joinTable;
+    my $id = $stage."_id";
+
+    if ($stage eq "chip") {$joinTable="chipProcessedImfile";}
+    elsif ($stage eq "cam") {$joinTable="camProcessedExp";}
+    elsif ($stage eq "fake") {$joinTable="fakeProcessedImfile";}
+    elsif ($stage eq "warp") {$joinTable="warpSkyfile";}
+    elsif ($stage eq "stack") {$joinTable="stackSumSkyfile";}
+    elsif ($stage eq "diff") {$joinTable="diffSkyfile";}
+    elsif ($stage eq "magic") {$joinTable="magicNodeResult";}
+    elsif ($stage eq "magicDS") {$id = "magic_ds_id"; $joinTable="magicDSFile";}
+    elsif ($stage eq "dist") {$joinTable="distComponent";}
+    else {return -1;}
+
+    my $faultCol =  $joinTable.".fault";
+    my $stateCol =  $table.".state";
+
+    my $query = $db->prepare(<<SQL);
+    SELECT COUNT(DISTINCT $id) 
+        FROM $table
+        JOIN $joinTable USING ($id)
+        WHERE label LIKE '$label'
+        AND $faultCol != 0
+        AND $stateCol = 'new'
+
+SQL
+
+        $query->execute;
+    return scalar $query->fetchrow_array();
+}
+
Index: /branches/pap/tools/diff_outputs.pl
===================================================================
--- /branches/pap/tools/diff_outputs.pl	(revision 28002)
+++ /branches/pap/tools/diff_outputs.pl	(revision 28003)
@@ -19,6 +19,6 @@
                            'ALL' => [ 'IMAGE', 'MASK', 'VARIANCE', 'SOURCES', 'JPEG1', 'JPEG2', 'KERNEL',
                                       'INVERSE.IMAGE', 'INVERSE.MASK', 'INVERSE.VARIANCE', 'INVERSE.SOURCES',
-                                      'INCONV.IMAGE', 'INCONV.MASK', 'INCONV.VARIANCE',
-                                      'REFCONV.IMAGE', 'REFCONV.MASK', 'REFCONV.VARIANCE',
+#                                      'INCONV.IMAGE', 'INCONV.MASK', 'INCONV.VARIANCE',
+#                                      'REFCONV.IMAGE', 'REFCONV.MASK', 'REFCONV.VARIANCE',
                                       'LOG',
                                ],
Index: /branches/pap/tools/errors.pl
===================================================================
--- /branches/pap/tools/errors.pl	(revision 28002)
+++ /branches/pap/tools/errors.pl	(revision 28003)
@@ -12,4 +12,5 @@
 my ($db_host, $db_name, $db_user, $db_pw); # Database details
 my ($label);                               # Label
+my ($group);                               # Data group
 my ($stage);                               # Stage of interest
 my ($fault);                               # Fault code of interest
@@ -23,4 +24,5 @@
            'stage=s' => \$stage, # Stage
            'label=s@' => \$label, # Label(s)
+           'data_group=s@' => \$group, # Data group(s)
            'fault=s' => \$fault, # Fault code
            'limit=s' => \$limit, # Limit to query
@@ -49,5 +51,5 @@
 my $label_table;                # Table with label
 if ($stage eq "diff") {
-    $sql = "SELECT diff_id, skycell_id, hostname, path_base FROM diffRun JOIN diffSkyfile USING(diff_id) WHERE fault != 0";
+    $sql = "SELECT diff_id, skycell_id, hostname, path_base FROM diffRun JOIN diffSkyfile USING(diff_id) WHERE fault != 0 AND state = 'new'";
     $label_table = "diffRun";
     $fault_table = "diffSkyfile";
@@ -82,4 +84,5 @@
 my $where = "";                 # WHERE restriction
 $where .= " AND ($label_table.label LIKE '" . join("' OR $label_table.label LIKE '", @$label) . "')" if defined $label;
+$where .= " AND ($label_table.data_group LIKE '" . join("' OR $label_table.data_group LIKE '", @$group) . "')" if defined $group;
 $where .= " AND $fault_table.fault = $fault" if defined $fault;
 
@@ -102,4 +105,5 @@
 my %neb_entry;
 my %variance;
+my %error_reading;
 my %unknown;
 my %bad;
@@ -199,4 +203,9 @@
             last;
         }
+        if ($line =~ /Error reading .*, (\S+)/) {
+            $error_reading{$name} = $1;
+            $found = 1;
+            last;
+        }
     }
     $unknown{$name} = $log unless $found;
@@ -207,105 +216,33 @@
 print "\n";
 
-if (scalar keys %assertion) {
-    print "Assertion failures: " . ( scalar keys %assertion ) . "\n";
-    foreach my $name (keys %assertion) {
-        print "$name: $assertion{$name}\n";
-    }
-    print "\n";
+print_failure(\%assertion, "Assertion failures");
+print_failure(\%cannot_find_file, "'Cannot find file' errors");
+print_failure(\%unable_access, "'Unable to access file' errors");
+print_failure(\%failed_real_name, "'Failed to determine real name' errors");
+print_failure(\%failed_close, "'Failed to close' errors");
+print_failure(\%transparencies, "'Unable to perform statistics on transparencies' errors");
+print_failure(\%couldnt_open_file, "'Could not open file' errors");
+print_failure(\%failed_read, "'Failed to read' errors");
+print_failure(\%no_instances_available, "'No instances available' errors");
+print_failure(\%neb_entry, "'Neb entry not found' errors");
+print_failure(\%variance, "'Variance renormalisation' errors");
+print_failure(\%error_reading, "'Error reading' errors");
+print_failure(\%unknown, "Unknown errors");
+print_failure(\%bad, "Bad logs");
+
+### Pau.
+
+sub print_failure
+{
+    my $data = shift;           # Data
+    my $desc = shift;           # Description
+
+    if (scalar keys %$data) {
+        print "$desc: " . (scalar keys %$data) . "\n";
+        foreach my $name (keys %$data) {
+            print "$name: $$data{$name}\n";
+        }
+        print "\n";
+    }
+    return 1;
 }
-
-if (scalar keys %cannot_find_file) {
-    print "'Cannot find file' errors: " . ( scalar keys %cannot_find_file ) . "\n";
-    foreach my $name (keys %cannot_find_file) {
-        print "$name: $cannot_find_file{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %unable_access) {
-    print "'Unable to access file' errors: " . ( scalar keys %unable_access ) . "\n";
-    foreach my $name (keys %unable_access) {
-        print "$name: $unable_access{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %failed_real_name) {
-    print "'Failed to determine real name' errors: " . ( scalar keys %failed_real_name ) . "\n";
-    foreach my $name (keys %failed_real_name) {
-        print "$name: $failed_real_name{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %failed_close) {
-    print "'Failed to close' errors: " . ( scalar keys %failed_close ) . "\n";
-    foreach my $name (keys %failed_close) {
-        print "$name: $failed_close{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %transparencies) {
-    print "'Unable to perform statistics on transparencies' errors: " . ( scalar keys %transparencies ) . "\n";
-    foreach my $name (keys %transparencies) {
-        print "$name: $transparencies{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %couldnt_open_file) {
-    print "'Could not open file' errors: " . ( scalar keys %couldnt_open_file ) . "\n";
-    foreach my $name (keys %couldnt_open_file) {
-        print "$name: $couldnt_open_file{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %failed_read) {
-    print "'failed to read' errors: " . ( scalar keys %failed_read ) . "\n";
-    foreach my $name (keys %failed_read) {
-        print "$name: $failed_read{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %no_instances_available) {
-    print "'no instances available' errors: " . ( scalar keys %no_instances_available ) . "\n";
-    foreach my $name (keys %no_instances_available) {
-        print "$name: $no_instances_available{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %neb_entry) {
-    print "'neb entry not found' errors: " . ( scalar keys %neb_entry ) . "\n";
-    foreach my $name (keys %neb_entry) {
-        print "$name: $neb_entry{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %variance) {
-    print "'variance renormalisation' errors: " . ( scalar keys %variance ) . "\n";
-    foreach my $name (keys %variance) {
-        print "$name: $variance{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %unknown) {
-    print "Unknown errors: " . ( scalar keys %unknown ) . "\n";
-    foreach my $name (keys %unknown) {
-        print "$name: $unknown{$name}\n";
-    }
-    print "\n";
-}
-
-if (scalar keys %bad) {
-    print "Bad logs: " . ( scalar keys %bad ) . "\n";
-    foreach my $name (keys %bad) {
-        print "$name: $bad{$name}\n";
-    }
-    print "\n";
-}
Index: /branches/pap/tools/gpc1_find_images.pl
===================================================================
--- /branches/pap/tools/gpc1_find_images.pl	(revision 28002)
+++ /branches/pap/tools/gpc1_find_images.pl	(revision 28003)
@@ -240,4 +240,5 @@
     @scan = ();
     if (exists($opt{R})||exists($opt{B})) {
+#	print STDERR "$exp_workdir $exp_name\n";
 	open(NLS,"neb-ls $exp_workdir/${exp_name}/ |") || die "can't neb-ls";
 	while (<NLS>) {
Index: /branches/pap/tools/publish_mops.pl
===================================================================
--- /branches/pap/tools/publish_mops.pl	(revision 28002)
+++ /branches/pap/tools/publish_mops.pl	(revision 28003)
@@ -67,5 +67,5 @@
     my $inverse = shift;        # Inverse diff?
 
-    my $exposure = $db->selectrow_hashref("SELECT DISTINCT exp_name, exp_id, chipInput.chip_id, camInput.cam_id, fakeInput.fake_id, warpInput.warp_id, zpt_obs, zpt_stdev, SQRT(sigma_ra*sigma_ra+sigma_dec*sigma_dec) AS astrom_rms FROM diffRun JOIN diffInputSkyfile USING(diff_id) JOIN warpRun AS warpTemplate ON warpTemplate.warp_id = warp1 JOIN fakeRun AS fakeTemplate ON fakeTemplate.fake_id = warpTemplate.fake_id JOIN camProcessedExp ON fakeTemplate.cam_id = camProcessedExp.cam_id JOIN warpRun AS warpInput ON warpInput.warp_id = " . ($inverse ? "warp2" : "warp1") . " JOIN fakeRun AS fakeInput ON fakeInput.fake_id = warpInput.fake_id JOIN camRun AS camInput ON camInput.cam_id = fakeInput.cam_id JOIN chipRun AS chipInput ON chipInput.chip_id = camInput.cam_id JOIN rawExp USING(exp_id) WHERE diff_id = $diff_id") or die "Unable to execute SQL: $DBI::errstr";
+    my $exposure = $db->selectrow_hashref("SELECT DISTINCT rawInput.exp_name, rawInput.exp_id, chipInput.chip_id, camInput.cam_id, fakeInput.fake_id, warpInput.warp_id, zpt_obs + 2.5*LOG10(rawTemplate.exp_time) AS zp, zpt_stdev, SQRT(sigma_ra*sigma_ra+sigma_dec*sigma_dec) AS astrom_rms FROM diffRun JOIN diffInputSkyfile USING(diff_id) JOIN warpRun AS warpTemplate ON warpTemplate.warp_id = warp1 JOIN fakeRun AS fakeTemplate ON fakeTemplate.fake_id = warpTemplate.fake_id JOIN camProcessedExp ON fakeTemplate.cam_id = camProcessedExp.cam_id JOIN camRun AS camTemplate ON camTemplate.cam_id = fakeTemplate.cam_id JOIN chipRun AS chipTemplate ON chipTemplate.chip_id = camTemplate.chip_id JOIN rawExp AS rawTemplate ON rawTemplate.exp_id = chipTemplate.exp_id JOIN warpRun AS warpInput ON warpInput.warp_id = " . ($inverse ? "warp2" : "warp1") . " JOIN fakeRun AS fakeInput ON fakeInput.fake_id = warpInput.fake_id JOIN camRun AS camInput ON camInput.cam_id = fakeInput.cam_id JOIN chipRun AS chipInput ON chipInput.chip_id = camInput.chip_id JOIN rawExp AS rawInput ON rawInput.exp_id = chipInput.exp_id WHERE diff_id = $diff_id") or die "Unable to execute SQL: $DBI::errstr";
 
     my $exp_name = $exposure->{exp_name};
@@ -75,5 +75,5 @@
     my $fake_id = $exposure->{fake_id};
     my $warp_id = $exposure->{warp_id};
-    my $zp = $exposure->{zpt_obs};
+    my $zp = $exposure->{zp};
     my $zp_err = $exposure->{zpt_stdev};
     my $astrom_rms = $exposure->{astrom_rms};
