Index: /trunk/ippTools/share/pxadmin_create_tables.sql
===================================================================
--- /trunk/ippTools/share/pxadmin_create_tables.sql	(revision 25424)
+++ /trunk/ippTools/share/pxadmin_create_tables.sql	(revision 25425)
@@ -223,4 +223,5 @@
     teltemp_extra FLOAT,
     pon_time FLOAT,
+    burntool_state SMALLINT,
     user_1 DOUBLE,
     user_2 DOUBLE,
Index: /trunk/ippTools/share/regtool_updateprocessedimfile.sql
===================================================================
--- /trunk/ippTools/share/regtool_updateprocessedimfile.sql	(revision 25424)
+++ /trunk/ippTools/share/regtool_updateprocessedimfile.sql	(revision 25425)
@@ -1,4 +1,4 @@
 UPDATE rawImfile
-  SET user_1 = %lf
+  SET burntool_state = %d
   WHERE
     rawImfile.exp_id = %lld
Index: /trunk/ippTools/src/regtool.c
===================================================================
--- /trunk/ippTools/src/regtool.c	(revision 25424)
+++ /trunk/ippTools/src/regtool.c	(revision 25425)
@@ -224,4 +224,5 @@
     PXOPT_LOOKUP_F32(teltemp_extra, config->args, "-teltemp_extra", false, false);
     PXOPT_LOOKUP_F32(pon_time, config->args, "-pon_time", false, false);
+    PXOPT_LOOKUP_S16(burntool_state, config->args, "-burntool_state", false, false);
     PXOPT_LOOKUP_F64(user_1, config->args, "-user_1", false, false);
     PXOPT_LOOKUP_F64(user_2, config->args, "-user_2", false, false);
@@ -467,12 +468,13 @@
 
     PXOPT_LOOKUP_S16(fault, config->args, "-fault",   false, false);
-    PXOPT_LOOKUP_F64(user_1, config->args, "-user_1", false, false);
-
-    if ((fault == INT16_MAX) && !isfinite(user_1)) { 
-        psError(PS_ERR_UNKNOWN, false, "one of -fault or -user_1 must be selected");
-        return false;
-    }
-    if ((fault != INT16_MAX) && isfinite(user_1)) { 
-        psError(PS_ERR_UNKNOWN, false, "only one of -fault or -user_1 must be selected");
+/*     PXOPT_LOOKUP_F64(user_1, config->args, "-user_1", false, false); */
+    PXOPT_LOOKUP_S16(burntool_state, config->args, "-burntool_state", false, false);
+    
+    if ((fault == INT16_MAX) && !isfinite(burntool_state)) { 
+        psError(PS_ERR_UNKNOWN, false, "one of -fault or -burntool_state must be selected");
+        return false;
+    }
+    if ((fault != INT16_MAX) && isfinite(burntool_state)) { 
+        psError(PS_ERR_UNKNOWN, false, "only one of -fault or -burntool_state must be selected");
         return false;
     }
@@ -491,5 +493,5 @@
     }
 
