Index: branches/eam_branches/ipp-20140813/Ohana/src/addstar/src/build_links.c
===================================================================
--- branches/eam_branches/ipp-20140813/Ohana/src/addstar/src/build_links.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/Ohana/src/addstar/src/build_links.c	(revision 37351)
@@ -1,3 +1,5 @@
 # include "addstar.h"
+
+# define myAbortF(FORMAT,...) { fprintf (stderr, FORMAT, __VA_ARGS__); abort(); }
 
 /* 
@@ -47,6 +49,5 @@
 
     if (N >= Nmeasure) {
-      fprintf (stderr, "overflow in init_measure_links\n");
-      abort ();
+      myAbort ("overflow in init_measure_links\n");
     }
   }
@@ -136,5 +137,5 @@
 Measure *sort_measure (Average *average, off_t Naverage, Measure *measure, off_t Nmeasure, off_t *next_meas) {
 
-  off_t i, k, n, N;
+  int i, k, n, N;
   Measure *tmpmeasure;
 
@@ -146,7 +147,7 @@
     average[i].measureOffset = N;
     for (k = 0; k < average[i].Nmeasure; k++, N++) {
-      if (n == -1) abort();
+      if (n == -1) myAbortF("invalid measureOffset for ave %d, measureOffset %d, measure %d\n", i, average[i].measureOffset, k);
       tmpmeasure[N] = measure[n]; 
-      if (measure[n].averef != i) abort();
+      if (measure[n].averef != i) myAbortF("invalid averef for ave %d, measureOffset %d, measure %d, averef %d\n", i, average[i].measureOffset, k, measure[n].averef);
       tmpmeasure[N].averef = i;
       n = next_meas[n];
@@ -175,6 +176,5 @@
       next_miss[N] = -1;
       if (N >= Nmissing) {
-	fprintf (stderr, "overflow in init_missing_links");
-	abort ();
+	myAbort ("overflow in init_missing_links");
       }
       N++;
@@ -253,6 +253,5 @@
 
     if (N >= Nlensing) {
-      fprintf (stderr, "overflow in init_lensing_links\n");
-      abort ();
+      myAbort ("overflow in init_lensing_links\n");
     }
     N++;
@@ -343,5 +342,5 @@
 Lensing *sort_lensing (Average *average, off_t Naverage, Lensing *lensing, off_t Nlensing, off_t *next_lens) {
 
-  off_t i, k, n, N;
+  int i, k, n, N;
   Lensing *tmplensing;
 
@@ -354,7 +353,7 @@
     average[i].lensingOffset = N;
     for (k = 0; k < average[i].Nlensing; k++, N++) {
-      if (n == -1) abort();
+      if (n == -1) myAbortF("invalid lensingOffset for ave %d, lensingOffset %d, lensing %d\n", i, average[i].lensingOffset, k);
       tmplensing[N] = lensing[n]; 
-      if (lensing[n].averef != i) abort();
+      if (lensing[n].averef != i) myAbortF("invalid averef for ave %d, lensingOffset %d, lensing %d, averef %d\n", i, average[i].lensingOffset, k, lensing[n].averef);
       tmplensing[N].averef = i;
       n = next_lens[n];
Index: branches/eam_branches/ipp-20140813/Ohana/src/addstar/src/resort_catalog.c
===================================================================
--- branches/eam_branches/ipp-20140813/Ohana/src/addstar/src/resort_catalog.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/Ohana/src/addstar/src/resort_catalog.c	(revision 37351)
@@ -82,5 +82,26 @@
       myAssert(average[averageSeq[i]].catID == measure[measureSeq[i]].catID, "object / detection mismatch");
 # if (1)
-      myAssert(average[averageSeq[i]].objID == measure[measureSeq[i]].objID, "object / detection mismatch");
+      // myAssert(average[averageSeq[i]].objID == measure[measureSeq[i]].objID, "object / detection mismatch");
+      // check if the objID is correct. if not, check if it is byte-swapped (this has happened) and repair if so.  
+      // otherwise, abort
+      if (average[averageSeq[i]].objID != measure[measureSeq[i]].objID) {
+	fprintf (stderr, "object / detection mismatch average.objID = %d, measure.objID = %d, catID: %d, detID: %d", 
+		 average[averageSeq[i]].objID, measure[measureSeq[i]].objID, 
+		 measure[measureSeq[i]].catID, measure[measureSeq[i]].detID);
+	int objIDalt = measure[measureSeq[i]].objID;
+	char *byte = (char *) &objIDalt;
+	char tmp;
+	tmp = byte[0]; byte[0] = byte[3]; byte[3] = tmp;
+	tmp = byte[1]; byte[1] = byte[2]; byte[2] = tmp;
+	if (average[averageSeq[i]].objID == objIDalt) {
+	  fprintf (stderr, "objID is byte-swapped, repairing\n");
+	  measure[measureSeq[i]].objID = average[averageSeq[i]].objID; // XXX I don't really like this...
+	} else if (measure[measureSeq[i]].objID == 0) {
+	  fprintf (stderr, "objID is 0, repairing\n");
+	  measure[measureSeq[i]].objID = average[averageSeq[i]].objID; // XXX I don't really like this...
+	} else {
+	  myAbort ("objID is NOT byte-swapped, aborting\n");
+	}
+      }
 # else
       // for reasons I do not understand, the mini dvodbs generated on stsci1X had a handful of detections with an inconsistency between averef and objID.  
Index: branches/eam_branches/ipp-20140813/ippScripts/Build.PL
===================================================================
--- branches/eam_branches/ipp-20140813/ippScripts/Build.PL	(revision 37350)
+++ branches/eam_branches/ipp-20140813/ippScripts/Build.PL	(revision 37351)
@@ -119,4 +119,5 @@
         scripts/ipp_apply_burntool.pl
         scripts/ipp_apply_burntool_single.pl
+        scripts/ipp_apply_burntool_fix.pl
         scripts/make_burntool_pcontrol.pl
         scripts/bundle_detrends.pl
Index: branches/eam_branches/ipp-20140813/ippScripts/MANIFEST
===================================================================
--- branches/eam_branches/ipp-20140813/ippScripts/MANIFEST	(revision 37350)
+++ branches/eam_branches/ipp-20140813/ippScripts/MANIFEST	(revision 37351)
@@ -43,4 +43,5 @@
 scripts/ipp_apply_burntool.pl
 scripts/ipp_apply_burntool_single.pl
+scripts/ipp_apply_burntool_fix.pl
 scripts/make_burntool_pcontrol.pl
 scripts/bundle_detrends.pl
Index: branches/eam_branches/ipp-20140813/ippScripts/scripts/ipp_apply_burntool_fix.pl
===================================================================
--- branches/eam_branches/ipp-20140813/ippScripts/scripts/ipp_apply_burntool_fix.pl	(revision 37351)
+++ branches/eam_branches/ipp-20140813/ippScripts/scripts/ipp_apply_burntool_fix.pl	(revision 37351)
@@ -0,0 +1,142 @@
+#! /usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Carp;
+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 );
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::List qw( parse_md_list );
+use PS::IPP::Config 1.01 qw( :standard );
+
+
+my $missing_tools;
+my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
+my $burntool = can_run('ipp_apply_burntool_single.pl') or (warn "Can't find ipp_burntool_apply_single.pl" and $missing_tools = 1);
+if ($missing_tools) {
+    warn("Can't find required tools.");
+    exit($PS_EXIT_CONFIG_ERROR);
+}
+
+my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
+
+my $save;
+my $exp_name;
+my $class_id;
+my $dbname = 'gpc1';
+my $camera = 'GPC1';
+my $verbose = 0;
+GetOptions(
+    'save=s'          => \$save,
+    'exp_name|e=s'    => \$exp_name,
+    'class_id|c=s'  => \$class_id,
+    'verbose|v'     => \$verbose,
+    'dbname=s'      => \$dbname,
+) or pod2usage( 2 );
+
+die "usage: $0 --exp_name (exp_name) --class_id (class_id)\n" unless $class_id and $exp_name;
+
+# Set up the commands we'll use:
+$regtool  .= " -dbname $dbname -exp_name $exp_name -class_id $class_id";
+$burntool .= " --dbname $dbname --camera $camera";
+
+# Check database entry for this to get the exp_id and image uri
+my $regData;
+{
+    my $command = "$regtool -processedimfile";
+    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);
+        carp("Unable to perform $command: $error_code");
+        exit $error_code;
+    }
+    my $list = $mdcParser->parse(join "", @$stdout_buf) or die("Unable to parse regtool metadata");
+    my $mdc = parse_md_list($list);
+    $regData = $mdc->[0];
+}
+
+my $exp_id = $regData->{exp_id};
+my $uri = $regData->{uri};
+
+die "failed to find exp_name in regtool output" unless $exp_name;
+die "failed to find uri in regtool output" unless $uri;
+
+# Construct burntool table name
+my $table;
+($table = $uri) =~ s/\.fits/\.burn\.tbl/;
+print "$table\n";
+
+# Look for the old table, and if it exists, move it out of the way and delete it so we can work from scratch.
+my $table_exists;
+{
+    my $command = "neb-stat $table";
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+        run(command => $command, verbose => $verbose);
+    if ($success) {
+        $table_exists = 1;
+    } else {
+        $table_exists = 0;
+    }
+}
+
+if ($table_exists) {
+    # file exists
+    my $moved = "$table.bad";
+    my $command = "neb-mv $table $moved";
+    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);
+        carp("Unable to perform $command: $error_code");
+        exit $error_code;
+    }
+    # don't care if this fails
+    &vsystem ("neb-rm --force $moved");
+}
+
+# Calculate the previous uri for the table by decrementing the nightly image sequence
+my $left = substr $exp_name, 0, 6;
+my $num = substr $exp_name, 6, 4;
+my $end = substr $exp_name, 10, 1;
+
+# print "$left $num $end\n";
+
+my $prev = $num - 1;
+my $prev_name = sprintf "$left%04d$end", $prev;
+
+my $prev_uri = $uri;
+$prev_uri =~ s/$exp_name/$prev_name/g;
+die "failed" unless $prev_uri;
+
+# Run the burntool command to generate the table.
+{
+    my $command = "$burntool --exp_id $exp_id --class_id $class_id --this_uri $uri --previous_uri $prev_uri";
+    $command .= " --verbose" if $verbose;
+    print "$command\n";
+    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);
+        carp("Unable to perform $command: $error_code");
+        exit $error_code;
+    }
+}
+
+# This isn't needed, but doesn't hurt anything.
+# Copy the table we just made to a local directory
+if (defined $save) {
+    my $nebfile = `neb-locate -p $table`; chomp $nebfile;
+    vsystem ("cp $nebfile $save");
+}
+
+
+exit 0;
+
+sub vsystem {
+    print STDERR "@_\n";
+    my $status = system ("@_");
+    $status;
+}
Index: branches/eam_branches/ipp-20140813/ippScripts/scripts/lap_science.pl
===================================================================
--- branches/eam_branches/ipp-20140813/ippScripts/scripts/lap_science.pl	(revision 37350)
+++ branches/eam_branches/ipp-20140813/ippScripts/scripts/lap_science.pl	(revision 37351)
@@ -1077,8 +1077,10 @@
 	&my_die("Unable to perform stacktool -definebyquery: $error_code", $lap_id);
     }
-    $stacks_made .= $mdcParser->parse_list(join "", @$stdout_buf) or
+    my $stacks_made_deep .= $mdcParser->parse_list(join "", @$stdout_buf) or
 	&my_die("unable to parse metadata from stacktool -definebyquery", $lap_id, "");    
 
-
+    # Append deep stacks to stacks so we can get a complete count later.
+    push @{ $stacks_made}, @{ $stacks_made_deep };
+    
     ## Determine the sass_id so we can record it in the database.
     $command = "$stacktool ";
Index: branches/eam_branches/ipp-20140813/ippconfig/gpc1/ppStack.config
===================================================================
--- branches/eam_branches/ipp-20140813/ippconfig/gpc1/ppStack.config	(revision 37350)
+++ branches/eam_branches/ipp-20140813/ippconfig/gpc1/ppStack.config	(revision 37351)
@@ -160,5 +160,5 @@
     STACK.TYPE              STR   DEEP_STACK  ## needed?
     PSF.INPUT.CLIP.SIMPLE   BOOL  True
-    PSF.INPUT.MAX           F32   7.0    # center/edge can vary 1-2 pix, prefer <6 pix but needs to be <7 pix for edges
+    PSF.INPUT.MAX           F32   10.0   # center/edge can vary 1-2 pix, prefer <6 pix but needs to be <10 pix for edges until code improved..
     PSF.INPUT.CLIP.NSIGMA   F32   100.0  # any change to inputs can greatly impact edge filling factor..
     PSF.INPUT.THRESH        F32   NAN
Index: branches/eam_branches/ipp-20140813/ippconfig/gpc1/psastro.config
===================================================================
--- branches/eam_branches/ipp-20140813/ippconfig/gpc1/psastro.config	(revision 37350)
+++ branches/eam_branches/ipp-20140813/ippconfig/gpc1/psastro.config	(revision 37351)
@@ -520,4 +520,6 @@
    PSASTRO.MAX.ERROR       	   F32   0.2  # in arcsec units, still liberal limit for well known astrometry for skycells
    PSASTRO.MIN.NSTAR       	   S32   10   # edges may not have many and require special treatment 
+
+   KH.CORRECT.APPLY              BOOL     FALSE
 END
 
@@ -555,6 +557,4 @@
    PSASTRO.MIN.NSTAR               S32   10   # edges may not have many and require special treatment 
 
-END
-
-
-
+   KH.CORRECT.APPLY              BOOL     FALSE
+END
Index: branches/eam_branches/ipp-20140813/psLib/src/math/psEllipse.c
===================================================================
--- branches/eam_branches/ipp-20140813/psLib/src/math/psEllipse.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psLib/src/math/psEllipse.c	(revision 37351)
@@ -134,4 +134,66 @@
     assert (isfinite(axes.major));
     assert (isfinite(axes.minor));
+
+    return axes;
+}
+// ellipse derotation (sx, sy, sxy) -> (major, minor, theta)
+psEllipseAxes psEllipseShapeToAxesWithErrors(psEllipseShape shape, psEllipseShape shapeErrors, double maxAR, psEllipseAxes *pShapeErrors)
+{
+    psEllipseAxes axes;
+    psEllipseAxes errors;
+
+    double f1 = 1.0 / PS_SQR(shape.sy) + 1.0 / PS_SQR(shape.sx);
+    double f2 = 1.0 / PS_SQR(shape.sy) - 1.0 / PS_SQR(shape.sx);
+
+    double f32 = PS_SQR(f2) + 4*PS_SQR(shape.sxy);
+    double f3 = sqrt(f32);
+
+    double df1 = - 2.0 * shapeErrors.sy / (PS_SQR(shape.sy) * shape.sy)
+                 - 2.0 * shapeErrors.sx / (PS_SQR(shape.sx) * shape.sx);
+    double df2 = - 2.0 * shapeErrors.sy / (PS_SQR(shape.sy) * shape.sy)
+                 + 2.0 * shapeErrors.sx / (PS_SQR(shape.sx) * shape.sx);
+
+    // df3 = 0.5 * df32 / sqrt(f32) = 0.5 * df32 / f3
+    double df3 = 0.5 * (2.0*f2*df2 + 2 * 4 * shape.sxy * shapeErrors.sxy) / f3;
+
+    double f13 = f1 + f3;
+    axes.minor = sqrt (2.0 / f13);
+
+    // dminor = -0.5 * sqrt (2) * df13 * f13**-3/2  = - 0.5 * df13 * minor / f13
+    errors.minor = - 0.5 * (df1 + df3) * axes.minor / f13;
+
+    axes.theta = -0.5 * atan2 (+2.0*shape.sxy, f2);
+
+    // according to wikipedia the derivitive of atan2(y, x) is
+    //
+    //  dAtan2(y, x) = - y * dx / (x**2 + y**2)) + x * dy / (x**2 + y**2) (for x > 0 and y!=0)
+    //  where
+    //  y = 2 * sxy  dy = 2 * dsxy   x = f2 so dx = df2
+
+    // dtheta = -0.5 * dAtan2(y, x)
+
+    errors.theta = -0.5 * ( -2.0 * shape.sxy * df2  +  f2 * 2 *shapeErrors.sxy ) / 
+                            (PS_SQR(f2) + 4 * PS_SQR(shape.sxy)) ;
+
+    // long, thin objects are likely to have a poorly measured major axis
+    // the angle and minor axis are likely to be ok.
+    // restrict the axis ratio
+    double rAR2 = (f1 - f3) / (f1 + f3);
+    if (rAR2 < 1.0/PS_SQR(maxAR)) {
+        axes.major = axes.minor * maxAR;
+        errors.major = errors.minor * maxAR;
+    } else {
+        axes.major = sqrt (2.0 / (f1 - f3));
+
+        // dmajor = -0.5 * (df1 - df3) * sqrt(2) * (f1 - f3)**-3/2
+        //        = -0.5 * (df2 - df3) * major / (f1 - f3)
+        errors.major = -0.5 * axes.major * (df1 - df3) / (f1 - f3);
+    }
+
+    assert (isfinite(axes.theta));
+    assert (isfinite(axes.major));
+    assert (isfinite(axes.minor));
+
+    *pShapeErrors = errors;
 
     return axes;
Index: branches/eam_branches/ipp-20140813/psLib/src/math/psEllipse.h
===================================================================
--- branches/eam_branches/ipp-20140813/psLib/src/math/psEllipse.h	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psLib/src/math/psEllipse.h	(revision 37351)
@@ -65,4 +65,11 @@
                                    );
 
+/// Convert shape to axes representation and compute errors
+psEllipseAxes psEllipseShapeToAxesWithErrors(psEllipseShape shape, ///< Shape of ellipse
+                                   psEllipseShape errors, ///<errors on shape params
+                                   double maxAR, ///< Maximum allowed axis ratio
+                                   psEllipseAxes *pShapeErrors ///< propagated errors on axes
+                                   );
+
 /// Convert axes to polarization representation
 psEllipsePol psEllipseAxesToPol(psEllipseAxes axes ///< Axes of ellipse
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/Makefile.am	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/Makefile.am	(revision 37351)
@@ -53,4 +53,5 @@
 	pmSourceIO_CMF_PS1_SV2.c \
 	pmSourceIO_CMF_PS1_SV3.c \
+	pmSourceIO_CMF_PS1_SV4.c \
 	pmSourceIO_CMF_PS1_DV1.c \
 	pmSourceIO_CMF_PS1_DV2.c \
@@ -157,5 +158,6 @@
 pmSourceIO_CMF_PS1_SV1.c \
 pmSourceIO_CMF_PS1_SV2.c \
-pmSourceIO_CMF_PS1_SV3.c
+pmSourceIO_CMF_PS1_SV3.c \
+pmSourceIO_CMF_PS1_SV4.c
 
 pmSourceIO_CMF_PS1_V1.c : pmSourceIO_CMF.c.in mksource.pl
@@ -195,3 +197,6 @@
 	mksource.pl pmSourceIO_CMF.c.in PS1_SV3 pmSourceIO_CMF_PS1_SV3.c
 
+pmSourceIO_CMF_PS1_SV4.c : pmSourceIO_CMF.c.in mksource.pl
+	mksource.pl pmSourceIO_CMF.c.in PS1_SV4 pmSourceIO_CMF_PS1_SV4.c
+
 # EXTRA_DIST = pmErrorCodes.h.in pmErrorCodes.dat pmErrorCodes.c.in
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/mksource.pl
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/mksource.pl	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/mksource.pl	(revision 37351)
@@ -29,4 +29,5 @@
 		"PS1_SV2", 2,
 		"PS1_SV3", 3,
+		"PS1_SV4", 4,
     );
 
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/pmSource.c
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/pmSource.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/pmSource.c	(revision 37351)
@@ -176,4 +176,7 @@
     source->parent = NULL;
     source->tmpPtr = NULL;
+    source->chipNum = -1;
+    source->chipX = -1000;
+    source->chipY = -1000;
     source->imageID = -1;
     source->nFrames = 0;
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/pmSource.h
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/pmSource.h	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/pmSource.h	(revision 37351)
@@ -127,4 +127,7 @@
     pmSource *parent;			///< reference to the master source from which this is derived
     psPtr *tmpPtr;                      ///< pointer that may be used to store data in a particular module. e.g. psphotKronIterate.
+    short chipNum;                      ///< camera dependent of chip suppling pixels for fullforce source
+    short chipX;                        ///< chip space X coord of fullforce source
+    short chipY;                        ///< chip space Y coord of fullforce source
     int imageID;
     psU16 nFrames;
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO.c
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO.c	(revision 37351)
@@ -602,4 +602,5 @@
 	    PM_SOURCES_WRITE("PS1_SV2",   CMF_PS1_SV2);
 	    PM_SOURCES_WRITE("PS1_SV3",   CMF_PS1_SV3);
+	    PM_SOURCES_WRITE("PS1_SV4",   CMF_PS1_SV4);
 	    PM_SOURCES_WRITE("PS1_DV1",   CMF_PS1_DV1);
 	    PM_SOURCES_WRITE("PS1_DV2",   CMF_PS1_DV2);
@@ -1124,4 +1125,5 @@
 	    PM_SOURCES_READ_PSF("PS1_SV2",   CMF_PS1_SV2);
 	    PM_SOURCES_READ_PSF("PS1_SV3",   CMF_PS1_SV3);
+	    PM_SOURCES_READ_PSF("PS1_SV4",   CMF_PS1_SV4);
 	    PM_SOURCES_READ_PSF("PS1_DV1",   CMF_PS1_DV1);
 	    PM_SOURCES_READ_PSF("PS1_DV2",   CMF_PS1_DV2);
@@ -1412,4 +1414,5 @@
 	PM_SOURCES_READ_XSRC("PS1_SV2",   CMF_PS1_SV2);
 	PM_SOURCES_READ_XSRC("PS1_SV3",   CMF_PS1_SV3);
+	PM_SOURCES_READ_XSRC("PS1_SV4",   CMF_PS1_SV4);
 	PM_SOURCES_READ_XSRC("PS1_DV1",   CMF_PS1_DV1);
 	PM_SOURCES_READ_XSRC("PS1_DV2",   CMF_PS1_DV2);
@@ -1454,4 +1457,5 @@
 	PM_SOURCES_READ_XFIT("PS1_SV2",   CMF_PS1_SV2);
 	PM_SOURCES_READ_XFIT("PS1_SV3",   CMF_PS1_SV3);
+	PM_SOURCES_READ_XFIT("PS1_SV4",   CMF_PS1_SV4);
 	PM_SOURCES_READ_XFIT("PS1_DV1",   CMF_PS1_DV1);
 	PM_SOURCES_READ_XFIT("PS1_DV2",   CMF_PS1_DV2);
@@ -1495,4 +1499,5 @@
 	PM_SOURCES_READ_XRAD("PS1_SV2",   CMF_PS1_SV2);
 	PM_SOURCES_READ_XRAD("PS1_SV3",   CMF_PS1_SV3);
+	PM_SOURCES_READ_XRAD("PS1_SV4",   CMF_PS1_SV4);
 	PM_SOURCES_READ_XRAD("PS1_DV1",   CMF_PS1_DV1);
 	PM_SOURCES_READ_XRAD("PS1_DV2",   CMF_PS1_DV2);
@@ -1536,4 +1541,5 @@
 	PM_SOURCES_READ_XGAL("PS1_SV2",   CMF_PS1_SV2);
 	PM_SOURCES_READ_XGAL("PS1_SV3",   CMF_PS1_SV3);
+	PM_SOURCES_READ_XGAL("PS1_SV4",   CMF_PS1_SV4);
 	PM_SOURCES_READ_XGAL("PS1_DV1",   CMF_PS1_DV1);
 	PM_SOURCES_READ_XGAL("PS1_DV2",   CMF_PS1_DV2);
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO.h
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO.h	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO.h	(revision 37351)
@@ -41,4 +41,5 @@
 MK_PROTO(CMF_PS1_SV2);
 MK_PROTO(CMF_PS1_SV3);
+MK_PROTO(CMF_PS1_SV4);
 MK_PROTO(CMF_PS1_DV1);
 MK_PROTO(CMF_PS1_DV2);
Index: branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO_CMF.c.in
===================================================================
--- branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO_CMF.c.in	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psModules/src/objects/pmSourceIO_CMF.c.in	(revision 37351)
@@ -221,4 +221,12 @@
 	  @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E2_SH_PSF",   PS_DATA_F32, "shear polarizability element (objects)",     source->lensingPSF->shear->e2); 
 	}
+
+        // if lensing params exist also include the backmapped chipID and chip coordinates
+	if (source->lensingPSF && source->lensingPSF->shear) {
+            @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "SRC_CHIP_NUM",   PS_DATA_S16, "id of warp input chip",     source->chipNum); 
+            @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "SRC_CHIP_X",    PS_DATA_S16, "x coord in warp input chip",     source->chipX); 
+            @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "SRC_CHIP_Y",    PS_DATA_S16, "y coord in warp input chip",     source->chipY); 
+            @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "PADDING3",      PS_DATA_S16, "more padding", 0);
+        }
 
         @>PS1_V2,PS1_SV?,>PS1_DV1@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1",       PS_DATA_F32, "first radial moment",                        moments.Mrf);
@@ -907,5 +915,5 @@
     }
 
-    @>PS1_DV2@ pmChip *chip = readout->parent->parent;
+    @>PS1_DV2,>PS1_SV3@ pmChip *chip = readout->parent->parent;
 
     pmModelStatus badModel = PM_MODEL_STATUS_NONE;
@@ -966,12 +974,12 @@
 	    }
 
-	    @>PS1_DV2@ psSphere ptSky = {0.0, 0.0, 0.0, 0.0};
-	    @>PS1_DV2@ float posAngle = 0.0;
-	    @>PS1_DV2@ float pltScale = 0.0;
-	    @>PS1_DV2@ pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos);
-	    @>PS1_DV2@ double raPos = ptSky.r*PS_DEG_RAD;
-	    @>PS1_DV2@ double decPos = ptSky.d*PS_DEG_RAD;
-	    @>PS1_DV2@ posAngle *= PS_DEG_RAD;
-	    @>PS1_DV2@ pltScale *= PS_DEG_RAD*3600.0;
+	    @>PS1_DV2,>PS1_SV3@ psSphere ptSky = {0.0, 0.0, 0.0, 0.0};
+	    @>PS1_DV2,>PS1_SV3@ float posAngle = 0.0;
+	    @>PS1_DV2,>PS1_SV3@ float pltScale = 0.0;
+	    @>PS1_DV2,>PS1_SV3@ pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos);
+	    @>PS1_DV2,>PS1_SV3@ double raPos = ptSky.r*PS_DEG_RAD;
+	    @>PS1_DV2,>PS1_SV3@ double decPos = ptSky.d*PS_DEG_RAD;
+	    @>PS1_DV2,>PS1_SV3@ posAngle *= PS_DEG_RAD;
+	    @>PS1_DV2,>PS1_SV3@ pltScale *= PS_DEG_RAD*3600.0;
 
 	    float kronFlux = source->moments ? source->moments->KronFlux : NAN;
@@ -987,6 +995,6 @@
             psMetadataAddF32 (row, PS_LIST_TAIL, "X_EXT_SIG",        0, "Sigma in EXT x coordinate",                  xErr);
             psMetadataAddF32 (row, PS_LIST_TAIL, "Y_EXT_SIG",        0, "Sigma in EXT y coordinate",                  yErr);
-            @>PS1_DV2@ psMetadataAddF32 (row, PS_LIST_TAIL, "RA_EXT",           0, "EXT model ra coordinate",                    raPos);
-            @>PS1_DV2@ psMetadataAddF32 (row, PS_LIST_TAIL, "DEC_EXT",          0, "EXT model dec coordinate",                   decPos);
+            @>PS1_DV2,>PS1_SV3@ psMetadataAddF32 (row, PS_LIST_TAIL, "RA_EXT",           0, "EXT model ra coordinate",                    raPos);
+            @>PS1_DV2,>PS1_SV3@ psMetadataAddF32 (row, PS_LIST_TAIL, "DEC_EXT",          0, "EXT model dec coordinate",                   decPos);
 	    @>PS1_DV2@ float instFlux = isfinite(model->mag) ? pow(10.0, -0.4*model->mag) : NAN;
 	    @>PS1_DV2@ psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_FLUX",    0, "EXT fit instrumental counts",                instFlux);
Index: branches/eam_branches/ipp-20140813/psphot/src/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20140813/psphot/src/Makefile.am	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psphot/src/Makefile.am	(revision 37351)
@@ -97,6 +97,6 @@
 # generalized forced photometry (including Kron, Petro, and Models) of specified positions given a specified psf
 psphotFullForce_SOURCES = \
-        psphotFullForce.c             \
-	psphotFullForceArguments.c    \
+        psphotFullForce.c          \
+	psphotFullForceArguments.c \
 	psphotParseCamera.c        \
 	psphotImageLoop.c	   \
@@ -259,5 +259,6 @@
 	psphotEfficiency.c	       \
 	psphotSetNFrames.c	       \
-	psphotSourceMemory.c
+	psphotSourceMemory.c	       \
+	psphotChipParams.c
 
 # not currently used
Index: branches/eam_branches/ipp-20140813/psphot/src/psphot.h
===================================================================
--- branches/eam_branches/ipp-20140813/psphot/src/psphot.h	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psphot/src/psphot.h	(revision 37351)
@@ -571,6 +571,10 @@
 bool psphotSourceMemoryReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index);
 
+bool psphotChipParams(pmConfig *config, const pmFPAview *view, const char *filerule);
+bool psphotChipParams_Threaded(psThreadJob *job);
+
 const char * psphotGetFilerule(const char *baseRule);
 extern bool psphotINpsphotStack;
 
+
 #endif
Index: branches/eam_branches/ipp-20140813/psphot/src/psphotChipParams.c
===================================================================
--- branches/eam_branches/ipp-20140813/psphot/src/psphotChipParams.c	(revision 37351)
+++ branches/eam_branches/ipp-20140813/psphot/src/psphotChipParams.c	(revision 37351)
@@ -0,0 +1,293 @@
+# include "psphotInternal.h"
+
+bool psphotChipParamsReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char *filerule, pmReadout *readout, psArray *sources);
+bool psphotChipParams_Threaded (psThreadJob *job);
+bool psphotChipParamsSource (pmSource *source, psArray *backmaps);
+
+typedef struct {
+    int         index;
+    short       chipNum;
+    psString    name;
+    float       C0x;
+    float       C1x;
+    float       C2x;
+    float       C0y;
+    float       C1y;
+    float       C2y;
+    int         xMin;
+    int         xMax;
+    int         yMin;
+    int         yMax;
+} psphotChipBackmap ;
+
+psArray * psphotChipParamsParseBackmaps(pmReadout *readout);
+
+bool psphotChipParams (pmConfig *config, const pmFPAview *view, const char *filerule)
+{
+    bool status = true;
+
+    fprintf (stdout, "\n");
+    psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Chip Parameters ---");
+
+    // select the appropriate recipe information
+    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
+    psAssert (recipe, "missing recipe?");
+
+    int num = psphotFileruleCount(config, filerule);
+
+    // skip the chisq image (optionally?)
+    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
+    if (!status) chisqNum = -1;
+
+    // loop over the available readouts
+    for (int i = 0; i < num; i++) {
+        if (i == chisqNum) continue; // skip chisq image
+
+        // find the currently selected readout
+        pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i); // File of interest
+        psAssert (file, "missing file?");
+
+        pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
+        psAssert (readout, "missing readout?");
+
+        pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
+        psAssert (detections, "missing detections?");
+
+        psArray *sources = detections->newSources ? detections->newSources : detections->allSources;
+        psAssert (sources, "missing sources?");
+
+        if (!psphotChipParamsReadout (config, recipe, view, filerule, readout, sources)) {
+            psError (PSPHOT_ERR_CONFIG, false, "failed to measure magnitudes for %s entry %d", filerule, i);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool psphotChipParamsReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char *filerule, pmReadout *readout, psArray *sources) {
+
+    bool status = false;
+
+    if (!sources->n) {
+        psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping chipParams");
+        return true;
+    }
+
+    psTimerStart ("psphot.chipparams");
+
+    // determine the number of allowed threads
+    int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
+    if (!status) {
+        nThreads = 0;
+    }
+    psArray *backmaps = psphotChipParamsParseBackmaps(readout);
+    if (!backmaps) {
+        psError (PSPHOT_ERR_UNKNOWN, false, "failed to parse chip backmaps  for %s", filerule);
+        return false;
+    }
+
+    // threaded measurement of the source magnitudes
+    // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)
+    int Cx = 1, Cy = 1;
+    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
+
+    psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);
+
+    for (int i = 0; i < cellGroups->n; i++) {
+
+        psArray *cells = cellGroups->data[i];
+
+        for (int j = 0; j < cells->n; j++) {
+
+            // allocate a job -- if threads are not defined, this just runs the job
+            psThreadJob *job = psThreadJobAlloc ("PSPHOT_CHIP_PARAMS");
+
+            psArrayAdd(job->args, 1, cells->data[j]); // sources
+            psArrayAdd(job->args, 1, backmaps); // sources
+
+// set this to 0 to run without threading
+# if (1)
+            if (!psThreadJobAddPending(job)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+                psFree(backmaps);
+                return false;
+            }
+# else
+	    if (!psphotChipParams_Threaded(job)) {
+		psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+		// psFree(AnalysisRegion);
+                psFree(backmaps);
+		return false;
+	    }
+	    psFree(job);
+# endif
+        }
+
+        // wait for the threads to finish and manage results
+        if (!psThreadPoolWait (false, true)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
+            psFree(backmaps);
+            return false;
+        }
+
+        // we have only supplied one type of job, so we can assume the types here
+        psThreadJob *job = NULL;
+        while ((job = psThreadJobGetDone()) != NULL) {
+            if (job->args->n < 1) {
+                fprintf (stderr, "error with job\n");
+            }
+            psFree(job);
+        }
+    }
+    psFree (cellGroups);
+    psFree(backmaps);
+
+    psLogMsg ("psphot.chip.params", PS_LOG_WARN, "measure chip paramters : %f sec for %ld objects\n", psTimerMark ("psphot.chipparams"), sources->n);
+    return true;
+}
+
+bool psphotChipParams_Threaded (psThreadJob *job) {
+
+    psArray *sources                = job->args->data[0];
+    psArray *backmaps               = job->args->data[1];
+
+    for (int i = 0; i < sources->n; i++) {
+	pmSource *source = sources->data[i];
+	if (!source->peak) continue; // XXX how can we have a peak-less source?
+
+        psphotChipParamsSource(source, backmaps);
+    }
+
+    return true;
+}
+
+
+bool psphotChipParamsSource (pmSource *source, psArray *backmaps) {
+
+    PS_ASSERT_PTR_NON_NULL(source, false);
+    PS_ASSERT_PTR_NON_NULL(source->peak, false);
+    PS_ASSERT_PTR_NON_NULL(source->pixels, false);
+
+    float warp_x = source->peak->xf;
+    float warp_y = source->peak->yf;
+
+    int chipForSource = -1;
+    for (int i=0; i < backmaps->n; i++) {
+        psphotChipBackmap *thisChip = backmaps->data[i];
+
+        float chip_x = thisChip->C0x + thisChip->C1x * warp_x + thisChip->C2x * warp_y;
+        float chip_y = thisChip->C0y + thisChip->C1y * warp_x + thisChip->C2y * warp_y;
+        if (chip_x >= thisChip->xMin && chip_x <= thisChip->xMax &&
+            chip_y >= thisChip->yMin && chip_y <= thisChip->yMax) {
+
+            chipForSource = thisChip->chipNum;
+            if (0) {
+                printf("source %8d on chip: %s %2d at %6.1f, %6.1f\n", source->chipNum, thisChip->name, 
+                    chipForSource, chip_x, chip_y);
+            }
+            source->chipNum = chipForSource;
+            source->chipX = chip_x;
+            source->chipY = chip_y;
+            // Since it is on this chip we are done for this source
+            break;
+        }
+    }
+    if (chipForSource < 0) return false;
+
+    return true;
+}
+
+
+psArray * psphotChipParamsParseBackmaps(pmReadout *readout) {
+
+    // XXX: I'm assuming the structure of the FPA here. Find a more usual way
+    // to find header
+    psMetadata *header = readout->parent->parent->parent->hdu->header;
+    if (!header) {
+        psError(PS_ERR_UNKNOWN, true, "Unable to find header for readout.");
+        return NULL;
+    }
+
+    psArray *backmaps = psArrayAllocEmpty(6);
+
+    // find the keywords that define the warp to chip transformations stored by
+    // pswarpUpdateMetadata()
+
+    for (int i = 0; ; i++) {
+        bool mdok;
+        char keyword[16];
+
+        sprintf(keyword, "SRC_%04d", i);
+        psString chipName = psMetadataLookupStr(&mdok, header, keyword);
+        if (!chipName) {
+            break;
+        }
+        psphotChipBackmap *thisChip = psAlloc(sizeof(psphotChipBackmap));
+        psArrayAdd(backmaps, 1, thisChip);
+        psFree(thisChip);
+
+        thisChip->index = i;
+        thisChip->name = chipName; // not incrementing the reference this gets freed before header
+
+        // XXX: If chipName begins with XY assume gpc1 style class_id and use number as ID
+        if (!strncmp(chipName, "XY", 2)) {
+            thisChip->chipNum = atoi(chipName+2);
+        } else {
+            // otherwise just use the index
+            thisChip->chipNum = thisChip->index;
+        }
+
+        sprintf(keyword, "SEC_%04d", i);
+        psString chipRegionStr = psMetadataLookupStr(&mdok, header, keyword);
+        if (!chipRegionStr) {
+            psError(PS_ERR_UNKNOWN, true, "failed to find required keyword %s", keyword);
+            psFree(backmaps);
+            return NULL;
+        }
+        int nvals = sscanf(chipRegionStr, "[%d:%d,%d:%d]", &thisChip->xMin, &thisChip->xMax, &thisChip->yMin, &thisChip->yMax);
+        if (nvals != 4) {
+            psError(PS_ERR_UNKNOWN, true, "failed to parse %s: %s", keyword, chipRegionStr);
+            psFree(backmaps);
+            return NULL;
+        }
+        // convert from fits extent convention to zero offset array
+        #define COORD_SLACK 2
+        thisChip->xMin -= COORD_SLACK; thisChip->xMax += COORD_SLACK; 
+        thisChip->yMin -= COORD_SLACK; thisChip->yMax += COORD_SLACK;
+
+        sprintf(keyword, "MPX_%04d", i);
+        psString mpx = psMetadataLookupStr(&mdok, header, keyword);
+        if (!mpx) {
+            psError(PS_ERR_UNKNOWN, true, "failed to find %s", keyword);
+            psFree(backmaps);
+            return NULL;
+        }
+        nvals = sscanf(mpx, "[%f,%f,%f]", &thisChip->C0x, &thisChip->C1x, &thisChip->C2x);
+        if (nvals != 3) {
+            psError(PS_ERR_UNKNOWN, true, "failed to parse %s: %s", keyword, mpx);
+            psFree(backmaps);
+            return NULL;
+        }
+        sprintf(keyword, "MPY_%04d", i);
+        psString mpy = psMetadataLookupStr(&mdok, header, keyword);
+        if (!mpy) {
+            psError(PS_ERR_UNKNOWN, true, "failed to find %s", keyword);
+            psFree(backmaps);
+            return NULL;
+        }
+        nvals = sscanf(mpy, "[%f,%f,%f]", &thisChip->C0y, &thisChip->C1y, &thisChip->C2y);
+        if (nvals != 3) {
+            psError(PS_ERR_UNKNOWN, true, "failed to parse %s: %s", keyword, mpx);
+            psFree(backmaps);
+            return NULL;
+        }
+    }
+
+    if (!backmaps->n) {
+        psFree(backmaps);
+        return NULL;
+    }
+
+    return backmaps;
+}
Index: branches/eam_branches/ipp-20140813/psphot/src/psphotFullForceReadout.c
===================================================================
--- branches/eam_branches/ipp-20140813/psphot/src/psphotFullForceReadout.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psphot/src/psphotFullForceReadout.c	(revision 37351)
@@ -106,4 +106,6 @@
     psphotKronFlux (config, view, filerule);
 
+    psphotChipParams (config, view, filerule);
+
     // measure petro fluxes
     psphotPetroFlux (config, view, filerule);
Index: branches/eam_branches/ipp-20140813/psphot/src/psphotSetThreads.c
===================================================================
--- branches/eam_branches/ipp-20140813/psphot/src/psphotSetThreads.c	(revision 37350)
+++ branches/eam_branches/ipp-20140813/psphot/src/psphotSetThreads.c	(revision 37351)
@@ -87,4 +87,9 @@
     psFree(task);
 
+    task = psThreadTaskAlloc("PSPHOT_CHIP_PARAMS", 2);
+    task->function = &psphotChipParams_Threaded;
+    psThreadTaskAdd(task);
+    psFree(task);
+
     return true;
 }
Index: branches/eam_branches/ipp-20140813/pstamp/scripts/pstamp_job_run.pl
===================================================================
--- branches/eam_branches/ipp-20140813/pstamp/scripts/pstamp_job_run.pl	(revision 37350)
+++ branches/eam_branches/ipp-20140813/pstamp/scripts/pstamp_job_run.pl	(revision 37351)
@@ -91,4 +91,6 @@
 my $ppBackgroundStack = can_run('ppBackgroundStack') or (warn "Can't find ppBackgroundStack" and $missing_tools = 1);
 my $stack_bkg_mk_mdc = can_run('stack_bkg_mk_mdc.pl') or (warn "Can't find stack_bkg_mk_mdc.pl" and $missing_tools = 1);
+my $fpack = can_run('fpack') or (warn "Can't find fpack" and $missing_tools = 1);
+
 
 if ($missing_tools) {
@@ -146,7 +148,4 @@
     my $mask;
     my $variance;
-
-    # We need to background restore HERE
-    # and change the image file supplied to ppstamp
 
     my $fileArgs = " -file $params->{image}";
@@ -224,5 +223,5 @@
 
     # unless the stage is stack_summary we use ppstamp to make postage stamps (including -wholefile)
-    # otherwise we make copies of the input files to the outputs
+    # if stage is stack_summary we make copies of the input files to the outputs
     my $use_ppstamp = ($stage ne 'stack_summary');
 
@@ -243,5 +242,86 @@
             $exitStatus = $PS_EXIT_SYS_ERROR;
         }
-        # XXX: if stage is stack deal with EXP and NUM images if selected
+
+        # if stage is stack deal with EXP and NUM images if selected by running ppstamp again
+        if (!$exitStatus and $stage eq 'stack' and ($options & ($PSTAMP_SELECT_EXP | $PSTAMP_SELECT_NUM))) {
+            # XXX Here I am assuming that nothing relevant gets added to $argString 
+            # Need to check
+            my $roiArgs = $params->{job_args};
+
+            # XXX: define expnum and exptime input images in the params file so that we don't have to
+            # make assumptions about the file rules here
+            my $pathBase = $params->{stack_path_base};
+            $pathBase = $params->{path_base} unless defined $pathBase;
+            unless (defined $pathBase) {
+                my_die("stack path base undefined found when creating exp or expnum image", $job_id, $PS_EXIT_PROG_ERROR);
+            }
+            $pathBase .= ".unconv";
+            my $tmpBase = "$outputBase.TMP";
+            # nocompress because exp image gets corrupted if we do
+            my $command = "$ppstamp $tmpBase $roiArgs  -nocompress -stage stack";
+            # XXX: use file rules
+            # Image is the EXP (exptime) image
+            $command .= " -file $pathBase.exp.fits";
+            # treat number image as mask
+            $command .= " -mask $pathBase.num.fits" if ($options & $PSTAMP_SELECT_NUM);
+
+            $command .= " -forheader $calibfile" if $calibfile;
+
+            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                run(command => $command, verbose => $verbose);
+
+            if (WIFEXITED($error_code)) {
+                $exitStatus = WEXITSTATUS($error_code);
+            } else {
+                print STDERR "ppstamp failed error_code: $error_code\n";
+                $exitStatus = $PS_EXIT_SYS_ERROR;
+            }
+
+            # command to compress fits files to stdout using gzip
+            my $fpack_gzip = "$fpack -g -S";
+            $fpack_gzip .= " -D" unless $save_temps;
+
+            if (!$exitStatus and ($options & $PSTAMP_SELECT_NUM)) {
+                # rename the num image if selected since it is not a mask
+                # Change .exp.mk to .num
+                my $tmpName = "$tmpBase.mk.fits";
+                my $numName = "$outputBase.num.fits";
+                # optionally fpack it while we're here unless user wants uncompressed images
+                unless ($options & $PSTAMP_SELECT_UNCOMPRESSED) {
+                    my $command = "$fpack_gzip $tmpName > $numName";
+                    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                        run(command => $command, verbose => $verbose);
+
+                    if (WIFEXITED($error_code)) {
+                        $exitStatus = WEXITSTATUS($error_code);
+                    } else {
+                        print STDERR "ppstamp failed error_code: $error_code\n";
+                        print STDERR "@$stderr_buf\n";
+                        $exitStatus = $PS_EXIT_SYS_ERROR;
+                    }
+                } elsif (!$exitStatus) {
+                    rename $tmpName, $numName 
+                        or my_die ("failed to rename $tmpName to $numName", $job_id, $PS_EXIT_UNKNOWN_ERROR);
+                }
+
+            }
+            # fpack the exp image if not -nocompress
+            unless ($exitStatus or ($options & $PSTAMP_SELECT_UNCOMPRESSED)) {
+                my $command = "$fpack_gzip $tmpBase.fits > $outputBase.exp.fits";
+                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+                    run(command => $command, verbose => $verbose);
+
+                if (WIFEXITED($error_code)) {
+                    $exitStatus = WEXITSTATUS($error_code);
+                } else {
+                    print STDERR "ppstamp failed error_code: $error_code\n";
+                    print STDERR "@$stderr_buf\n";
+                    $exitStatus = $PS_EXIT_SYS_ERROR;
+                }
+            } elsif (!$exitStatus) {
+                rename "$tmpBase.fits", "$outputBase.exp.fits"
+                    or my_die ("failed to rename $tmpBase.fits to $outputBase.exp.fits", $job_id, $PS_EXIT_UNKNOWN_ERROR);
+            }
+        }
     } else {
         $exitStatus = justCopyFiles($outputBase, \$options, $params);
Index: branches/eam_branches/ipp-20140813/tools/heather/queuesliceslap2.pl
===================================================================
--- branches/eam_branches/ipp-20140813/tools/heather/queuesliceslap2.pl	(revision 37350)
+++ branches/eam_branches/ipp-20140813/tools/heather/queuesliceslap2.pl	(revision 37351)
@@ -4,5 +4,7 @@
 
 
-$label = "LAP.ThreePi.20130717";
+#$label = "LAP.ThreePi.20130717";
+$label = "LAP.ThreePi.20130717.pole3";
+#$label = "LAP.ThreePi.20130717.pole3.CNP";
 
 @segments = (0,1,2,3,4,5,6,7,8);
@@ -11,12 +13,14 @@
 
 
-@slices = ("00","02","04","06","08",10,12,14,16,18,20,22);
-    
-$slice = $slices[0];
-$slice = $slices[1];
+@slices = ("00","02","04","06","08","10","12","14","16","18","20","22");
+ 
+foreach $slice (@slices) {
+   
+#$slice = $slices[0];
+#$slice = $slices[1];
     foreach $num (@segments) {
 
-	$dvodb = "LAP.20130717";
-	$minidvodb_group = "LAP.slice$slice.$segments[$num].cam";
+	$dvodb = "LAP.PV2.20130717";
+	$minidvodb_group = "LAP.PV2.slice$slice.$segments[$num].cam";
 	$dvodb_label = "$minidvodb_group";
 	$ra_min = $slice*15.0;
@@ -27,7 +31,11 @@
 
 	
-	print "addtool -definebyquery  -label $label -set_dvodb $dvodb -set_minidvodb_group $minidvodb_group -set_minidvodb -set_label $dvodb_label -stage cam -uncensored -ra_min $ra_min -ra_max $ra_max -decl_min $dec_min -decl_max $dec_max -dbname gpc1 \n";
-
-
+	$com =  "addtool -definebyquery  -label $label -set_dvodb $dvodb -set_minidvodb_group $minidvodb_group -set_minidvodb -set_label $dvodb_label -stage cam -uncensored -ra_min $ra_min -ra_max $ra_max -decl_min $dec_min -decl_max $dec_max -dbname gpc1";
+	print "$com\n";
+	`$com`;
+    }
 
 }
+$com2 = "addtool -definebyquery  -label $label -set_dvodb $dvodb -set_minidvodb_group LAP.PV2.pole.cam -set_minidvodb -set_label LAP.PV2.pole.cam -stage cam -uncensored -ra_min 0 -ra_max 360 -decl_min 75 -decl_max 90 -dbname gpc1";
+print "$com2\n";
+`$com2`;
Index: branches/eam_branches/ipp-20140813/tools/heather/queuesliceslap2skycal.pl
===================================================================
--- branches/eam_branches/ipp-20140813/tools/heather/queuesliceslap2skycal.pl	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/heather/queuesliceslap2skycal.pl	(revision 37351)
@@ -0,0 +1,41 @@
+#addtool  -pretend -definebyquery -label LAP.ThreePi.20120706 -set_dvodb LAP.20120706 -set_minidvodb_group LAP.slice06.part2.cam -set_minidvodb -set_label LAP.slice06.part2.cam -stage cam -uncensored -ra_min 90 -ra_max 120 -decl_min -35 -decl_max 20 -dbname gpc1 -simple | wc
+
+#addtool  -pretend -definebyquery -label LAP.ThreePi.20120706 -set_dvodb LAP.20120706 -set_minidvodb_group LAP.slice06.cam -set_minidvodb -set_label LAP.slice06.cam -stage cam -uncensored -ra_min 90 -ra_max 120 -decl_min 20 -decl_max 75 -dbname gpc1 -simple | wc
+
+
+#$label = "LAP.ThreePi.20130717";
+#$label = "LAP.ThreePi.20130717.pole3";
+$label = "LAP.ThreePi.20130717.pole3.CNP";
+
+@segments = (0,1,2,3,4,5,6,7,8);
+@segments1 = ( -35, -22,-10,2,14,26,38,50,62);
+@segments2 = ( -22,-10,2,14,26,38,50,62,75);
+
+
+@slices = ("00","02","04","06","08","10","12","14","16","18","20","22");
+ 
+foreach $slice (@slices) {
+   
+#$slice = $slices[0];
+#$slice = $slices[1];
+    foreach $num (@segments) {
+
+	$dvodb = "LAP.PV2.20130717";
+	$minidvodb_group = "LAP.PV2.slice$slice.$segments[$num].skycal";
+	$dvodb_label = "$minidvodb_group";
+	$ra_min = $slice*15.0;
+	$ra_max = ($slice+2)*15.0;
+	$dec_min = $segments1[$num];
+	$dec_max = $segments2[$num];
+#	print "$dvodb $minidvodb_group $ra_min $ra_max $dec_min $dec_max\n";
+
+	
+	$com =  "addtool -definebyquery  -label $label -set_dvodb $dvodb -set_minidvodb_group $minidvodb_group -set_minidvodb -set_label $dvodb_label -stage skycal -uncensored -ra_min $ra_min -ra_max $ra_max -dec_min $dec_min -dec_max $dec_max -dbname gpc1";
+	print "$com\n";
+	`$com`;
+    }
+
+}
+$com2 = "addtool -definebyquery  -label $label -set_dvodb $dvodb -set_minidvodb_group LAP.PV2.pole.skycal -set_minidvodb -set_label LAP.PV2.pole.skycal -stage skycal -uncensored -ra_min 0 -ra_max 360 -dec_min 75 -dec_max 90 -dbname gpc1";
+print "$com2\n";
+`$com2`;
Index: branches/eam_branches/ipp-20140813/tools/iasc/README
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/README	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/README	(revision 37351)
@@ -0,0 +1,70 @@
+# IASC is the asteroids/comets outreach program 
+# Ask Richard Wainscoat about it
+# SVN:  https://svn.pan-starrs.ifa.hawaii.edu/repo/ipp/trunk/tools/iasc
+
+### Usage
+1) Select the set of exposures to be published
+	e.g. o6897g0312o o6897g0328o o6897g0344o o6897g0360o
+2) Choose a name for the target directory (usually the date when the observations
+   were made)
+	e.g. 20140828
+3) Execute:
+	./RUN.sh <target directory> <exposures list>
+	e.g.
+	./RUN.sh 20140828 o6897g0312o o6897g0328o o6897g0344o o6897g0360o
+4) Send an e-mail to the people who requested the set of exposures, telling them 
+   where to find the set
+
+
+### Details
+
+To get chip processed image files with updated astrometry we have the postage stamp
+server make full image stamps for each chip. Then we download the files and change
+the names to remove the stuff that the pstamp server needs to add.
+
+The process is
+
+1. Make the destination directory. I have been using the date. For example
+    mkdir 20120412
+
+For each exposure
+    postreq <exp_name>
+    # wait for request to finish (check pstamp status page)
+    getit <fileset_name> <destdir>
+
+2. rsync the directory to /data/ipp022.0/ps1-outreach:
+	rsync -avz YYYYMMDD ipp@ipp0222:/data/ipp022.0/ps1-outreach/
+   To speed it up:
+	rsync -av YYYYMMDD ipp@ipp0222:/data/ipp022.0/ps1-outreach --exclude 'YYYYMMDD/*/*.tmp'
+
+3. The directory is visible to epo folks as
+	rsync://ipp0222.ifa.hawaii.edu/ps1-outreach/YYYYMMDD
+   Test it with:
+	rsync -avz rsync://ps1epo@ipp0222.ifa.hawaii.edu/ps1-outreach/20130308 .
+   Password can be found in ipp022:/etc/rsyncd.secrets
+
+4. Make sure that the smfs have been published to the datastore
+   ./check_if_smfs_have_been_published.py o6359g0309o o6359g0330o o6359g0351o o6359g0372o
+
+5. Tell the persons who made the request that all is good
+
+######
+For example
+    (ippc18:~/outreach) ./postreq o6029g0262o
+    running psmkreq --req_type byexp --stage chip --pixcenter --x 0 --y 0 --width 0 --height 0 --id o6029g0262o --req_name o6029g0262o.20120412T201043
+    running pstamptool -dbname ippRequestServer -dbserver ippc17 -label WEB -addreq -uri /home/panstarrs/bills/outreach/o6029g0262o.20120412T201043.fits
+    posted o6029g0262o.20120412T201043 req_id: 160657
+    results will be at http://datastore.ipp.ifa.hawaii.edu/pstampresults/o6029g0262o.20120412T201043
+
+    ./getit  o6029g0262o.20120412T201043 20120412
+    # lots of noise from dsget
+
+    # files are in 20120412/o6029g0262o
+    
+./check_if_smfs_have_been_published.py o6359g0309o o6359g0330o o6359g0351o o6359g0372o
+o6359g0309o: OK (2 published)
+o6359g0330o: OK (2 published)
+o6359g0351o: OK (2 published)
+o6359g0372o: OK (2 published)
+
+NOTE : the directory in which this is run needs to be globally visible via NFS.
Index: branches/eam_branches/ipp-20140813/tools/iasc/RUN.sh
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/RUN.sh	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/RUN.sh	(revision 37351)
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+targetdir=$1
+shift
+exposures=$*
+
+echo "Creating targetdir [$targetdir]"
+mkdir -p $targetdir
+mkdir -p $targetdir/smf
+
+images=""
+for exposure in $exposures; do
+	echo "Requesting images for $exposure"
+	image=`./postreq $exposure | grep datastore.ipp.ifa.hawaii.edu | sed 's/^.*\///'`
+	images="$images $image"
+	echo "Requesting smf for $exposure"
+	./get_smf.sh $exposure $targetdir
+done
+
+todelete=""
+for image in $images; do
+	status=1
+	while [ $status -ne 0 ]; do
+		sleep 30
+		echo "Copying images for $image"
+		./getit $image $targetdir
+		status=$?
+	done
+	todelete="$todelete $image.fits"
+done
+echo "All images copied locally"
+
+echo "Rsyncing: rsync -av $targetdir ipp@ipp0222:/data/ipp022.0/ps1-outreach/"
+rsync -av $targetdir ipp@ipp0222:/data/ipp022.0/ps1-outreach/
+rsync -av $targetdir ipp@ipp0222:/data/ipp022.0/ps1-outreach/
+
+echo
+echo "Done"
+echo "Dataset can be copied from rsync://ps1epo@ipp0222.ifa.hawaii.edu/ps1-outreach/$targetdir"
+echo "Command line:"
+echo "  rsync -avz rsync://ps1epo@ipp0222.ifa.hawaii.edu/ps1-outreach/$targetdir ."
+echo
+echo "Command to run to cleanup local directory:"
+echo "  rm -rf $targetdir $todelete"
+echo
+
Index: branches/eam_branches/ipp-20140813/tools/iasc/get_smf.sh
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/get_smf.sh	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/get_smf.sh	(revision 37351)
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# $1: expsore name
+# $2: destination directory (date)
+
+pathbase=`echo "SELECT path_base FROM camProcessedExp JOIN camRun USING(cam_id) JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id) WHERE exp_name = '$1' " | mysql -h scidbm -u ipp -pipp gpc1 | grep -v path_base`
+
+source=`neb-ls -p $pathbase.smf`
+
+mkdir -p $2/smf
+cp $source $2/smf/$1.smf
+
Index: branches/eam_branches/ipp-20140813/tools/iasc/getit
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/getit	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/getit	(revision 37351)
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+my $dsroot = 'http://datastore.ipp.ifa.hawaii.edu/pstampresults';
+
+my $fs = shift;
+my $dest = shift;
+
+# set this if the files have already been downloaded 
+my $skip_download = 0;
+
+die "usage: $0 <fileset_name> <destdir" if !$fs or !$dest;
+
+
+# $fs = 'web_' . $fs if !($fs =~ /web_/);
+
+my $url = "$dsroot/$fs";
+
+my $destdir = "$dest/$fs";
+
+unless($skip_download) {
+
+    my $rc = system "dsgetfileset -u $url -o $destdir";
+    if ($rc) {
+        my $status = $rc >>  8;
+        die "dsgetfileset failed with $rc $status\n";
+    }
+}
+
+# read exp_name from results.mdc (keyword is FPA_ID)
+my $grepout = `grep FPA_ID $destdir/results.mdc | tail -n 1`;
+chomp $grepout;
+
+die "failed to find exp_name in results.mdc" unless $grepout;
+
+my (undef, undef, $exp_name) = split " ", $grepout;
+
+die "failed to find exp_name in results.mdc: $grepout" unless $exp_name;
+
+my $final_destdir = "$dest/$exp_name";
+rename $destdir, $final_destdir or die "failed to rename $destdir";
+
+chdir $final_destdir or die "failed to chdir to $final_destdir";
+
+system 'perl /data/ippc18.0/home/ipp/iasc.v2/rename.stamp.outputs.pl *';
+
+
Index: branches/eam_branches/ipp-20140813/tools/iasc/obsolete/check_if_smfs_have_been_published.py
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/obsolete/check_if_smfs_have_been_published.py	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/obsolete/check_if_smfs_have_been_published.py	(revision 37351)
@@ -0,0 +1,38 @@
+#!/usr/bin/env python
+
+import MySQLdb
+import sys
+
+def usage(program_name):
+    return """
+%s [exposure name] [...]
+
+Check if the smf of <exposure name> have been published to the datastore
+
+-h, -help, --help:
+  Displays this help and exits
+"""
+
+def process_arguments(arguments):
+    if len(arguments)<2:
+        sys.stderr.write(usage(arguments[0]))
+        sys.exit(1)
+    index = 1
+    if arguments[index] == "-h" or arguments[index] == "-help" or arguments[index] == "--help":
+        sys.stderr.write(usage(arguments[0]))
+        sys.exit(0)
+    return arguments[index:]
+
+if __name__ == "__main__":
+    exposures = process_arguments(sys.argv)
+    gpc1 = MySQLdb.connect('ippdb01', 'ipp', 'ipp', 'gpc1')
+    cursor = gpc1.cursor()
+    for exposure in exposures:
+        statement = "SELECT COUNT(distinct(distRun.dist_id)) FROM distRun JOIN distComponent USING(dist_id) JOIN camRun ON camRun.cam_id=distRun.stage_id JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id) WHERE exp_name = '%s' AND distRun.stage='camera'" % exposure
+        cursor.execute(statement)
+        count=cursor.fetchall()[0][0]
+        if count != 0:
+            print "%s: OK (%d published)" % (exposure, count)
+        else:
+            print "%s: FAIL (%d published)" % (exposure, count)
+
Index: branches/eam_branches/ipp-20140813/tools/iasc/postreq
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/postreq	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/postreq	(revision 37351)
@@ -0,0 +1,36 @@
+#!/usr/bin/env perl 
+
+# create a postage stamp request file to get full chip images for
+# a given exposure
+# post it to the server with label WEB
+
+use strict; 
+use warnings;
+use POSIX qw( strftime );
+
+my $exp_name = shift;
+die "need exposure name\n" if !$exp_name;
+
+my $datestr = strftime "%Y%m%dT%H%M%S", gmtime;
+
+# request name must be unique add datetime
+my $req_name = "$exp_name.$datestr";
+
+# make the request file
+my $cmd = "psmkreq --req_type byexp --stage chip --pixcenter --x 0 --y 0 --width 0 --height 0 --id $exp_name --req_name $req_name";
+
+print "running $cmd\n";
+my $rc = system $cmd;
+
+die "psmkreq failed" if $rc;
+
+# add the request to the database
+my $postcmd = "pstamptool -dbname ippRequestServer -dbserver ippc17 -label WEB -addreq -uri $ENV{PWD}/$req_name.fits";
+
+print "running $postcmd\n";
+
+my $req_id = `$postcmd`;
+chomp $req_id;
+
+print "posted $req_name req_id: $req_id\n";
+print "results will be at http://datastore.ipp.ifa.hawaii.edu/pstampresults/$req_name\n";
Index: branches/eam_branches/ipp-20140813/tools/iasc/rename.stamp.outputs.pl
===================================================================
--- branches/eam_branches/ipp-20140813/tools/iasc/rename.stamp.outputs.pl	(revision 37351)
+++ branches/eam_branches/ipp-20140813/tools/iasc/rename.stamp.outputs.pl	(revision 37351)
@@ -0,0 +1,12 @@
+#!/usr/bin/env perl
+
+my $verbose = 0;
+
+foreach my $name (@ARGV) {
+    next if !($name =~ /1_/);
+    my (undef, undef, undef, $new_name) = split "_", $name;
+    die "failed to extract new name from $name\n" unless $new_name;
+    print "$name $new_name\n" if $verbose;
+    rename $name, $new_name or die "failed to rename $name\n";
+}
+
