Index: trunk/ippScripts/scripts/ipp_apply_burntool_single.pl
===================================================================
--- trunk/ippScripts/scripts/ipp_apply_burntool_single.pl	(revision 30113)
+++ trunk/ippScripts/scripts/ipp_apply_burntool_single.pl	(revision 30120)
@@ -178,5 +178,5 @@
         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);
+        vsystem("$regtool -dbname $dbname -updateprocessedimfile -exp_id $exp_id -class_id $class_id -burntool_state 0 -set_state pending_burntool",1);
     }
     printf STDERR "$message\n";
Index: trunk/ippScripts/scripts/nightly_science.pl
===================================================================
--- trunk/ippScripts/scripts/nightly_science.pl	(revision 30113)
+++ trunk/ippScripts/scripts/nightly_science.pl	(revision 30120)
@@ -396,5 +396,5 @@
     exit(0);
 }
-exit(10);
+
 if (defined($check_confirm_stacks) || defined($test_mode)) {
     $metadata_out{nsStackState} = 'CONFIRM_STACKING';
@@ -409,5 +409,5 @@
     exit(0);
 }
-
+exit(10);
 if (defined($check_sweetspot) || defined($test_mode) || defined($check_mode)) {
     $metadata_out{nsSSState} = 'CHECKSWEETSPOT';
@@ -1097,4 +1097,6 @@
     my $pretend = shift;
 
+    my $Npotential = 0;
+    my $Nqueued = 0;
     foreach my $target (sort (keys %science_config)) {
 	if ($science_config{$target}{STACKABLE} == 1) {
@@ -1120,5 +1122,7 @@
 		    next;
 		}
+		$Npotential++;
                 if ($Nalready != 0) {
+		    $Nqueued++;
 		    if ($debug == 1) {
 			print STDERR "execute_stacks: Not queueing $target in filter $filter on $date due to already existing stacks.\n";
@@ -1137,4 +1141,5 @@
 		    }
                     stack_queue($date,$target,$filter);
+		    $Nqueued ++;
                 }
 		if (defined($pretend)) {
@@ -1152,4 +1157,9 @@
         }
     }
+    $metadata_out{nsStackPotential} = $Npotential;
+    $metadata_out{nsStackQueued}    = $Nqueued;
+    if (($Npotential == $Nqueued)&&($metadata_out{nsObservingState} eq 'END_OF_NIGHT')) {
+	$metadata_out{nsStackState} = 'FINISHED_STACKS';
+    }	
 }
 
@@ -1231,8 +1241,15 @@
     my ($label,$workdir,$obs_mode,$object,$comment,$tess_id,$dist_group,$data_group,$reduction) = get_tool_parameters($date,$target);
 
-    my $sth = "SELECT diff_id from diffRun JOIN diffInputSkyfile USING(diff_id) where data_group = '$data_group' AND warp1 = $warp_id_1 AND warp2 = $warp_id_2";
+    my $count = 0;
+    
+    my $sth = "SELECT DISTINCT diff_id from diffRun JOIN diffInputSkyfile USING(diff_id) where data_group = '$data_group' AND warp1 = $warp_id_1 AND warp2 = $warp_id_2";
     my $data_ref = $db->selectall_arrayref( $sth );
-
-    return($#{ $data_ref } + 1);
+    $count += $#{ $data_ref } + 1;
+
+    $sth = "SELECT DISTINCT diff_id from diffRun JOIN diffInputSkyfile USING(diff_id) where data_group = '$data_group' AND warp1 = $warp_id_2 AND warp2 = $warp_id_1";
+    $data_ref = $db->selectall_arrayref( $sth );
+    $count += $#{ $data_ref } + 1;
+
+    return($count);
 }
 