-    if (isfinite(user_1)) {
+    if (isfinite(burntool_state)) {
 	psString query = pxDataGet("regtool_updateprocessedimfile.sql");
 	if (!query) {
@@ -498,5 +500,5 @@
 	}
 
-	if (!p_psDBRunQueryF(config->dbh, query, user_1, exp_id, class_id)) {
+	if (!p_psDBRunQueryF(config->dbh, query, burntool_state, exp_id, class_id)) {
 	    psError(PS_ERR_UNKNOWN, false, "database error");
 	    psFree(query);
Index: /trunk/ippTools/src/regtoolConfig.c
===================================================================
--- /trunk/ippTools/src/regtoolConfig.c	(revision 25424)
+++ /trunk/ippTools/src/regtoolConfig.c	(revision 25425)
@@ -155,5 +155,5 @@
     ADD_OPT(S64, updateprocessedimfileArgs, "-exp_id",        "search by exposure ID", 0);
     ADD_OPT(Str, updateprocessedimfileArgs, "-class_id",      "search by class ID", NULL);
-    ADD_OPT(F64, updateprocessedimfileArgs, "-user_1",        "set user stat (1)", NAN);
+    ADD_OPT(S16, updateprocessedimfileArgs, "-burntool_state",        "set burntool state", 0);
     ADD_OPT(S16, updateprocessedimfileArgs, "-fault",          "set fault code", INT16_MAX);
 
Index: /trunk/ippconfig/gpc1/camera.config
===================================================================
--- /trunk/ippconfig/gpc1/camera.config	(revision 25424)
+++ /trunk/ippconfig/gpc1/camera.config	(revision 25425)
@@ -147,2 +147,4 @@
 
 PHOTCODE.RULE           STR     {DETECTOR}.{FILTER.ID}.{CHIP.NAME}	# Rule for generating photcode
+
+BURNTOOL.STATE.GOOD     S16     12  # Value for burntool_state with the most recent bt version.
Index: /trunk/ippconfig/gpc1/format_20090220.config
===================================================================
--- /trunk/ippconfig/gpc1/format_20090220.config	(revision 25424)
+++ /trunk/ippconfig/gpc1/format_20090220.config	(revision 25425)
@@ -207,4 +207,6 @@
         FPA.TELTEMP.TRUSS  STR  TELTEMTR # Mid truss temperatures (C
         FPA.TELTEMP.EXTRA  STR  TELTEMEX # Miscellaneous temperatures (C)     
+
+	FPA.BURNTOOL.APPLIED STR BTOOLAPP
 
         FPA.PON.TIME    STR     PONTIME
Index: /trunk/ippconfig/recipes/ppImage.config
===================================================================
--- /trunk/ippconfig/recipes/ppImage.config	(revision 25424)
+++ /trunk/ippconfig/recipes/ppImage.config	(revision 25425)
@@ -56,5 +56,6 @@
 SCAN.ROWS        S32     100
 
-BURNTOOL.TRAILS U16 0x01
+# Which regions identified by burntool to mask. 0x01 : only unfit trails, 0x02 "up" trails, 0x04 "down" trails
+BURNTOOL.TRAILS     U16 0x01
 
 # Non-linearity correction
Index: /trunk/ippconfig/recipes/ppStats.config
===================================================================
--- /trunk/ippconfig/recipes/ppStats.config	(revision 25424)
+++ /trunk/ippconfig/recipes/ppStats.config	(revision 25425)
@@ -190,4 +190,6 @@
   CONCEPT       STR     FPA.TELTEMP.EXTRA  # Miscellaneous temperatures (C)     
 
+  CONCEPT       STR     FPA.BURNTOOL.APPLIED 
+
   CONCEPT       STR	FPA.PON.TIME    # time since last power on
 
Index: /trunk/ippconfig/recipes/ppStatsFromMetadata.config
===================================================================
--- /trunk/ippconfig/recipes/ppStatsFromMetadata.config	(revision 25424)
+++ /trunk/ippconfig/recipes/ppStatsFromMetadata.config	(revision 25425)
@@ -44,4 +44,5 @@
   ENTRY  VAL  FPA.TELTEMP.EXTRA   F32  CONSTANT          -teltemp_extra       # Miscellaneous temperatures (C)
   ENTRY  VAL  FPA.PON.TIME     	  F32  CONSTANT          -pon_time            # time since last power on
+#  ENTRY  VAL  FPA.BURNTOOL.APPLIED S32 CONSTANT          -burntool_state      # 
   ENTRY  VAL  CHIP.TEMP        	  F32  SAMPLE_MEAN       -ccd_temp            # CCD temperature
   ENTRY  VAL  CELL.EXPOSURE    	  F32  SAMPLE_MEAN       -exp_time            # Exposure time
Index: /trunk/psModules/src/concepts/pmConcepts.c
===================================================================
--- /trunk/psModules/src/concepts/pmConcepts.c	(revision 25424)
+++ /trunk/psModules/src/concepts/pmConcepts.c	(revision 25425)
@@ -329,4 +329,5 @@
         conceptRegisterF32("FPA.TELTEMP.EXTRA", "Telescope Temperatures: extra", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA);
         conceptRegisterF32("FPA.PON.TIME", "Power On Time", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA);
+	conceptRegisterS32("FPA.BURNTOOL.APPLIED", "Status of burntool processing", p_pmConceptParse_BTOOLAPP,NULL,NULL,false,PM_FPA_LEVEL_FPA);
         conceptRegisterF32("FPA.EXPOSURE", "Exposure time (sec)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA);
     }
@@ -344,4 +345,5 @@
         conceptRegisterF32("CHIP.TEMP", "Temperature of chip", NULL, NULL, NULL, false, PM_FPA_LEVEL_CHIP);
         conceptRegisterStr("CHIP.ID", "Chip identifier", NULL, NULL, NULL, false, PM_FPA_LEVEL_CHIP);
+
     }
 
Index: /trunk/psModules/src/concepts/pmConceptsRead.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsRead.c	(revision 25424)
+++ /trunk/psModules/src/concepts/pmConceptsRead.c	(revision 25425)
@@ -73,5 +73,4 @@
         return false;
     }
-
     psTrace ("psModules.concepts", 3, "parsing concept: %s\n", spec->blank->name);
     if (!strcmp (spec->blank->name, "CELL.XPARITY")) {
@@ -275,4 +274,5 @@
         psMetadataItem *headerItem = NULL; // The value of the concept from the header
 
+
         psTrace ("psModules.concepts", 3, "reading concept: %s\n", name);
         if (!strcmp (name, "CELL.XPARITY")) {
@@ -307,5 +307,4 @@
             }
         }
-
         if (!headerItem) {
             psMetadataItem *formatItem = psMetadataLookup(transSpec, name); // Item with keyword
@@ -328,5 +327,4 @@
             }
             psString keywords = formatItem->data.str; // The FITS keywords
-
             // In case there are multiple headers
             psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords
Index: /trunk/psModules/src/concepts/pmConceptsStandard.c
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 25424)
+++ /trunk/psModules/src/concepts/pmConceptsStandard.c	(revision 25425)
@@ -160,5 +160,4 @@
     assert(concept);
     assert(pattern);
-
     double value = NAN;
     switch (concept->type) {
@@ -632,4 +631,34 @@
     return psMetadataItemAllocS32(pattern->name, pattern->comment, binning);
 }
+
+// BTOOLAPP
+psMetadataItem *p_pmConceptParse_BTOOLAPP(const psMetadataItem *concept,
+					  const psMetadataItem *pattern,
+					  pmConceptSource source,
+					  const psMetadata *cameraFormat,
+					  const pmFPA *fpa,
+					  const pmChip *chip,
+					  const pmCell *cell)
+{
+  assert(concept);
+  assert(pattern);
+
+  int bt_status = 0;
+
+  if (concept->type != PS_DATA_BOOL) {
+    psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Type for %s (%x) is not BOOL\n",
+	    concept->name, concept->type);
+    return NULL;
+  }
+
+  if (concept->data.B == true) {
+    bt_status = -2;
+  }
+  else if (concept->data.B == false) {
+    bt_status = 1 ;
+  }
+  
+  return psMetadataItemAllocS32(concept->name, concept->comment, bt_status);
+}  
 
 // Get the current value of a concept
