Index: /trunk/ippScripts/scripts/ipp_serial_inject.pl
===================================================================
--- /trunk/ippScripts/scripts/ipp_serial_inject.pl	(revision 14020)
+++ /trunk/ippScripts/scripts/ipp_serial_inject.pl	(revision 14021)
@@ -1,6 +1,13 @@
 #!/usr/bin/env perl
 
-# this program injects a list of single-file exposures into the db, taking the
-# filename (without .fits) as the exp_tag.
+# this program injects a list of single-file exposures into the db,
+# taking the filename (without .fits) as the exp_tag.  the user
+# supplies a temporary telescope and instrument name.  these are used
+# for informational purposes only until the registration step can
+# determine the true telescope and instrument name from the image
+# headers.
+
+# this program should not fail because of the data format or the
+# configuration, except for the very basic database setup.
 
 use warnings;
@@ -8,11 +15,8 @@
 
 use IPC::Cmd 0.36 qw( can_run run );
-use PS::IPP::Metadata::Config;
-use PS::IPP::Metadata::List qw( parse_md_list );
 use File::Spec;
-# use File::Find::Rule;
 use PS::IPP::Config;
-my $ipprc = PS::IPP::Config->new();
-my $mdcParser = PS::IPP::Metadata::Config->new;	# Parser for metadata config files
+
+my $ipprc = PS::IPP::Config->new(); # this is used for PATH, NEB filename conversions
 
 use Getopt::Long qw( GetOptions :config auto_help auto_version gnu_getopt );
@@ -20,14 +24,25 @@
 
 # Parse the command-line arguments
-my ($workdir, $dbname);
+my ($workdir, $dbname, $telescope, $instrument, $help);
 GetOptions(
-    'workdir|w=s'   => \$workdir,  # working directory for output files
-    'dbname|d=s'    => \$dbname    # Database name
+    'workdir|w=s'    => \$workdir, # working directory for output files
+    'dbname|d=s'     => \$dbname, # Database name
+    'telescope|t=s'  => \$telescope, # user-supplied telescope name
+    'instrument|i=s' => \$instrument, # user-supplied instrument name
+    'help'           => \$help # give help listing
 ) or pod2usage( 2 );
 
