Index: /trunk/tools/bills/adddeltacolumns
===================================================================
--- /trunk/tools/bills/adddeltacolumns	(revision 38860)
+++ /trunk/tools/bills/adddeltacolumns	(revision 38860)
@@ -0,0 +1,44 @@
+#!/usr/bin/env perl
+
+# take a file that describes the conversion beteween ipp smf and cmf columns and psps column and create a 
+# stilts filter command that will add a column to a table with the difference between the 
+# Detection value and the expected value
+
+use strict;
+use warnings;
+
+my $verbose;
+
+my $in = shift;
+my $out = shift;
+die "usage $0 <input matched detections> <output>\n" unless $in and $out;
+my $confdir = '/home/panstarrs/bills/ipp/tools/bills';
+my $conversionFile = 'p2columns.txt';
+my $stiltsJar =  '/home/panstarrs/bills/jars/stilts.jar';
+my $stilts = "java -jar $stiltsJar";
+
+open C, "<$confdir/p2columns.txt" or die "failed to open p2columns.txt\n";
+
+my $cmd="'addcol -after zp zpFactor 3630.78*pow(10,-0.4*zp);";
+
+foreach my $line (<C>) {
+    next if $line =~ '^#';
+    next if !$line;
+    chomp $line;
+    my ($data, $comment) = split '#', $line;
+    next if !$data;
+    my ($p2, $ipp, $conversion) = split ' ', $data;
+
+    next if !$ipp;
+    $conversion = "" unless $conversion;
+    my $equation = "$ipp$conversion";
+    $equation = "$p2-$equation";
+    $cmd .=  "addcol -after $p2 d_$p2 $equation;";
+}
+$cmd .= "'";
+
+my $command = "$stilts tpipe in=$in out=$out cmd=$cmd";
+
+print "$command\n" if $verbose;
+
+system $command;
Index: /trunk/tools/bills/comparep2detections
===================================================================
--- /trunk/tools/bills/comparep2detections	(revision 38860)
+++ /trunk/tools/bills/comparep2detections	(revision 38860)
@@ -0,0 +1,85 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+use File::Basename;
+
+
+my $joinType = '1and2';
+my $in;
+my $out;
+my $ofmt;
+my $stiltsJar = '/home/panstarrs/bills/jars/stilts.jar';
+my $stilts = "java -jar $stiltsJar";
+
+my $test = 1;
+
+my ($verbose, $save_temps);
+
+GetOptions(
+    "test"              =>  \$test,
+    "ofmt=s"            =>  \$ofmt,
+    "join=s"            =>  \$joinType,
+    "verbose|v"         =>  \$verbose,
+    "save-temps"        =>  \$save_temps,
+) or pod2usage( 2 );
+
+die "usage: $0 [--ofmt <ofmt>] <p2 batch file> [<out>]\n" unless (scalar @ARGV == 1) or (scalar @ARGV == 2);
+
+$in = shift;
+$out = shift;
+
+my $detcat = "cat." . basename($in);
+
+runcommand( "concatp2batch $in $detcat");
+
+# find exp_id. XXX: we could use batch name for this or require user to find this
+my $command = "$stilts tcat in=$detcat icmd='head 1;keepcols imageID;' ofmt=ascii | grep -v '#'";
+my $imageID = `$command`;
+# XXX TODO: check for success
+chomp $imageID;
+my $exp_id = $imageID / 100;
+print "exp_id is $exp_id\n" if $verbose;
+
+my $smf;
+if ($test) {
+    # XXX: make an option
+    my $testdata = "/data/ippc19.0/home/bills/ipp/ippToPsps/test/testdata";
+    $smf = sprintf "%s/test.%02d.smf", $testdata, $exp_id;
+} else {
+    # XXX: look up the smf for the exposure here
+    die "only test mode works right now\n";
+}
+
+my $ippcat = "cat." . basename($smf);
+
+$command = "concatsmf $smf $ippcat";
+$command .= " --test" if $test;
+
+runcommand($command);
+
+my $matched = "m." . basename($out);
+runcommand("matchIppToPsps $detcat $ippcat $matched");
+
+if (!$save_temps) {
+    unlink $detcat;
+    unlink $ippcat;
+}
+
+runcommand("adddeltacolumns $matched $out");
+
+exit 0;
+
+
+sub runcommand {
+    my $command = shift;
+    print "Running: $command\n" if $verbose;
+    my $rc = system $command;
+    if ($rc) {
+        my $status = $rc >> 8;
+        die "$command failed\nrc = $rc status = $status";
+    }
+}
Index: /trunk/tools/bills/concatp2batch
===================================================================
--- /trunk/tools/bills/concatp2batch	(revision 38860)
+++ /trunk/tools/bills/concatp2batch	(revision 38860)
@@ -0,0 +1,63 @@
+#!/usr/bin/env perl
+
+# given a P2 ippToPsps batch file
+# concatenate all of the Detection extensions so that all of the Detections for
+# an exposure are in a single fits extension
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Temp qw( tempdir  tempfile );
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+
+# It wouldn't be too hard to make ota an array and do a list of chips.
+# for now just all or one
+
+my ($save_temps, $verbose);
+my $test;
+
+GetOptions(
+    "vebose|v"          =>  \$verbose,
+    "save-temps"        =>  \$save_temps,
+    "test"              =>  \$test,
+) or pod2usage( 2 );
+
+die "usage: $0 <p2 batch file> <output>\n" unless scalar @ARGV == 2;
+
+my $input = shift;
+my $output = shift;
+
+# TODO: make this an option
+my $stiltsJar = '/home/panstarrs/bills/jars/stilts.jar';
+
+my $stilts="java -jar $stiltsJar";
+
+my $ofmt = 'fits';
+
+my $extensionList = `ftlist $input h | grep Detection | awk '{print \$2}'`;
+
+my ($listFile, $listName) = tempfile ("/tmp/foo.XXXX", UNLINK => !$save_temps);
+
+# make a list of the detection extension names
+print "$listName\n" if $save_temps;
+foreach my $n (split "\n", $extensionList) {
+    print "$n\n" if $verbose;
+    # ftlist HDU number starts with 1, stilts expects zero based index
+    $n -= 1;
+    print $listFile "$input#$n\n";
+}
+close $listFile;
+
+# my $cmd = "$stilts tcat in=\@$listName out=$output ofmt=$ofmt ocmd='tablename $extname;'";
+my $cmd = "$stilts tcat in=\@$listName out=$output ofmt=$ofmt";
+my $rc = system $cmd;
+if ($rc) {
+    my $status = $rc >> 8;
+    die "stilts failed with $status $rc\n";
+}
+
+exit 0;
+
Index: /trunk/tools/bills/concatsmf
===================================================================
--- /trunk/tools/bills/concatsmf	(revision 38859)
+++ /trunk/tools/bills/concatsmf	(revision 38860)
@@ -21,4 +21,5 @@
 
 my ($ota, $save_temps, $verbose);