Index: /trunk/psModules/src/concepts/pmConceptsStandard.h
===================================================================
--- /trunk/psModules/src/concepts/pmConceptsStandard.h	(revision 25424)
+++ /trunk/psModules/src/concepts/pmConceptsStandard.h	(revision 25425)
@@ -115,4 +115,16 @@
     );
 
+/// Format for the BTOOLAPP conceptn
+psMetadataItem *p_pmConceptParse_BTOOLAPP(
+    const psMetadataItem *concept, ///< Concept to format
+    const psMetadataItem *pattern,
+    pmConceptSource source, ///< Source for concept
+    const psMetadata *cameraFormat, ///< Camera format definition
+    const pmFPA *fpa, ///< FPA for concept, or NULL
+    const pmChip *chip, ///< Chip for concept, or NULL
+    const pmCell *cell ///< Cell for concept, or NULL
+    );
+
+
 /// Parse the cell binning concepts: CELL.XBIN, CELL.YBIN
 psMetadataItem *p_pmConceptParse_CELL_Binning(
Index: /trunk/tools/examine_burntool_pcontrol.pl
===================================================================
--- /trunk/tools/examine_burntool_pcontrol.pl	(revision 25424)
+++ /trunk/tools/examine_burntool_pcontrol.pl	(revision 25425)
@@ -2,5 +2,4 @@
 
 # script to print out information about the current status of a burntool run.
-
 use DBI;
 use Getopt::Std;
@@ -15,24 +14,50 @@
     print STDERR "         status of the processing.  On the OTA grid:\n";
     print STDERR "                  _             Blank chip\n";
-    print STDERR "                  N             Null value for user_1. No burntool attempted.\n";
-    print STDERR "                  O             0.1 value for user_1. Burntool failed or is running.\n";
-    print STDERR "                  B             1.0 value for user_1. Burntool succeeded.\n";
+    print STDERR "                  N             Null/zero value for burntool_state. No burntool attempted.\n";
+    print STDERR "                  O             -1 value for burntool_state. Burntool is running.\n";
+    print STDERR "                  E             -2 value for burntool_state. Error!\n";
+    print STDERR "                  B             Current version value for burntool_state. Burntool succeeded.\n";
+    print STDERR "                  b             Old version value for burntool_state. Burntool needs to be rerun.\n";
     exit(1);
 }
