Index: /trunk/ippScripts/scripts/detrend_create_resid.pl
===================================================================
--- /trunk/ippScripts/scripts/detrend_create_resid.pl	(revision 8491)
+++ /trunk/ippScripts/scripts/detrend_create_resid.pl	(revision 8491)
@@ -0,0 +1,90 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+
+use IPC::Cmd qw( can_run run );
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::Stats;
+use Data::Dumper;
+
+
+# Recipes to use, as a function of the detrend type
+use constant RECIPES => {
+    'bias' => 'PPIMAGE_B',	# Bias only
+    'dark' => 'PPIMAGE_D',	# Dark only
+    'flat' => 'PPIMAGE_F',	# Flat-field only
+};
+
+use constant DELETE_STATS => 0;	# Delete the statistics file when done?
+
+# Parse the command-line arguments
+if (scalar @ARGV != 6) {
+    die "Perform detrend processing at the imfile level.\n\n" .
+	"Usage: $0 DET_ID EXP_ID CLASS_ID DETREND_TYPE INPUT.fits OUTPUT_ROOT\n\n";
+}
+my $detId = shift @ARGV;	# Detrend ID
+my $expId = shift @ARGV;	# Exposure ID
+my $classId = shift @ARGV;	# Class ID
+my $detType = shift @ARGV;	# Detrend type
+my $input = shift @ARGV;	# Input FITS file
+my $output = shift @ARGV;	# Output root name
+
+# Look for programs we need
+my $missing_tools;
+my $dettool = can_run('dettool') or (warn "Can't find dettool" and $missing_tools = 1);
+my $ppImage = can_run('ppImage') or (warn "Can't find ppImage" and $missing_tools = 1);
+die "Can't find required tools.\n" if $missing_tools;
+
+# Recipe to use in processing
+my $recipe = RECIPES->{$detType};
+die "Unrecognised detrend type: $detType\n" if not defined $recipe;
+
+### Output file names --- must match camera configuration!
+my $outputName = $output . '.' . $classId . '.fit';
+my $bin1Name = $output . '.' . $classId . '.b1.fit';
+my $bin2Name =  $output . '.' . $classId . '.b2.fit';
+
+# Run ppImage
+{
+    my $command = "$ppImage -file $input $output -recipe PPIMAGE $recipe" .
+	" -stat $output.stats"; # Command to run ppImage
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => 1);
+    die "Unable to perform ppImage on $input: $error_code\n" if not $success;
+    die "Couldn't find expected output file: $outputName\n" if not -f $outputName;
+    die "Couldn't find expected output file: $bin1Name\n" if not -f $bin1Name;
+    die "Couldn't find expected output file: $bin2Name\n" if not -f $bin2Name;
+}
+
+# Get the statistics on the residual image
+my $stats;			# Statistics from ppImage
+{
+    my $statsFile;		# File handle
+    open $statsFile, "$output.stats" or die "Can't open statistics file $output.stats: $!\n";
+    my @contents = <$statsFile>; # Contents of file
+    close $statsFile;
+    my $mdcParser = PS::IPP::Metadata::Config->new;	# Parser for metadata config files
+    my $metadata = $mdcParser->parse(join "", @contents); # Metadata from the stats
+    $stats = PS::IPP::Metadata::Stats->new(); # Stats parser
+    $stats->parse($metadata) or die "Unable to find all values in statistics output.\n";
+}
+
+# Add the processed file to the database
+{
+    my $command = "dettool -addresidimfile -det_id $detId -exp_id $expId " .
+	"-class_id $classId -recipe $recipe -uri $outputName -b1 $bin1Name " .
+	"-b2 $bin2Name"; # Command to run dettool
+    $command .= " -bg " . $stats->bg_mean();
+    $command .= " -bg_stdev " . $stats->bg_stdev();
+    $command .= " -bg_mean_stdev " . $stats->bg_mean_stdev();
+
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => 1);
+    die "Unable to perform dettool -addprocessed for $detId/$expId/$classId: $error_code\n"
+	if not $success;
+}
+
+unlink "$output.stats" if DELETE_STATS;
+
+__END__
