Index: /trunk/ippScripts/scripts/phase3.pl
===================================================================
--- /trunk/ippScripts/scripts/phase3.pl	(revision 9366)
+++ /trunk/ippScripts/scripts/phase3.pl	(revision 9366)
@@ -0,0 +1,151 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+
+use vars qw( $VERSION );
+$VERSION = '0.01';
+
+use IPC::Cmd qw( can_run run );
+use PS::IPP::Metadata::Config;
+use PS::IPP::Metadata::List qw( parse_md_list );
+use Statistics::Descriptive;
+
+use PS::IPP::Config;
+my $ipprc = PS::IPP::Config->new(); # IPP configuration
+use File::Spec;
+
+use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
+use Pod::Usage qw( pod2usage );
+
+my ($exp_tag, $no_update);
+GetOptions(
+    'exp_tag|e=s'       => \$exp_tag,
+    'no-update'         => \$no_update
+) or pod2usage( 2 );
+
+pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
+pod2usage(
+    -msg => "Required options: --exp_tag",
+    -exitval => 3,
+) unless defined $exp_tag;
+
+use constant RECIPE1 => 'PPIMAGE_J1'; # Recipe to use for ppImage to make JPEGs
+use constant RECIPE2 => 'PPIMAGE_J2'; # Recipe to use for ppImage to make JPEGs
+
+
+# Look for programs we need
+my $missing_tools;
+my $p3tool = can_run('p3tool') or (warn "Can't find p3tool" 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;
+
+my $mdcParser = PS::IPP::Metadata::Config->new;	# Parser for metadata config files
+
+# Get list of component files
+my $files;			# Array of component files
+{
+    my $command = "$p3tool -pendingimfile -exp_tag $exp_tag"; # Command to run
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => 1);
+    die "Unable to perform p3tool -pendingimfile: $error_code\n" if not $success;
+    my $metadata = $mdcParser->parse(join "", @$stdout_buf) 
+        or die "unable to parse metadata config doc";
+    $files = parse_md_list($metadata);
+}
+
+# Gather the statistics
+my ($bg, $bg_stdev, $bg_mean_stdev); # The statistics triplet
+{
+    my @backgrounds;		# Array of backgrounds in each component
+    my @stdevs;			# Array of standard deviations in each component
+#    my @ra;			# Array of ra errors
+#    my @dec;			# Array of dec errors
+#    my @zp;			# Array of photometric zero points
+    foreach my $file (@$files) {
+	die "Unable to find class id\n" unless defined $file->{class_id};
+	my $class_id = $file->{class_id};
+	die "Unable to find bg for class_id=$class_id\n" unless defined $file->{bg};
+	die "Unable to find bg_mean_stdev for class_id=$class_id\n" unless defined $file->{bg_mean_stdev};
+#	die "Unable to find sigma_ra for class_id=$class_id\n" unless defined $file->{sigma_ra};
+#	die "Unable to find sigma_dec for class_id=$class_id\n" unless defined $file->{sigma_dec};
+#	die "Unable to find zp for class_id=$class_id\n" unless defined $file->{zp};
+	push @backgrounds, $file->{bg};
+	push @stdevs, $file->{bg_mean_stdev};
+    }
+
+    {
+	my $stats = Statistics::Descriptive::Sparse->new; # Statistics calculator
+	$stats->add_data(@backgrounds);
+	$bg = $stats->mean();
+	if (scalar @backgrounds == 1) {
+	    $bg_stdev = 0.0;
+	} else {
+	    $bg_stdev = $stats->standard_deviation();
+	}
+    }
+    {
+	my $stats = Statistics::Descriptive::Sparse->new; # Statistics calculator
+	$stats->add_data(@stdevs);
+	$bg_mean_stdev = $stats->mean();
+    }
+}
+
+my $example = ${$files}[0]->{b1_uri}; # Example filename
+my ($vol, $dir, $file) = File::Spec->splitpath( $example );
+
+# Generate the file list, and get the statistics
+my $outputRoot = $exp_tag . '.p3'; # Root output name
+$outputRoot = File::Spec->rel2abs( File::Spec->catpath( $vol, $dir, $outputRoot ), $ipprc->workdir() );
+my $list1Name = $outputRoot . '.b1.list'; # Name for the input file list for binning 1
+my $list2Name = $outputRoot . '.b2.list'; # Name for the input file list for binning 2
+my @means;			# Array of means
+my @stdevs;			# Array of stdevs
+open my $list1File, '>' . $list1Name;
+open my $list2File, '>' . $list2Name;
+foreach my $file (@$files) {
+    print $list1File (File::Spec->rel2abs( $file->{b1_uri}, $ipprc->workdir() ) . "\n");
+    print $list2File (File::Spec->rel2abs( $file->{b2_uri}, $ipprc->workdir() ) . "\n");
+    push @means, $file->{bg};
+    push @stdevs, $file->{bg_stdev};
+}
+close $list1File;
+close $list2File;
+
+# Output products --- need to synch with the camera configuration!
+my $jpeg1Name = $outputRoot . ".b1.jpg"; # Binned JPEG #1
+my $jpeg2Name = $outputRoot . ".b2.jpg"; # Binned JPEG #2
+
+# Make the jpeg for binning 1
+{
+    my $command = "$ppImage -list $list1Name $outputRoot -recipe PPIMAGE " . RECIPE1; # Command to run
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => 1);
+    die "Unable to find expected output file: $jpeg1Name\n" if not -f $jpeg1Name;
+}
+
+# Make the jpeg for binning 2
+{
+    my $command = "$ppImage -list $list2Name $outputRoot -recipe PPIMAGE " . RECIPE2; # Command to run
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => 1);
+    die "Unable to find expected output file: $jpeg2Name\n" if not -f $jpeg2Name;
+}
+
+
+# Add the result into the database
+$outputRoot = File::Spec->abs2rel( $outputRoot, $ipprc->workdir() );
+unless ($no_update) {
+    my $command = "$p3tool -addprocessedexp -exp_tag $exp_tag " .
+	"-recip " . RECIPE1() . "," . RECIPE2() . " -b1_uri $jpeg1Name -b2_uri $jpeg2Name " .
+	"-bg $bg -bg_stdev $bg_stdev -bg_mean_stdev $bg_mean_stdev"; # Command to run
+    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => 1);
+    die "Unable to perform p3tool -addprocessedexp: $error_code\n" if not $success;
+
+    unlink $list1Name;
+    unlink $list2Name;
+}
+
+
+__END__
