Index: branches/bills_081204/PStamp/lib/PStamp.pm
===================================================================
--- trunk/PStamp/lib/PStamp.pm	(revision 19437)
+++ branches/bills_081204/PStamp/lib/PStamp.pm	(revision 20890)
@@ -43,5 +43,6 @@
 =cut
 
-use PStamp::RequestFile;
+use PStamp::RequestFile qw( :standard );
+use PStamp::Job qw( :standard );
 
 =head1 CREDITS
Index: branches/bills_081204/PStamp/lib/PStamp/Job.pm
===================================================================
--- trunk/PStamp/lib/PStamp/Job.pm	(revision 19437)
+++ branches/bills_081204/PStamp/lib/PStamp/Job.pm	(revision 20890)
@@ -44,6 +44,40 @@
     # we die in response to bad data in request files
     die "Unknown req_type: $req_type" if ($req_type ne "byid") and ($req_type ne "byexp")
-                                        and ($req_type ne "bycoord");
-    if ($req_type eq "bycoord") {
+                                        and ($req_type ne "bycoord") and ($req_type ne "bydiff");
+    if (($req_type eq "byid") and ($img_type eq "diff")) {
+        # lookups of all of the information for diff images requires a two level lookup to
+        # get the exposure information. Switching the req_type allows us to keep that code
+        # in one place
+        $req_type = "bydiff";
+    }
+    if ($req_type eq "bydiff") {
+        my $results = lookup_bydiff($ipprc, $image_db, $id, $img_type, $verbose);
+        if (!$results) {
+            return undef;
+        }
+        if ($img_type eq "diff") {
+            return [$results];
+        } elsif (($img_type eq "raw") or ($img_type eq "chip")) {
+            $req_type = "byexp";
+            $id = $results->{exp_name};
+            return undef if !$id;
+            # fall through and lookup byexp
+        } elsif ($img_type eq "warp") {
+            $req_type = "byid";
+            $id = $results->{warp_id};
+            return undef if !$id;
+            # fall through and lookup by warp_id 
+        } elsif ($img_type eq "stack") {
+            $req_type = "byid";
+            $id = $results->{stack_id};
+            return undef if !$id;
+            # fall though and lookup by stack id
+        } else {
+            # shouldn't I check this elsewhere?
+            print STDERR "Error: $img_type is an unknown image type\n";
+            return undef;
+        }
+
+    } elsif ($req_type eq "bycoord") {
 
         # run
@@ -52,4 +86,7 @@
         my $results = lookup_bycoord($ipprc, $image_db, $x, $y, $mjd_min, $mjd_max, $filter, $verbose);
 
+        # now take the results and lookup byexp
+        # XXX: This needs work. What stops results from returning multiple images????
+        # We should loop over the set of images returned building up the full results array
         $req_type = "byexp";
         $id = $results->{exp_name};
@@ -86,7 +123,7 @@
     my $base_name;
     my $want_astrom;
-    my $use_class_id;
-
-    # special class_id value "null" means all 
+    my $set_class_id;
+
+    # special class_id value "null" means ignore
     if ($class_id eq "null") {
         $class_id = undef;
@@ -97,6 +134,6 @@
         $id_opt = "-exp_id";
         $command .= " -class_id $class_id" if $class_id;
-        $want_astrom = 0;
-        $use_class_id = 1;
+        $want_astrom = 1;
+        $set_class_id = 1;
     } elsif ($img_type eq "chip") {
         $command = "$chiptool -processedimfile -dbname $image_db";
@@ -107,5 +144,5 @@
         $base_name    = "path_base"; # name of the field for the chiptool output
         $want_astrom  = 1;
-        $use_class_id = 1;
+        $set_class_id = 1;
     } elsif ($img_type eq "warp") {
         $command = "$warptool -warped -dbname $image_db";
@@ -162,21 +199,28 @@
     foreach my $image (@$images) {
         my $base;
+
+        next if ($img_type eq "warp" and $image->{ignored});
+
         if ($base_name) {
             $base = $image->{$base_name};
-            # if base is undef then the output pruducts for thjis image are incomplete
-            # This may only happen for warps.
+            # if base is undef then the output pruducts for this image are incomplete
+            # This may only happen for warps. (Actually the test for ignored that I added
+            # just above probably solved the problem I was trying to solve with this test)
             next if !$base;
         }
         if (!$camera) {
             # This assumes that all images have the same camera
-            $ipprc->define_camera($image->{camera});
             $camera = $image->{camera};
+            $ipprc->define_camera($camera);
         }
         my $out = {};
         $out->{exp_id} = $image->{exp_id};
+        $out->{exp_name} = $image->{exp_name};
         $out->{image}  = $image->{uri};
         $out->{state}  = $image->{state}; # state is undef for rawExp, but that's ok
-        $class_id = $image->{class_id} if $use_class_id;
-
+        if ($set_class_id) {
+            $class_id = $image->{class_id};
+            $out->{class_id} = $class_id;
+        }
 
         # find the mask and weight images
@@ -187,10 +231,4 @@
         $out->{camera} = $camera;
 
-#XXX gpc1 and mops data that I've been looking at was made with astrometry in chip processing
-#so the filerule doesn't match
-if ($camera ne "SIMTEST") {
-    $want_astrom = 0;
-}
-       
         $out->{astrom} = find_astrometry($ipprc, $image_db, $image, $verbose) if $want_astrom;
 
@@ -199,4 +237,104 @@
 
     return $output;
+}
+sub lookup_bydiff {
+    my $ipprc    = shift;
+    my $image_db = shift;
+    my $id       = shift;
+    my $img_type = shift;
+    my $verbose = shift;
+
+    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 -diff_id $id -dbname $image_db";
+
+    # 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 ($n > 1) {
+        die ("difftool returned an unexpected number of diffskyfiles: $n");
+    } elsif ($n == 0) {
+        return undef;
+    }
+
+    my $image = $images->[0];
+
+    # The standard way to do a diff is warp - stack 
+    # so we interpret the requested image in that way
+
+    # XXX the query currently returns max long long for null
+    # this line is ready if we switch the code to return zero for null
+    my $stack_id = $image->{stack_id_temp_1};
+    if ($stack_id and ($stack_id != 9223372036854775807)) {
+        $image->{stack_id} = $stack_id;
+    }
+
+    # XXX the query currently returns max long long for null
+    # this line is ready if we switch the code to return zero for null
+    my $warp_id =  $image->{warp_id_temp_0};
+    if ($warp_id and ($warp_id != 9223372036854775807)) {
+        $image->{warp_id} = $warp_id;
+
+        ## now use the warp and go get the exposure information
+        $command = "warptool -warped -warp_id $warp_id -dbname $image_db -limit 1";
+        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 $warps = parse_md_fast($mdcParser, $buf)
+            or die ("Unable to parse metadata config doc");
+        my $warp = $warps->[0];
+
+        $image->{exp_id} = $warp->{exp_id};
+        $image->{exp_name} = $warp->{exp_name};
+        $image->{camera} = $warp->{camera};
+    }
+
+    if ($img_type eq "diff") {
+        # 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
+        $image->{image} = $image->{uri};
+        if ($image->{camera}) {
+            $ipprc->define_camera($image->{camera});
+            $image->{mask}   = $ipprc->filename("PPSUB.OUTPUT.MASK", $image->{path_base});
+            $image->{weight} = $ipprc->filename("PPSUB.OUTPUT.WEIGHT", $image->{path_base});
+        } else {
+            # XXX this will only happen if the minuend is not a warp
+            print STDERR "WARNING: cannot resolve camera so cannot get weight and mask images\n";
+        }
+    }
+
+    return $image;
 }
 
@@ -334,5 +472,5 @@
 
 # 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 of the ippScripts.
+# slow parser. This is similar to and adapted from code in various ippScripts.
 sub parse_md_fast {
     my $mdcParser = shift;
@@ -374,52 +512,39 @@
 # resolve_project()
 # get project specific information
-# This is a placeholder final implementation will use configuration file and database to
-# map from "project" to image database, dvo database, telescope, camera, etc
-#
-# For now just get the database and the class_id that will be used for image lookup
-
 sub resolve_project {
+    my $ipprc = shift;
     my $project_name = shift;
-    my $img_type     = shift;
-    my $class_id     = shift;
+    my $dbname = shift;
     die "project is not defined" if !$project_name;
 
-    # for megacam and simtest since images are at the fpa level, leave out the
-    # class_id at the lookup stage
-    #
-    # TODO: get this information from a database or a configuration file
-
-    my $ret_dbname;
-    my $ret_class_id;
-    my $ret_inst;
-    my $ret_magic;
-    my $ret_camera;
-
-    if ($project_name eq "megacam-mops") {
-        $ret_dbname = "mops";
-        $ret_class_id = "null";
-        $ret_camera = "MEGACAM";
-        $ret_magic = 0;
-    } elsif ($project_name eq "simtest") {
-        $ret_dbname = "ps_simtest";
-        $ret_class_id = "null";
-        $ret_camera = "SIMTEST";
-        $ret_magic = 0;
-    } elsif ($project_name eq "gpc1") {
-        $ret_dbname = "gpc1";
-        $ret_class_id = $class_id;
-        $ret_camera = "GPC1";
-        $ret_magic = 0; # switch this to 1 when we're ready
-    } else {
-        die "unknown project $project_name";
-    }
-
-    if (($img_type ne "raw") and ($img_type ne "chip")) {
-        # don't need class_id
-        $ret_class_id = "";
-    }
-
-    return ($ret_dbname, $ret_class_id, $ret_camera, $ret_magic);
-}
-
+    my $verbose = 1;
+
+    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;
+    # 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;
+    }
+    my $proj_hash = parse_md_fast($mdcParser, $output);
+
+    return $proj_hash->[0];
+}
 1;