+my $test_smf;
 
 GetOptions(
@@ -26,4 +27,5 @@
     "vebose|v"          =>  \$verbose,
     "save-temps"        =>  \$save_temps,
+    "test"              =>  \$test_smf,
 ) or pod2usage( 2 );
 
@@ -55,4 +57,16 @@
 
 my ($exp_name, $exp_id, $cam_id);
+
+if ($test_smf) {
+    # Test smf created by the ippToPsps test suite
+    # file name format is 'test.$exp_id.smf"
+    # There is only a single psf extension for chipnum zero
+    (undef, $exp_id) = split '\.', $infilename;
+    extract_chip($path, $output, $exp_id, 0, 'Chip.psf');
+    exit 0;
+}
+
+# gpc1 smf
+
 ($exp_name, $exp_id, undef, $cam_id) = split '\.', $infilename;
 
Index: /trunk/tools/bills/matchIppToPsps
===================================================================
--- /trunk/tools/bills/matchIppToPsps	(revision 38859)
+++ /trunk/tools/bills/matchIppToPsps	(revision 38860)
@@ -39,4 +39,6 @@
 $cmd .= " ofmt=$ofmt" if $ofmt;
 
+$cmd .= " progress=none" unless $verbose;
+
 print "$cmd\n" if $verbose;
 