@@ -1276,11 +1293,11 @@
 	    foreach my $filter (@filter_list) {
 		my ($NprocChips,$NprocWarps) = pre_diff_queue($date,$observing_state,$target,$filter);
-		if ((!defined($force_diff_count))&&($NprocChips != $NprocWarps)) {
-		    if ($debug == 1) {
-			print STDERR "execute_diffs: Target $target in filter $filter on $date is not fully processed. ($NprocChips $NprocWarps)\n";
-		    }
-                    $metadata_out{nsDiffState} = 'FORCETOWARP';
-                    next;
-                }
+# 		if ((!defined($force_diff_count))&&($NprocChips != $NprocWarps)) {
+# 		    if ($debug == 1) {
+# 			print STDERR "execute_diffs: Target $target in filter $filter on $date is not fully processed. ($NprocChips $NprocWarps)\n";
+# 		    }
+#                     $metadata_out{nsDiffState} = 'FORCETOWARP';
+#                     next;
+#                 }
                 if ($NprocChips == 0) {
 		    if ($debug == 1) {
@@ -1326,28 +1343,65 @@
 
     my $object_ref = $db->selectall_arrayref( $obj_sth );
+
+    my $Npotential = 0;
+    my $Nqueued = 0;
     
     foreach my $object_row (@{ $object_ref }) {
 	my $this_object = shift @{ $object_row };
-	my $input_sth = "select exp_id,warp_id,dateobs from warpRun JOIN fakeRun USING(fake_id) JOIN camRun USING(cam_id) JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id) ";
+	my $input_sth = "select exp_id,warp_id,dateobs,rawExp.comment from warpRun JOIN fakeRun USING(fake_id) JOIN camRun USING(cam_id) JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id) ";
 	$input_sth .= " WHERE warpRun.state = 'full' AND warpRun.label = '$label' AND warpRun.data_group = '$data_group' AND rawExp.filter = '$filter' AND rawExp.object = '$this_object' ";
 	$input_sth .= " ORDER BY dateobs ";
 	
 	my $warps = $db->selectall_arrayref( $input_sth );
+
+	# Each comment should only appear once. Therefore, if we see it more than once, we assume the first is extra.
+	my %comment_hash = ();
+	foreach my $this_warp (@{ $warps }) {
+	    my $this_comment = ${ $this_warp }[3];
+	    my $this_exp_id  = ${ $this_warp }[0];
+	    $comment_hash{$this_comment} = $this_exp_id;
+	}
 	
 	if (($#{ $warps } + 1) % 2 != 0) {
-	    print STDERR "diff_queue: Number of input warps to make diffs is not even for target $target and object $this_object! $#{ $warps }\n";
-	    next;
+	    print STDERR "diff_queue: Number of input warps to make diffs is not even for target $target and object $this_object! $#{ $warps } ";
+	    if ($#{ $warps} + 1 == 1) {
+		print STDERR ": I can do no diffs with only one exposure.\n";
+		next;
+	    }
+	    else {
+		print STDERR ": I should declare an exposure to be faulty.\n";
+		my @keep_warps = ();
+#		print "@{ $warps }\n";
+		foreach my $this_warp (@{ $warps }) {
+		    my $this_comment = ${ $this_warp }[3];
+		    my $this_exp_id  = ${ $this_warp }[0];
+		    if ($comment_hash{$this_comment} == $this_exp_id) {
+			push @keep_warps, $this_warp;
+		    }
+		    else {
+			print STDERR "diff_queue: excluding $this_exp_id for $this_object\n";
+		    }
+		}
+		@{ $warps } = @keep_warps;
+#		print "@{ $warps }\n";
+	    }
 	}
 	
 	while ($#{ $warps } > -1) {
 	    my $input_warp = shift @{ $warps };
+	    my $input_exp_id = ${ $input_warp }[0];
+	    my $input_comment = ${ $input_warp }[3];
+
+	    
 	    my $template_warp = shift @{ $warps };
-	    my $input_exp_id = ${ $input_warp }[0];
+
 	    my $template_exp_id = ${ $template_warp }[0];
 	    
 	    my $input_warp_id = ${ $input_warp }[1];
 	    my $template_warp_id = ${ $template_warp }[1];
-	    
+
+	    $Npotential++;
 	    if (verify_uniqueness_diff($input_warp_id,$template_warp_id,$date,$target) != 0) {
+		$Nqueued++;
 		print STDERR "Diffs already queued for this $date $target $input_exp_id $template_exp_id\n";
 		next;
@@ -1366,4 +1420,5 @@
 		$cmd .= ' -pretend ';
 		print STDERR "diff_queue: $cmd\n";
+		print STDERR " $input_warp_id $template_warp_id\n";
 	    }
 	    
@@ -1378,4 +1433,10 @@
 	}
     }
+    $metadata_out{nsDiffPotential} += $Npotential;
+    $metadata_out{nsDiffQueued}    += $Nqueued;
+    if (($metadata_out{nsDiffPotential} == $metadata_out{nsDiffQueued})&&($metadata_out{nsObservingState} eq 'END_OF_NIGHT')) {
+	$metadata_out{nsDiffState} = 'FINISHED_DIFFS';
+    }	
+
 }
 	    
Index: trunk/ippScripts/scripts/register_imfile.pl
===================================================================
--- trunk/ippScripts/scripts/register_imfile.pl	(revision 30113)
+++ trunk/ippScripts/scripts/register_imfile.pl	(revision 30120)
@@ -54,6 +54,6 @@
 ) or pod2usage( 2 );
 
-my $ipprc = PS::IPP::Config->new() or my_die( "Unable to set up", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
-$ipprc->redirect_output($logfile) or my_die( "Unable to redirect output", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_SYS_ERROR ) if $logfile;
+my $ipprc = PS::IPP::Config->new() or my_die_for_add( "Unable to set up", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR ); # IPP configuration
+$ipprc->redirect_output($logfile) or my_die_for_add( "Unable to redirect output", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_SYS_ERROR ) if $logfile;
 
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
@@ -101,5 +101,5 @@
     print "STDOUT:\n$out1";
     print "STDERR:\n$err1";
-    &my_die("Unable to perform ppStats on exposure id $exp_id: " . $h1->result(), $exp_id, $tmp_exp_name, $tmp_class_id, $uri, ($h1->result() or $PS_EXIT_PROG_ERROR) ) unless $result1;
+    &my_die_for_add("Unable to perform ppStats on exposure id $exp_id: " . $h1->result(), $exp_id, $tmp_exp_name, $tmp_class_id, $uri, ($h1->result() or $PS_EXIT_PROG_ERROR) ) unless $result1;
 
     print "[Running " . join(' ', @command2) . "]\n";
@@ -110,5 +110,5 @@
     print "STDOUT:\n$out2";
     print "STDERR:\n$err2";
-    &my_die("Unable to perform ppStatsFromMetadata on exposure id $exp_id: " . $h2->result(), $exp_id, $tmp_exp_name, $tmp_class_id, $uri, ($h2->result() or $PS_EXIT_PROG_ERROR) ) unless $result2;
+    &my_die_for_add("Unable to perform ppStatsFromMetadata on exposure id $exp_id: " . $h2->result(), $exp_id, $tmp_exp_name, $tmp_class_id, $uri, ($h2->result() or $PS_EXIT_PROG_ERROR) ) unless $result2;
     chomp $out2;
     $cmdflags = $out2;
@@ -162,9 +162,9 @@
 
 # we require at a minimum: -telescope, -inst, -filelevel, -class_id, -exp_type
-if (uc(&value_for_flag ($cmdflags, "NULL", "-telescope")) eq "NULL") { &my_die ("telescope not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
-if (uc(&value_for_flag ($cmdflags, "NULL", "-inst"))      eq "NULL") { &my_die ("inst      not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
-if (uc(&value_for_flag ($cmdflags, "NULL", "-filelevel")) eq "NULL") { &my_die ("filelevel not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
-if (uc(&value_for_flag ($cmdflags, "NULL", "-class_id"))  eq "NULL") { &my_die ("class_id  not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
-if (uc(&value_for_flag ($cmdflags, "NULL", "-exp_type"))  eq "NULL") { &my_die ("exp_type  not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
+if (uc(&value_for_flag ($cmdflags, "NULL", "-telescope")) eq "NULL") { &my_die_for_add ("telescope not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
+if (uc(&value_for_flag ($cmdflags, "NULL", "-inst"))      eq "NULL") { &my_die_for_add ("inst      not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
+if (uc(&value_for_flag ($cmdflags, "NULL", "-filelevel")) eq "NULL") { &my_die_for_add ("filelevel not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
+if (uc(&value_for_flag ($cmdflags, "NULL", "-class_id"))  eq "NULL") { &my_die_for_add ("class_id  not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
+if (uc(&value_for_flag ($cmdflags, "NULL", "-exp_type"))  eq "NULL") { &my_die_for_add ("exp_type  not found", $exp_id, $tmp_exp_name, $tmp_class_id, $uri, $PS_EXIT_CONFIG_ERROR); }
 
 my $command = "$regtool -addprocessedimfile";
@@ -177,5 +177,10 @@
 $command .= " -hostname $host" if defined $host;
 $command .= " -dbname $dbname" if defined $dbname;
-$command .= " -data_state check_burntool";
+if (abs($burntoolState) == $burntoolStateGood) {
+    $command .= " -data_state full";
+}
+else {
+    $command .= " -data_state check_burntool";
+}
 $command .= " $cmdflags";
 
@@ -236,5 +241,5 @@
 # We now have an imfile in the database, check if we can burntool it.  If not, continue on.
 
-{ 
+if (abs($burntoolState) != $burntoolStateGood) { 
     my $mdcParser  = PS::IPP::Metadata::Config->new;
 
@@ -256,6 +261,6 @@
     unless ($success) {
 	$error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR);
-	&my_die("Unable to perform regtool: $error_code", 
-		$class_id, $exp_name, $date, $PS_EXIT_SYS_ERROR);
+	&my_die_for_update("Unable to perform regtool: $error_code", 
+			   $exp_id, $exp_name, $class_id, $PS_EXIT_SYS_ERROR);
     }
 
@@ -270,7 +275,7 @@
 	    
 	    my $list = parse_md_list( $mdcParser->parse( join( "\n", @single ) ) );
-	    &my_die("Unable to parse output from regtool", 
-		    $class_id, $exp_name, $date, $PS_EXIT_SYS_ERROR) unless
-			defined $list;
+	    &my_die_for_update("Unable to parse output from regtool", 
+			       $exp_id, $exp_name, $class_id, $PS_EXIT_SYS_ERROR) unless
+				   defined $list;
 	    push @{ $exposures }, @$list;
 	    @single = ();
@@ -353,5 +358,5 @@
 }
 
-sub my_die
+sub my_die_for_add
 {
     my $msg = shift; # Warning message on die
@@ -384,4 +389,30 @@
     exit $exit_code;
 }
+sub my_die_for_update
+{
+    my $msg = shift; # Warning message on die
+    my $exp_id = shift;
+    my $exp_name = shift;
+    my $class_id = shift;
+    my $uri = shift;
+    my $exit_code = shift;
+
+    # for failed imfiles, we insert UNKNOWN for inst, telescope, class_id
+
+    $exit_code = $PS_EXIT_PROG_ERROR unless defined $exit_code;
+
+    carp($msg);
+    if (defined $exp_id && defined $tmp_class_id and not $no_update) {
+        my $command = "$regtool -updateprocessedimfile";
+        $command .= " -exp_id $exp_id";
+        $command .= " -class_id $class_id";
+        $command .= " -fault $exit_code";
+        $command .= " -hostname $host" if defined $host;
+        $command .= " -dbname $dbname" if defined $dbname;
+        print "Running: $command\n";
+        system($command);
+    }
+    exit $exit_code;
+}
 
 # Pau.