-
-# Read a class_id and user_1 pair, and set the correct cell of the (sorry, global) character array vector
+$| = 1;
+# Determine what the value of "BURNTOOL.STATE.GOOD" currently is:
+$burntoolStateGood = 999;
+open(LAZY,"ppConfigDump -camera GPC1 -dump-camera - |") || die "Can't run ppConfigDump\n";
+while(<LAZY>) {
+    chomp;
+    if ($_ =~ /BURNTOOL.STATE.GOOD/) {
+	@line = split /\s+/;
+	$burntoolStateGood = $line[2];
+    }
+}
+close(LAZY);
+unless( $burntoolStateGood == 999) {
+    print STDERR "GOOD == $burntoolStateGood\n";
+}
+
+# Read a class_id and burntool_state pair, and set the correct cell of the (sorry, global) character array vector
 sub class_to_vector {
     my $class = shift;
-    my $user1 = shift;
+    my $burntool_state = shift;
     my $char = '_';
-    if ($user1 == 1.0) {
-	$char = '[32mB[m';
+    if (abs($burntool_state) == $burntoolStateGood) {
+	$char = '[32;01mB[m';
 	$burncount++;
     }
-    elsif ($user1 == 0.1) {
+    elsif ($burntool_state == -1) {
+	$char = '[01;33mP[m';
+    }
+    elsif ($burntool_state == 0) {
 	$char = '[31mO[m';
     }
-    elsif ($user1 == -1.0) {
-	$char = '[34mN[m';
+    elsif ($burntool_state == -2) {
+	$char = '[35;01;44;05mE[m';
+    }
+    elsif ($burntool_state == -3) {
+	$char = '[34mX[m';
+    }
+    else {
+	$char = '[32mb[m';
     }
     
@@ -47,5 +72,4 @@
 # Engauge autoflush, in case the database server is acting up.
 $| = 1;
-
 
 # Load the pcontrol.pro file, and create arrays of the dates included
@@ -96,5 +120,5 @@
     # Get the data.  The limit is there to keep the database happy.  I don't think you can observe that many
     # images on a single night.
-    $sth = "SELECT exp_id,exp_name,obs_mode,dateobs,class_id,user_1,comment FROM rawImfile WHERE dateobs >= '${dmin}' AND dateobs <= '${dmax}' order by dateobs limit 60000";
+    $sth = "SELECT exp_id,exp_name,obs_mode,dateobs,class_id,burntool_state,comment FROM rawImfile WHERE dateobs >= '${dmin}' AND dateobs <= '${dmax}' order by dateobs limit 60000";
     $data_ref = $db->selectall_arrayref( $sth );
 
@@ -122,19 +146,20 @@
     
     foreach $row_ref (@{ $data_ref }) {
-	($exp_id,$exp_name, $obs_mode,$dateobs,$class_id,$user_1,$comment) = @{ $row_ref };
+	($exp_id,$exp_name, $obs_mode,$dateobs,$class_id,$burntool_state,$comment) = @{ $row_ref };
+
 	# Correct for nulls in the database.
 	if (!defined($obs_mode)) {
 	    $obs_mode = 'NULL';
 	}
-	if (!defined($user_1)) {
-	    $user_1 = -1;
+	if (!defined($burntool_state)) {
+	    $burntool_state = 0;
 	}
 	if (!defined($comment)) {
 	    $comment = ' ';
 	}
-
+#	print "$exp_id $class_id $burntool_state\n";
 	# If we're still working on the same exp_id, update the chip we got
 	if ($exp_id == $cur_exp_id) {
-	    class_to_vector($class_id,$user_1);
+	    class_to_vector($class_id,$burntool_state);
 	}
 	else {
@@ -156,5 +181,5 @@
 	    }
 	    ($cur_exp_id,$cur_exp_name,$cur_obs_mode,$cur_dateobs,$cur_comment) = ($exp_id,$exp_name,$obs_mode,$dateobs,$comment);
-	    class_to_vector($class_id,$user_1);
+	    class_to_vector($class_id,$burntool_state);
 	}
     }
@@ -169,6 +194,6 @@
     if ($burncount != 60) {
 	for ($j = 0; $j < 64; $j++) {
-	    $vector[$j] =~ s/\[..m(.).*/$1/;
-	    if ($vector[$j] ne 'B') {
+#	    printf("%d %s %d\n",$j, $vector[$j], ($vector[$j] !~ /B/));
+	    if ($vector[$j] !~ /B/) {
 		if ($vector[$j] ne '_') {
 		    $id = sprintf("XY%d%d",int($j / 8),$j % 8);
Index: /trunk/tools/ipp_apply_burntool.pl
===================================================================
--- /trunk/tools/ipp_apply_burntool.pl	(revision 25424)
+++ /trunk/tools/ipp_apply_burntool.pl	(revision 25425)
@@ -12,6 +12,6 @@
 use Carp;
 
-use IPC::Cmd 0.36 qw( can_run );
-use IPC::Run 0.36 qw( run );
+use IPC::Cmd 0.36 qw( can_run run );
+#use IPC::Run 0.36 qw( run );
 use PS::IPP::Metadata::List qw( parse_md_list );
 use PS::IPP::Config 1.01 qw( :standard );
@@ -20,15 +20,15 @@
 use Pod::Usage qw( pod2usage );
 
-my ( $class_id, $dateobs_begin, $dateobs_end, $skip_burned, $rerun_from_first, $dbname, $logfile, $verbose, $save_temps);
+my ( $class_id, $dateobs_begin, $dateobs_end, $convert, $camera, $dbname, $logfile, $verbose, $save_temps);
 GetOptions(
     'class_id=s'        => \$class_id, # chip identifier
     'dateobs_begin=s'   => \$dateobs_begin, # exposure date/time range start
     'dateobs_end=s'     => \$dateobs_end, # exposure date/time range stop
+    'camera=s'          => \$camera,     # Camera
     'dbname|d=s'        => \$dbname, # Database name
     'logfile=s'         => \$logfile,
-    'skip_burned'       => \$skip_burned,   # Print to stdout
-    'rerun_from_first'  => \$rerun_from_first,   # Print to stdout
     'verbose'           => \$verbose,   # Print to stdout
     'save-temps'        => \$save_temps, # Save temporary files?
+
     ) or pod2usage( 2 );
 
@@ -43,5 +43,8 @@
     defined $dbname;
 
-if ($skip_burned and $rerun_from_first) { &my_die("-rerun_from_first and -skip_burned are incompatible"); }
+unless (defined $camera) {
+    $camera = "GPC1";
+#    warn("No camera defined. Defaulting to $camera and warning.");
+}
 
 my $missing_tools;
@@ -49,5 +52,6 @@
 my $funpack  = can_run('funpack')  or (warn "Can't find funpack" and $missing_tools = 1);
 my $burntool = can_run('burntool') or (warn "Can't find burntool" and $missing_tools = 1);
-my $fpack    = can_run('fpack')    or (warn "Can't find fpack" and $missing_tools = 1);
+my $ppConfigDump = can_run('ppConfigDump') or (warn "Can't find ppConfigDump" and $missing_tools = 1);
+#my $fpack    = can_run('fpack')    or (warn "Can't find fpack" and $missing_tools = 1);
 if ($missing_tools) {
     warn("Can't find required tools.");
@@ -57,4 +61,35 @@
 my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
 
+# IPP configuration (including nebulous)
+my $ipprc = PS::IPP::Config->new( $camera ) or my_die("Unable to set up");
+
+$ipprc->redirect_output($logfile) if $logfile;
+
+# Determine the value of a "good" burntool run.
+my $config_cmd = "$ppConfigDump -camera $camera -dump-camera - | grep BURNTOOL";
+my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+    run ( command => $config_cmd, verbose => $verbose);
+unless ($success) {
+    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+    &my_die("Unable to perform ppConfigDump: $error_code", 0, 0, $class_id, $PS_EXIT_SYS_ERROR);
+}
+
+my $recipeData = $mdcParser->parse(join "", @$stdout_buf) or
+    &my_die("Unable to parse metadata config doc", 0, 0, $class_id, $PS_EXIT_SYS_ERROR);
+
+my $burntoolStateGood = 999;
+foreach my $cfg (@$recipeData) {
+    if ($cfg->{name} eq 'BURNTOOL.STATE.GOOD') {
+	$burntoolStateGood = $cfg->{value};
+    }
+}
+if ($burntoolStateGood == 999) {
+    &my_die("Failed to determine BURNTOOL.STATE.GOOD", $burntoolStateGood, $class_id, 0, $PS_EXIT_SYS_ERROR);
+}
+my $outState = -1 * abs($burntoolStateGood);
+
+print ">>$burntoolStateGood<<\n";
+
+# Define list of images to examine.
 my $command = "$regtool -processedimfile";
 $command .= " -class_id $class_id";
@@ -64,142 +99,101 @@
 $command .= " -dbname $dbname" if defined $dbname;
 
-my @command = split /\s+/, $command;
-my ( $stdin, $stdout, $stderr ); # Buffers for running program
-print "Running [$command]...\n" if $verbose;
-if (not run(\@command, \$stdin, \$stdout, \$stderr)) {
-    &my_die("Unable to perform regtool -processedimfile");
-}
-print $stdout . "\n" if $verbose;
-
-my @files;
-my @whole = split /\n/, $stdout;
-my @single = ();
-while ( scalar @whole > 0 ) {
-    my $value = shift @whole;
-    push @single, $value;
-    if ($value =~ /^\s*END\s*$/) {
-	push @single, "\n";
-
-	my $list = parse_md_list( $mdcParser->parse( join( "\n", @single ) ) );
-	&my_die("Unable to parse output from regtool") unless defined $list;
-	push @files, @$list;
-	@single = ();
-    }
-}
-
-# IPP configuration (including nebulous)
-my $ipprc = PS::IPP::Config->new() or my_die("Unable to set up");
-
-$ipprc->redirect_output($logfile) if $logfile;
-
-my $Nfiles = @files;
-print "files: $Nfiles\n";
+( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 
+    run ( command => $command, verbose => $verbose);
+unless ($success) {
+    $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
+    &my_die("Unable to perform regtool: $error_code", $class_id, $dateobs_begin, $dateobs_end, $PS_EXIT_SYS_ERROR);
+}
+
+my $metadata = $mdcParser->parse(join "", @$stdout_buf) or
+    &my_die("Unable to parse metadata", $class_id, $dateobs_begin, $dateobs_end, $PS_EXIT_SYS_ERROR);
+
+my $files = parse_md_list($metadata) or
+    &my_die("Unable to parse metadat list", $class_id, $dateobs_begin, $dateobs_end, $PS_EXIT_SYS_ERROR);
 
 my $REALRUN = 1;
-my $RAWTABLES = 1;
-# XXX if we want to avoid using the raw tables in this script, we need to delay deletion of the tempfile until the next pass.
-
-# first pass: mark the db entries to catch failures
-# these will not be identified as burned by chip processing (user_1 > 0.5)
-if (! $skip_burned)  {
-    foreach my $file (@files) {
+
+# Process each file in turn, checking to see if it needs processing, and doing it all in a single pass
+my $processNext = 0;
+my $previousTable = '';
+
+foreach my $file (@$files) {
+    my $exp_id = $file->{exp_id};
+    my $state = $file->{burntool_state};
+
+    my $rawImfile = $file->{uri};
+    my $rawImfileReal = $ipprc->file_resolve($rawImfile, 0);
+    
+    my $outTable  = $file->{uri};
+    $outTable  =~ s/fits$/burn.tbl/;
+    my $outTableReal = $ipprc->file_resolve($outTable, 1);
+    
+    my $process = 0;
+
+    if ($state == 0) {
+	$process = 1;
+    }
+    elsif ($state == -1) {
+	$process = 1;
+    }
+    elsif ($state == -3) {
+	$process = 1;
+    }
+    elsif ($state == -2) {
+	&my_die("Aborting as $rawImfile has modified pixel data!");
+    }
+    elsif ($state == $burntoolStateGood) {
+	$process = 0;
+	$previousTable = "infits=$rawImfileReal";
+    }
+    elsif ($state == -1 * $burntoolStateGood) {
+	$process = 0;
+	$previousTable = "in=$outTableReal";
+    }
+    else {
+	$process = 1;
+    }
+
+    if (($process == 1)||($processNext == 1)) {
+	$processNext = 1;
+	# Set state to processing
+	my $status = vsystem ("$regtool -dbname $dbname -updateprocessedimfile -exp_id $exp_id -class_id $class_id -burntool_state -1", $REALRUN);
+	if ($status) {
+	    &my_die("failed to update imfile");
+	}
+	$file->{burntool_state} = -1;
 	
-	# rerun_from_first treats the first image as already burned (if it is already burned)
-	# the artifact table from the first file is used for the rest of the sequence.
-	if ($rerun_from_first) {
-	    $skip_burned = 1;
-	    $rerun_from_first = 0;
-	    next;
-	}
-	my $exp_id = $file->{exp_id};
-
-	my $status;
-	$status = vsystem ("$regtool -dbname $dbname -updateprocessedimfile -exp_id $exp_id -class_id $class_id -user_1 0.1", 1);
+	my $tempfile = new File::Temp ( TEMPLATE => "$file->{exp_name}.XXXX",
+					DIR => '/tmp/',
+					UNLINK => !$save_temps,
+					SUFFIX => '.fits');
+	my $tempPixels = $tempfile->filename;
+	
+	# Run burntool
+	$status = vsystem ("$funpack -S $rawImfileReal > $tempPixels", $REALRUN);
+	if ($status) {
+	    &my_die("failed on funpack",$exp_id,$class_id);
+	}
+	if ($previousTable ne '') {
+	    $status = vsystem ("$burntool $tempPixels $previousTable out=$outTableReal tableonly=t persist=t", $REALRUN);
+	}
+	else {
+	    $status = vsystem ("$burntool $tempPixels out=$outTableReal tableonly=t persist=t", $REALRUN);
+	}
+	if ($status) {
+	    &my_die("failed on burntool",$exp_id,$class_id);
+	}
+	
+	$status = vsystem ("$regtool -dbname $dbname -updateprocessedimfile -exp_id $exp_id -class_id $class_id -burntool_state $outState", $REALRUN);
 	if ($status) {
 	    &my_die("failed to update imfile");
 	}
-	$file->{user_1} = 0.1;
-    }
-}
-
-my $prevFileOpt = "";
-foreach my $file (@files) {
-    my $exp_id = $file->{exp_id};
-
-    my $rawImfile = $file->{uri};
-    my $rawImfileReal;
-    if ($REALRUN) {
-	$rawImfileReal = $ipprc->file_resolve($rawImfile, 0);
-    } else {
-	($rawImfileReal) = $rawImfile =~ m|^neb:/(.*)|;
-    }
-    print "rawImfile: $rawImfile -> $rawImfileReal\n";
-
-    # mangle name, create tmp file (always a UNIX file)
-    my $basename = `basename $rawImfile`; chomp $basename;
-    my $tempfile = new File::Temp ( TEMPLATE => "$basename.XXXX", 
-				    DIR => '/tmp',
-				    UNLINK => !$save_temps,
-				    SUFFIX => '.fits');
-    my $tmpImfileReal = $tempfile->filename;
-    # print "tmpImfile: $tmpImfile -> $tmpImfileReal\n";
-    
-    # destination for the burntool-applied image file (may be a NEB file)
-    my $outImfile = $rawImfile;
-    $outImfile =~ s/fits$/burn.fits/;
-    my $outImfileReal = $ipprc->file_resolve($outImfile, 1);
-    # print "outImfile: $outImfile -> $outImfileReal\n";
-
-    # burntool now can write the artifacts to the fits file.
-    # destination for the burntool artifacts.  use this if RAWTABLES is set.
-    my $artImfile;
-    my $artImfileReal;
-    if ($RAWTABLES) {
-	$artImfile = $rawImfile;
-	$artImfile =~ s/fits$/burn.tbl/;
-	$artImfileReal = $ipprc->file_resolve($artImfile, 1);
-	# print "artImfile: $artImfile -> $artImfileReal\n";
-    }
-
-    print "$rawImfile : $skip_burned, $file->{user_1}\n";
-
-    if (! ($skip_burned and ($file->{user_1} > 0.5))) {
-	print "running on: $rawImfile\n";
-        # uncompress the image (do we need to check if it is compressed?)
-        my $status = vsystem ("$funpack -S $rawImfileReal > $tmpImfileReal", $REALRUN);
-        if ($status) {
-            &my_die("failed on funpack");
-        }
-
-        if ($RAWTABLES) {
-            $status = vsystem ("$burntool $tmpImfileReal out=$artImfileReal $prevFileOpt persist=t", $REALRUN);
-        } else {
-            $status = vsystem ("$burntool $tmpImfileReal $prevFileOpt persist=t", $REALRUN);
-        }
-        if ($status) {
-            &my_die("failed on burntool");
-        }
-
-        # compress the image (do we need to check if it is compressed?)
-        $status = vsystem ("$fpack -S $tmpImfileReal > $outImfileReal", $REALRUN);
-        if ($status) {
-            &my_die("failed on fpack");
-        }
-
-	# set the user_1 value to a new result value for now
-        $status = vsystem ("$regtool -dbname $dbname -updateprocessedimfile -exp_id $exp_id -class_id $class_id -user_1 2.0", 1);
-        if ($status) {
-            &my_die("failed to update imfile");
-        }
-        print "\n";
-    }
-    # save the artifact file for the next image
-    if ($RAWTABLES) {
-	$prevFileOpt = "in=$artImfileReal";
-    } else {
-	$prevFileOpt = "infits=$artImfileReal";
-    }
-}
-
+
+	$previousTable = "in=$outTableReal";
+
+	print "\n";
+    }
+}
+    
 exit 0;
 
@@ -220,5 +214,9 @@
 sub my_die {
     my $message = shift;
-
+    if ($#_ != -1) {
+	my $exp_id = shift;
+	my $class_id = shift;
+	vsystem("$regtool -dbname $dbname -updateprocessedimfile -exp_id $exp_id -class_id $class_id -burntool_state -3",1);
+    }
     printf STDERR "$message\n";
     exit 1;