Index: /trunk/tools/bills/p2columns.txt
===================================================================
--- /trunk/tools/bills/p2columns.txt	(revision 38860)
+++ /trunk/tools/bills/p2columns.txt	(revision 38860)
@@ -0,0 +1,61 @@
+# Note zpFactor = 3630.78*pow(10, -0.4*zp)
+
+objID
+uniquePspsP2id
+detectID
+ippObjID
+ippDetectID     IPP_IDET
+filterID
+surveyID
+imageID
+randomDetID
+dvoRegionID
+obsTime
+xPos            X_PSF
+yPos            Y_PSF
+xPosErr         X_PSF_SIG
+yPosErr         Y_PSF_SIG
+pltScale        PLTSCALE
+posAngle        POSANGLE
+ra
+dec
+raErr           X_PSF_SIG               *abs(PLTSCALE)
+decErr          Y_PSF_SIG               *abs(PLTSCALE)
+extNSigma       EXT_NSIGMA
+zp
+telluricExt
+expTime
+airMass
+psfFlux         PSF_INST_FLUX 		*zpFactor/expTime
+psfFluxErr      PSF_INST_FLUX_SIG	*zpFactor/expTime
+psfMajorFWHM    PSF_FWHM_MAJ            *abs(PLTSCALE)
+psfMinorFWHM    PSF_FWHM_MIN            *abs(PLTSCALE)
+psfTheta        PSF_THETA
+psfCore         PSF_CORE
+psfQf           PSF_QF
+psfQfPerfect    PSF_QF_PERFECT
+psfChiSq        PSF_CHISQ
+psfLikelihood                                                 # actually psfLikelihood(EXT_NSIGMA)
+momentXX        MOMENTS_XX		*PLTSCALE*PLTSCALE
+momentXY        MOMENTS_YY		*PLTSCALE*PLTSCALE
+momentYY        MOMENTS_XY		*PLTSCALE*PLTSCALE
+momentR1        MOMENTS_R1              *abs(PLTSCALE)
+momentRH        MOMENTS_RH              *sqrt(abs(PLTSCALE))
+momentM3C       MOMENTS_M3C		*PLTSCALE*PLTSCALE
+momentM3S       MOMENTS_M3S		*PLTSCALE*PLTSCALE
+momentM4C       MOMENTS_M4C		*PLTSCALE*PLTSCALE
+momentM4S       MOMENTS_M4S		*PLTSCALE*PLTSCALE
+apFlux          AP_FLUX		        *zpFactor/expTime
+apFluxErr       AP_FLUX_SIG		*zpFactor/expTime
+apFillF         AP_NPIX                 /(3.14159265359*pow(AP_MAG_RADIUS-0.5,2))
+apRadius        AP_MAG_RADIUS           *abs(PLTSCALE)
+kronFlux        KRON_FLUX		*zpFactor/expTime
+kronFluxErr     KRON_FLUX_ERR		*zpFactor/expTime
+kronRad         MOMENTS_R1              *2.5*abs(PLTSCALE)
+sky             SKY                     /PLTSCALE/PLTSCALE*zpFactor/expTime
+skyErr          SKY_SIGMA               /PLTSCALE/PLTSCALE*zpFactor/expTime
+infoFlag        FLAGS
+infoFlag2       FLAGS2
+infoFlag3
+processingVersion
+