-pod2usage( -msg => "Usage: $0 [--workdir path] [--dbname dbname] (files)", -exitval => 2 ) if scalar @ARGV == 0;
+pod2usage( -msg => "inject one or many files into the IPP pipeline database", -exitval => 2
+
+pod2usage( -msg => "Usage: $0 --telescope (name) --instrument (name) [--workdir path] [--dbname dbname] (files)", 
+	   -exitval => 2 ) if 
+	   scalar @ARGV == 0;
+
+pod2usage( -msg => "Required options: --telescope (name) --instrument (name)",
+	   -exitval => 3) unless
+	   defined $telescope and
+	   defined $instrument;
 
 my $pxinject = can_run('pxinject') or die "Can't find pxinject\n";
-my $ppStats = can_run('ppStats') or die "Can't find ppStats\n";
 
 # if workdir is not defined, assign the current path
@@ -40,5 +55,5 @@
 foreach my $file ( @ARGV ) {
     my $absfile = File::Spec->rel2abs( $file );
-    inject($absfile, $workdir, $dbname);
+    inject($absfile, $workdir, $dbname, $telescope, $instrument);
     $num ++;
 }
@@ -48,29 +63,16 @@
 sub inject
 {
-    my $absfile = shift;		# absolute path for this file
-    my $workdir  = shift;		# absolute path for output directory
-    my $dbname = shift;
+    my $absfile = shift;	# absolute path for this file
+    my $workdir  = shift;	# absolute path for output directory
+    my $dbname = shift;		# IPP database to use
+    my $telescope = shift;	# user-specified telescope
+    my $instrument = shift;	# user-specified instrument
 
     my ( $vol, $path, $name ) = File::Spec->splitpath( $absfile );
-    my ( $exp ) = $name =~ /(.*)\.fits/;
+    my ( $exp_name ) = $name =~ /(.*)\.fits/;
 
     my $relfile = $ipprc->convert_filename_relative( $absfile );
 
-    my $command_type = "$ppStats -recipe PPSTATS INJECT $absfile";
-
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = run(command => $command_type, verbose => 1);
-    die "Unable to perform ppStats: $error_code\n" if not $success;
-    my $metadata = $mdcParser->parse(join "", @$stdout_buf) 
-        or die "unable to parse metadata config doc";
-
-    my $type;
-    my $telescope;
-    my $instrument;
-    foreach my $row (@$metadata) {
-	if ($row->{name} eq "FPA.TELESCOPE")  { $telescope = $row->{value}; }
-	if ($row->{name} eq "FPA.INSTRUMENT") { $instrument = $row->{value}; } # this entry must return the camera in the ipp/config system which we load
-    }
-    
-    my $command_exp = "$pxinject -newExp -exp_id $exp -inst $instrument -telescope $telescope -imfiles 1 -workdir $workdir" ; # Command to run
+    my $command_exp = "$pxinject -newExp -exp_name $exp_name -inst $instrument -telescope $telescope -imfiles 1 -workdir $workdir" ; # Command to run
     if ($dbname) {
 	$command_exp = "$command_exp -dbname $dbname";
@@ -79,10 +81,11 @@
     my ( $success_exp, $error_code_exp, $full_buf_exp, $stdout_buf_exp, $stderr_buf_exp ) =
 	run( command => $command_exp, verbose => 1 );
-    die "Unable to inject $exp: $error_code_exp\n" if not $success_exp;
+    die "Unable to inject $exp_name: $error_code_exp\n" if not $success_exp;
     
     my @line = split(/\s+/, $$stdout_buf_exp[0]); # The output line, containing the exposure tag
-    my $exp_tag = $line[2];	# The exposure tag
+    my $exp_id = $line[2];	# The exposure tag
     
-    my $command_imfile = "$pxinject -newImfile -exp_tag $exp_tag -class fpa -class_id fpa -uri $relfile"; # Command to run
+    # XXX the class_id used here should be temporary : register should replace it with the true class_id
+    my $command_imfile = "$pxinject -newImfile -exp_id $exp_id -exp_name $exp_name -class fpa -class_id fpa -uri $relfile"; # Command to run
     if ($dbname) {
 	$command_imfile = "$command_imfile -dbname $dbname";
@@ -90,5 +93,5 @@
     
     my ( $success_imfile, $error_code_imfile, $full_buf_imfile, $stdout_buf_imfile, $stderr_buf_imfile ) = run( command => $command_imfile, verbose => 1 );
-    die "Unable to inject $exp imfile: $error_code_imfile\n" if not $success_imfile;
+    die "Unable to inject $exp_name imfile: $error_code_imfile\n" if not $success_imfile;
 
     return 1;
Index: /trunk/ippScripts/scripts/register_exp.pl
===================================================================
--- /trunk/ippScripts/scripts/register_exp.pl	(revision 14020)
+++ /trunk/ippScripts/scripts/register_exp.pl	(revision 14021)
@@ -1,4 +1,5 @@
 #!/usr/bin/env perl
 
+use Carp;
 use warnings;
 use strict;
@@ -9,4 +10,7 @@
 print "\n\n";
 print "Starting script $0 on $host\n\n";
+
+use vars qw( $VERSION );
+$VERSION = '0.01';
 
 use Cache::File;
@@ -31,9 +35,9 @@
     );
 
-my ($cache, $exp_tag, $workdir, $dbname, $no_update, $no_op);
-
+my ($cache, $exp_id, $exp_tag, $workdir, $dbname, $no_update, $no_op);
 GetOptions(
     'caches'        => \$cache,
-    'exp_tag|e=s'   => \$exp_tag,
+    'exp_id|e=s'    => \$exp_id,
+    'exp_tag|t=s'   => \$exp_tag,
     'workdir|w=s'   => \$workdir, # Working directory for output files
     'dbname|d=s'    => \$dbname, # Database name    
@@ -43,47 +47,38 @@
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
-pod2usage(
-    -msg => "Required options: --exp_tag",
-    -exitval => 3,
-) unless defined $exp_tag;
-
-# Define setup
-use constant TYPE => "exp_type"; # Observation type keyword
-
-# should we reverse this?  add -detrend UNLESS type is OBJECT? (we can always queue to chip by hand...)
-# use constant DETRENDS => [ "bias", "zero", "dark", "shutter", "flat", "fringe", "domeflat", "skyflat" ]; # Observation types to mark as detrend
-# use constant DETREND_FLAG => "-detrend"; # Flag to use to mark detrend exposure
-
-use constant SCIENCE => [ "object" ]; # Observation types to NOT mark as detrend
-use constant DETREND_FLAG => "-detrend"; # Flag to use to mark detrend exposure
-
-use constant REGISTER_URI => 'uri'; # Key for the URI
-use constant REGISTER_CLASSID => 'class_id'; # Key for the class id
-use constant REGISTER_BG => 'bg';        # Key for the background
-use constant REGISTER_BG_STDEV => 'bg_stdev'; # Key for the background standard deviation
-use constant REGISTER_BG_MEAN_STDEV => 'bg_mean_stdev'; # Key for the mean of the background standard deviation
-
-# These values should be constant for all components
-use constant CONSTANTS => [
-			   "filelevel",	# File level
-                           "object", # Object
-                           "exp_type", # Exposure type
-                           "filter", # Filter used
-                           "dateobs", # Time of exposure
-                       ];
-
-# These values may vary across components; we will take the average
-use constant VARIABLES => [
-                           "ccd_temp", # CCD temperature
-                           "exp_time", # Exposure time
-                           "sat_pixel_frac", # Fraction of saturated pixels
-                           "airmass", # Airmass
-                           "ra", # Right ascension
-                           "decl", # Declination
-                           "posang", # Position angle
-                           "alt", # Altitude
-                           "az", # Azimuth
-                           ];
-
+pod2usage( -msg => "Required options: --exp_id --exp_tag",
+	   -exitval => 3) unless
+    defined $exp_id and
+    defined $exp_tag;
+
+# add -detrend UNLESS type is one of SCIENCE listed below (eg, OBJECT)
+my @SCIENCE = ( "object" ); # Observation types to NOT mark as detrend
+my $DETREND_FLAG = "-detrend"; # Flag to use to mark detrend exposure
+
+# values to extract from output metadata and the stats to calculate
+my $STATS = 
+   [   
+       #          PPSTATS KEYWORD         STATISTIC          CHIPTOOL FLAG
+       { name => "exp_name",       type => "constant",   flag => "-exp_name" }, # File level
+       { name => "telescope",      type => "constant",   flag => "-telescope" }, # File level
+       { name => "inst",           type => "constant",   flag => "-inst" }, # File level
+       { name => "filelevel",      type => "constant",   flag => "-filelevel" }, # File level
+       { name => "object",         type => "constant",   flag => "-object" },
+       { name => "exp_type",       type => "constant",   flag => "-exp_type" }, # File level
+       { name => "filter",         type => "constant",   flag => "-filter" }, # File level
+       { name => "dateobs",        type => "constant",   flag => "-dateobs" }, # File level
+       { name => "ccd_temp",	   type => "mean", 	 flag => "-ccd_temp" }, # CCD temperature
+       { name => "exp_time",	   type => "mean", 	 flag => "-exp_time" }, # Exposure time
+       { name => "sat_pixel_frac", type => "mean", 	 flag => "-sat_pixel_frac" }, # Fraction of saturated pixels
+       { name => "airmass",	   type => "mean", 	 flag => "-airmass" }, # Airmass
+       { name => "ra",		   type => "mean", 	 flag => "-ra" }, # Right ascension
+       { name => "decl",	   type => "mean", 	 flag => "-decl" }, # Declination
+       { name => "posang",	   type => "mean", 	 flag => "-posang" }, # Position angle
+       { name => "alt",		   type => "mean", 	 flag => "-alt" }, # Altitude
+       { name => "az",		   type => "mean", 	 flag => "-az" }, # Azimuth
+       { name => "bg",		   type => "mean", 	 flag => "-bg" }, # Azimuth
+       { name => "bg",		   type => "stdev", 	 flag => "-bg_mean_stdev" }, # Azimuth
+       { name => "bg_stdev",	   type => "rms", 	 flag => "-bg_stdev" }, # Azimuth
+       ];
 
 # Look for commands we need
@@ -98,5 +93,4 @@
 
 # setup cache interface
-
 my $c = Cache::File->new(
     cache_root => File::Spec->catdir($ENV{'HOME'}, '.pxtools', basename($0)),
@@ -104,10 +98,7 @@
 );
 
-my $mdcParser = PS::IPP::Metadata::Config->new;        # Parser for metadata config files
-
-# Get the list of imfiles
-my $imfiles;
-{
-    my $command = "$regtool -processedimfile -exp_tag $exp_tag";
+# Get the list of imfiles & their stats
+{
+    my $command = "$regtool -processedimfile -exp_id $exp_id";
     $command .= " -dbname $dbname" if defined $dbname;
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -115,125 +106,58 @@
     unless ($success) {
 	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-        warn ("Unable to perform regtool -processedimfile on exposure id $exp_tag: $error_code");
+        warn ("Unable to perform regtool -processedimfile on exposure id $exp_id: $error_code");
         exit ($error_code);
     }
 
+    # Parse the output
+    my $mdcParser = PS::IPP::Metadata::Config->new;        # Parser for metadata config files
     my $metadata = $mdcParser->parse(join "", @$stdout_buf);
     unless ($metadata) {
-        warn ("Unable to parse metadata config doc");
-        &my_die ($exp_tag, $PS_EXIT_PROG_ERROR);
-    }
-    $imfiles = parse_md_list($metadata); # Data for imfiles
-}
-
-# Process the values
-my %values;                        # Values to update
-foreach my $variable (@{VARIABLES()}) {
-    $values{$variable} = [];
-}
-my @backgrounds;                # Array of backgrounds
-my @variances;                        # Array of background standard deviations\
-my $obsType;                        # Observation type
-  
-foreach my $imfile (@$imfiles) {
-    foreach my $constant (@{CONSTANTS()}) {
-        my $value = get_value($imfile, $constant); # Value for imfile
-        if (not defined $values{$constant}) {
-            $values{$constant} = $value;
-        }
-        if ($values{$constant} ne $value) {
-            warn ("Value of $constant for " . $imfile->{REGISTER_CLASSID()} .
-		  " doesn't match previous value");
-            &my_die($exp_tag, $PS_EXIT_PROG_ERROR);
-        }
-    }
-    
-    foreach my $variable (@{VARIABLES()}) {
-        my $value = get_value($imfile, $variable); # Value for imfile
-        my $array = $values{$variable};        # Array of data
-        push @$array, $value;
-    }
-    
-    my $bg = get_value($imfile, REGISTER_BG());
-    push @backgrounds, $bg;
-    
-    my $stdev = get_value($imfile, REGISTER_BG_MEAN_STDEV());
-    push @variances, $stdev**2;
-}
-
-if (0) {
-# XXX for a test, randomly declare a failure and return to pantasks
-    my $rnd = rand(1);
-    if ($rnd > 0.5) {
-	warn ("random failure");
-	&my_die ($exp_tag, $PS_EXIT_DATA_ERROR);
-    }
+        &my_die ("Unable to parse metadata config doc", $exp_id, $PS_EXIT_PROG_ERROR);
+    }
+
+    # extract the stats from the metadata
+    my $stats = PS::IPP::Metadata::Stats->new($STATS); # Stats parser
+    unless ($stats->parse($metadata)) {
+        &my_die ("Unable to find all values", $exp_id, $class_id, $PS_EXIT_CONFIG_ERROR);
+    }
+}
+
+my $command = "$regtool -addprocessedexp";
+$command .= " -exp_id $exp_id";
+$command .= " -exp_tag $exp_tag";
+$command .= " -dbname $dbname" if defined $dbname;
+
+# add in the elements from the selected stats above
+foreach my $entry (@$STATS) {
+    my $value = $entry->{value};
+    my $flag = $entry->{flag};
+    $command .= " $flag $value";
+}
+
+my $exp_type = &STATS_value_for_flag ("-exp_type");
+
+# Add the detrend flag, if needed
+foreach my $scienceType (@SCIENCE) {
+    if (lc($exp_type) =~ /$scienceType/) {
+	last;
+    }
+    $command .= " $DETREND_FLAG";
 }
 
 # Output results to the database
 unless ($no_update) {
-    my $command = "$regtool -addprocessedexp -exp_tag $exp_tag"; # Command to execute
-    
-    # Add the values of interest
-    foreach my $constant (@{CONSTANTS()}) {
-	my $value = $values{$constant};
-	if ($value =~ /\s/) {
-	    # Quote spaces
-	    $value = "\'$value\'";
-	}
-	$command .= " -$constant $value";
-    }
-    foreach my $variable (@{VARIABLES()}) {
-        my $array = $values{$variable};        # Array of values
-        my $stats = Statistics::Descriptive::Sparse->new; # Statistics calculator
-        $stats->add_data(@$array);
-
-	$command .= " -$variable " . $stats->mean();
-    }
-
-    # Add the statistics
-    my $meanStats = Statistics::Descriptive::Sparse->new; # Statistics calculator
-    $meanStats->add_data(@backgrounds);
-    my $stdevStats = Statistics::Descriptive::Sparse->new; # Statistics calculator
-    $stdevStats->add_data(@variances);
-    my $bg = ($meanStats->mean() or 'NAN');
-    my $bg_stdev = (sqrt($stdevStats->mean()) or 'NAN');
-    my $bg_mean_stdev = ($meanStats->standard_deviation() or 'NAN');
-    $command .= " -bg $bg -bg_stdev $bg_stdev -bg_mean_stdev $bg_mean_stdev";
-    
-    # Add the detrend flag
-    foreach my $scienceType (@{SCIENCE()}) {
-        if (lc($values{TYPE()}) =~ /$scienceType/) {
-            last;
-        }
-	$command .= ' ' . DETREND_FLAG;
-    }
-
-    $command .= " -dbname $dbname" if defined $dbname;
-
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
         cache_run(command => $command, verbose => 1);
     unless ($success) {
 	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-        warn ("Unable to run regtool -addprocessedexp for $exp_tag: $error_code");
+        warn ("Unable to run regtool -addprocessedexp for $exp_id: $error_code");
         exit($error_code);
     }
+} else {
+    print "skipping command: $command\n";
 }
 
 ### Pau.
-
-# Get the value for a particular imfile, along with a strong check for its existence
-sub get_value {
-    my $imfile = shift;                # The hash of values
-    my $name = shift;                # The name of the value to check
-
-    my $source = $imfile->{REGISTER_CLASSID()}; # Where it comes from
-
-    unless (defined $imfile->{$name}) {
-        warn ("Couldn't find value of $name for class_id=$source");
-        &my_die ($exp_tag, $PS_EXIT_PROG_ERROR);
-    }
-    return $imfile->{$name};
-}
 
 sub cache_run
@@ -253,12 +177,28 @@
 sub my_die
 {
-    my $exp_tag = $_[0];
-    my $exit_code = $_[1];
-    if ($exp_tag and not $no_update) {
-	my $command = "$regtool -addprocessedexp -exp_tag $exp_tag -code $exit_code";
+    my $msg = shift; # Warning message on die
+    my $exp_id = shift;
+    my $exit_code = shift;
+
+    carp($msg);
+    if ($exp_id and not $no_update) {
+	my $command = "$regtool -addprocessedexp -exp_id $exp_id -code $exit_code";
 	$command .= " -dbname $dbname" if defined $dbname;
 ###        system($command);
     }
     exit $exit_code;
+}
+
+sub STATS_value_for_flag 
+{
+    my $STATS = shift;
+    my $flag  = shift;
+
+    foreach my $entry (@$STATS) {
+	if ($flag eq $entry->{flag}) {
+	    return $entry->{value};
+	}
+    }
+    return 'NAN';
 }
 
Index: /trunk/ippScripts/scripts/register_imfile.pl
===================================================================
--- /trunk/ippScripts/scripts/register_imfile.pl	(revision 14020)
+++ /trunk/ippScripts/scripts/register_imfile.pl	(revision 14021)
@@ -1,4 +1,5 @@
 #!/usr/bin/env perl
 
+use Carp;
 use warnings;
 use strict;
@@ -37,10 +38,10 @@
 use Pod::Usage qw( pod2usage );
 
-my ($cache, $exp_tag, $class_id, $uri, $workdir, $dbname, $no_update, $no_op);
-
+my ($cache, $exp_id, $class_id, $exp_name, $uri, $workdir, $dbname, $no_update, $no_op);
 GetOptions(
     'caches'        => \$cache,
-    'exp_tag|e=s'   => \$exp_tag,
+    'exp_id|e=s'    => \$exp_id,
     'class_id|i=s'  => \$class_id,
+    'exp_name|n=s'  => \$exp_name,
     'uri|u=s'       => \$uri,
     'workdir|w=s'   => \$workdir, # Working directory for output files
@@ -51,37 +52,38 @@
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
-pod2usage(
-    -msg => "Required options: --exp_tag --class_id --uri",
-    -exitval => 3,
-) unless defined $exp_tag 
-    and defined $class_id 
-    and defined $uri;
+pod2usage( -msg => "Required options: --exp_id --class_id --exp_name --uri",
+	   -exitval => 3) unless
+    defined $exp_id and
+    defined $class_id and
+    defined $exp_name and
+    defined $uri;
 
 my $RECIPE = "REGISTER"; # Recipe to use for ppStats
 
-# These values should be constant for all components
-# The key is the name in the ppStats output; the value is the switch for "phase0 -updateexp"
-use constant CONSTANTS => {
-    "FILE.LEVEL"   => "-filelevel", # File level
-    "FPA.OBJECT"   => "-object", # Object
-    "FPA.OBSTYPE"  => "-exp_type", # Exposure type
-    "FPA.FILTER"   => "-filter", # Filter used
-    "FPA.AIRMASS"  => "-airmass", # Airmass
-    "FPA.RA"       => "-ra",        # Right ascension
-    "FPA.DEC"      => "-decl",        # Declination
-    "FPA.ALT"      => "-alt",        # Altitude
-    "FPA.AZ"       => "-az",        # Azimuth
-    "FPA.POSANGLE" => "-posang", # Position angle
-    "FPA.TIME"     => "-dateobs", # Date of observation (UTC)
-    };
-
-# These values may vary across components; we will take the average
-# The key is the name in the ppStats output; the value is the switch for "phase0 -updateexp"
-use constant VARIABLES => {
-    "CHIP.TEMP"      => "-ccd_temp", # CCD temperature
-    "CELL.EXPOSURE"  => "-exp_time", # Exposure time
-    "SAT_PIXEL_FRAC" => "-sat_pixel_frac" # fraction of saturated pixels
-    };
-
+# values to extract from output metadata and the stats to calculate
+my $STATS = 
+   [   
+       #          PPSTATS KEYWORD         STATISTIC          CHIPTOOL FLAG
+       { name => "FILE.LEVEL",     type => "constant", flag => "-filelevel" }, # File level
+       { name => "CLASS.ID",       type => "constant", flag => "-class_id" },  # Real Class ID
+       { name => "FPA.OBJECT",     type => "constant", flag => "-object" },    # Object
+       { name => "FPA.OBSTYPE",    type => "constant", flag => "-exp_type" },  # Exposure type
+       { name => "FPA.FILTER",     type => "constant", flag => "-filter" },    # Filter used
+       { name => "FPA.AIRMASS",    type => "constant", flag => "-airmass" },   # Airmass
+       { name => "FPA.RA",         type => "constant", flag => "-ra" },        # Right ascension
+       { name => "FPA.DEC",        type => "constant", flag => "-decl" },      # Declination
+       { name => "FPA.ALT",        type => "constant", flag => "-alt" },       # Altitude
+       { name => "FPA.AZ",         type => "constant", flag => "-az" },        # Azimuth
+       { name => "FPA.POSANGLE",   type => "constant", flag => "-posang" },    # Position angle
+       { name => "FPA.TIME",       type => "constant", flag => "-dateobs" },   # Date of observation (UTC)
+       { name => "FPA.TELESCOPE",  type => "constant", flag => "-telescope" }, # Telescope
+       { name => "FPA.INSTRUMENT", type => "constant", flag => "-inst" },      # Instrument 
+       { name => "CHIP.TEMP"       type => "mean",     flag => "-ccd_temp" }, # CCD temperature
+       { name => "CELL.EXPOSURE"   type => "mean",     flag => "-exp_time" }, # Exposure time
+       { name => "SAT_PIXEL_FRAC"  type => "mean",     flag => "-sat_pixel_frac" } # fraction of saturated pixels
+       { name => "ROBUST_MEDIAN",  type => "mean",     flag => "-bg" },
+       { name => "ROBUST_MEDIAN",  type => "stdev",    flag => "-bg_mean_stdev" },
+       { name => "ROBUST_STDEV",   type => "rms",      flag => "-bg_stdev" },
+   ];
 
 # Look for programs we need
@@ -105,6 +107,6 @@
 
 # Run ppStats on the input file
-my $stats;
 {
+    # extract the data from the image header; -level is used to get FILE.LEVEL and CLASS.ID
     my $command = "$ppStats $uri -recipe PPSTATS $RECIPE -level"; # Command to run ppStats
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
@@ -112,6 +114,5 @@
     unless ($success) { 
 	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-        warn ("Unable to perform ppStats on exposure id $exp_tag: $error_code");
-        &my_die ($exp_tag, $class_id, $error_code);
+        &my_die ("Unable to perform ppStats on exposure id $exp_id: $error_code", $exp_id, $class_id, $error_code);
     }
     
@@ -120,49 +121,33 @@
     my $metadata = $mdcParser->parse(join "", @$stdout_buf); # XXX is this join necessary?
     unless ($metadata) {
-        warn ("Unable to parse metadata config doc");
-        &my_die ($exp_tag, $class_id, $PS_EXIT_PROG_ERROR);
+        &my_die ("Unable to parse metadata config doc", $exp_id, $class_id, $PS_EXIT_PROG_ERROR);
     }
-    my @constants = keys %{CONSTANTS()}; # List of constants to parse out
-    my @variables = keys %{VARIABLES()}; # List of variables to parse out
 
-    $stats = PS::IPP::Metadata::Stats->new(\@constants, \@variables); # Stats parser
+    # extract the stats from the metadata
+    my $stats = PS::IPP::Metadata::Stats->new($STATS); # Stats parser
     unless ($stats->parse($metadata)) {
-        warn ("Unable to find all values");
-        &my_die ($exp_tag, $class_id, $PS_EXIT_CONFIG_ERROR);
+        &my_die ("Unable to find all values", $exp_id, $class_id, $PS_EXIT_CONFIG_ERROR);
     }
+}
+
+my $command = "$regtool -addprocessedimfile";
+$command .= " -exp_id $exp_id";
+$command .= " -temp_class_id $class_id"; # the original class_id supplied by the user, replace by ppStats CLASS.ID
+$command .= " -exp_name $exp_name"; # keep the supplied exp_name (could be derived from the file)
+$command .= " -dbname $dbname" if defined $dbname;
+
+# add in the elements from the selected stats above
+foreach my $entry (@$STATS) {
+    my $value = $entry->{value};
+    my $flag = $entry->{flag};
+    $command .= " $flag $value";
 }
 
 # Push the results into the database
 unless ($no_update) {
-    my $command = "$regtool -addprocessedimfile -exp_tag $exp_tag -class_id $class_id"; # Command to run regtool
-
-    foreach my $constant (keys %{CONSTANTS()}) {
-	my $value = ($stats->data($constant))->{value};
-	if ($value =~ /\s/) {
-	    # Quote arguments with whitespace
-            $value = "\'$value\'";
-        }
-        $command .=  ' ' . CONSTANTS->{$constant} . ' ' . $value;
-    }
-
-    foreach my $variable (keys %{VARIABLES()}) {
-        # Just use the mean value
-        $command .= ' ' . VARIABLES->{$variable} . ' ' . ($stats->data($variable))->{mean};
-    }
-
-    my $bg            = $stats->bg_mean();
-    my $bg_stdev      = $stats->bg_stdev();
-    my $bg_mean_stdev = $stats->bg_mean_stdev();
-
-    $command .= " -bg $bg -bg_stdev $bg_stdev -bg_mean_stdev $bg_mean_stdev";
-    $command .= " -dbname $dbname" if defined $dbname;
-
     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);
-        # If we can't run -addprocessedimfile, we can't actually set the error code. If this is not
-	# a database error, it is probably a programming error (in regtool or the passed args)
         warn ("Unable to perform regtool -addprocessedimfile: $error_code");
         exit($error_code);
@@ -186,9 +171,15 @@
 sub my_die
 {
-    my $exp_tag = $_[0];
-    my $class_id = $_[1];
-    my $exit_code = $_[2];
-    if ($exp_tag && $class_id and not $no_update) {
-	my $command = "$regtool -addprocessedimfile -exp_tag $exp_tag -class_id $class_id -code $exit_code";
+    my $msg = shift; # Warning message on die
+    my $exp_id = shift;
+    my $class_id = shift;
+    my $exit_code = shift;
+
+    carp($msg);
+    if ($exp_id && $class_id and not $no_update) {
+	my $command = "$regtool -addprocessedimfile";
+	$command .= " -exp_id $exp_id";
+	$command .= " -class_id $class_id";
+	$command .= " -code $exit_code";
 	$command .= " -dbname $dbname" if defined $dbname;
 ###        system ($command);
