Index: trunk/pstamp/scripts/detect_query_read
===================================================================
--- trunk/pstamp/scripts/detect_query_read	(revision 27788)
+++ trunk/pstamp/scripts/detect_query_read	(revision 28777)
@@ -26,5 +26,5 @@
 my $no_print_header = 0;    # omit the header keywords
 my $no_print_rows   = 0;    # omit the rows
-
+my $version = 0;
 
 my ( $input,			# Name of input text file
@@ -52,57 +52,107 @@
 my $status = 0;
 
-# The required keywords
-my $header = {
-        'QUERY_ID' => { name => 'QUERY_ID', 
-                        writetype => TSTRING, 
-                        comment => 'MOPS Query ID for this batch query',
-                        value => undef
-                      },
-        'FPA_ID'   => { name => 'FPA_ID', 
-                        writetype => TSTRING, 
-                        comment => 'orginal FPA_ID used at ingest',
-                        value => undef
-                      }, 
-        'MJD_OBS'  => { name => 'MJD-OBS', 
-                        writetype => TDOUBLE, 
-                        comment => 'starting time of the exposure, MJD',
-                        value => undef
-                      },
-        'FILTER'   => { name => 'FILTER', 
-                        writetype => TSTRING, 
-                        comment => 'effective filter use for the exposure',
-                        value => undef
-                      },
-        'OBSCODE'  => { name => 'OBSCODE', 
-                        writetype => TSTRING, 
-                        comment => 'site identifier (MPC observatory code)',
-                        value => undef
-                      },
- 	'STAGE'    => { 
-	                name => 'STAGE',
-			writetype => TSTRING,
-			comment => 'processing stage to examine',
-			value => undef
-	              }
-};
-
-# key_array insures that the order that the keywords is printed out is
-# the same as the ICD
-my @key_array = qw( QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE STAGE);
+# Read the input file
+
+my $inFits = Astro::FITS::CFITSIO::open_file( $input, READONLY, $status ); # FITS file handle
+check_fitsio($status);
+
+$inFits->movnam_hdu(BINARY_TBL, EXTNAME, 0, $status) and check_fitsio($status);
+
+my $inHeader = $inFits->read_header(); # Header for input
+
+my $numRows;			# Number of rows in table
+$inFits->get_num_rows($numRows, $status) and check_fitsio($status);
+
+# The keywords found in the header
+# my $header = {
+#         'EXTVER'   => { name => 'EXTVER',
+# 		       writetype => TSTRING,
+# 		       comment => 'Extension version',
+# 		       value => undef
+#                       },
+#         'EXTNAME'  => { name => 'EXTNAME',
+# 		       writetype => TSTRING,
+# 		       comment => 'name of this binary table extension',
+# 	  	       value => undef
+# 		      },
+#         'QUERY_ID' => { name => 'QUERY_ID', 
+#                         writetype => TSTRING, 
+#                         comment => 'MOPS Query ID for this batch query',
+#                         value => undef
+#                       },
+#         'FPA_ID'   => { name => 'FPA_ID', 
+#                         writetype => TSTRING, 
+#                         comment => 'orginal FPA_ID used at ingest',
+#                         value => undef
+#                       }, 
+#         'MJD_OBS'  => { name => 'MJD-OBS', 
+#                         writetype => TDOUBLE, 
+#                         comment => 'starting time of the exposure, MJD',
+#                         value => undef
+#                       },
+#         'FILTER'   => { name => 'FILTER', 
+#                         writetype => TSTRING, 
+#                         comment => 'effective filter use for the exposure',
+#                         value => undef
+#                       },
+#         'OBSCODE'  => { name => 'OBSCODE', 
+#                         writetype => TSTRING, 
+#                         comment => 'site identifier (MPC observatory code)',
+#                         value => undef
+#                       },
+#  	'STAGE'    => { 
+# 	                name => 'STAGE',
+# 			writetype => TSTRING,
+# 			comment => 'processing stage to examine',
+# 			value => undef
+# 	              }
+# };
+
+my $parse_error = 0;
+# Parse the header to determine what we expect to find.
+foreach my $header_key (keys %{ $inHeader }) {
+    $inHeader->{$header_key} =~ s/\s+//g;
+    $inHeader->{$header_key} =~ s/\'//g;
+}
+my ($EXTVER,$headerEXTNAME,$QUERY_ID,$FPA_ID,$MJD_OBS,$FILTER,$OBSCODE,$STAGE) = 
+    ($inHeader->{EXTVER},$inHeader->{EXTNAME},$inHeader->{QUERY_ID},$inHeader->{FPA_ID},
+     $inHeader->{'MJD-OBS'},$inHeader->{FILTER},$inHeader->{OBSCODE},$inHeader->{STAGE});
+unless(defined($EXTVER) && defined($headerEXTNAME) &&
+       (($EXTVER == 1)||($EXTVER == 2)) && 
+       ($headerEXTNAME eq EXTNAME)) {
+    $parse_error = 1;
+}
+unless(($EXTVER == 2)||
+       ((defined($QUERY_ID))&&(defined($FPA_ID))&&(defined($MJD_OBS))&&
+	(defined($FILTER))&&(defined($OBSCODE)))) {
+    $parse_error = 2;
+}
 
 # Specification of columns
 my $column_defs = [ 
         # matching rownum from detectability original request
-        { name => 'ROWNUM',   type => '20A', writetype => TSTRING }, 
+        { name => 'ROWNUM',   type => '20A', writetype => TSTRING, version => 1 }, 
         # coordinate at start of exposure, in degrees
-        { name => 'RA1_DEG',  type => 'D',   writetype => TDOUBLE },
+        { name => 'RA1_DEG',  type => 'D',   writetype => TDOUBLE, version => 1 },
         # coordinate at start of exposure, in degrees
-        { name => 'DEC1_DEG', type => 'D',   writetype => TDOUBLE },
+        { name => 'DEC1_DEG', type => 'D',   writetype => TDOUBLE, version => 1 },
         # coordinate at end of exposure, in degrees
-        { name => 'RA2_DEG',  type => 'D',   writetype => TDOUBLE },
+        { name => 'RA2_DEG',  type => 'D',   writetype => TDOUBLE, version => 1 },
         # coordinate at end of exposure, in degrees
-        { name => 'DEC2_DEG', type => 'D',   writetype => TDOUBLE },
+        { name => 'DEC2_DEG', type => 'D',   writetype => TDOUBLE, version => 1 },
         # apparent magnitude
-        { name => 'MAG',      type => 'D',   writetype => TDOUBLE },
+        { name => 'MAG',      type => 'D',   writetype => TDOUBLE, version => 1 },
+    # v2 query_id: MOPS query ID for this batch query
+    { name => 'QUERY_ID', type => '20A', writetype => TSTRING, version => 2, default => $QUERY_ID },
+    # v2 fpa_id: original FPA_ID used at ingest
+    { name => 'FPA_ID', type => '20A', writetype => TSTRING, version => 2, default => $FPA_ID },
+    # v2 mjd obs: starting time of the exposure, MJD
+    { name => 'MJD-OBS', type => 'D', writetype => TDOUBLE, version => 2, default => $MJD_OBS },
+    # v2 filter: effective filter used for the exposure as a string, allowed values of g, r, i, z, y, B, V, w
+    { name => 'FILTER', type => '3A', writetype => TSTRING, version => 2, default => $FILTER },
+    # v2 obscode: site identifier (MPC observatory code)
+    { name => 'OBSCODE', type => '3A', writetype => TSTRING, version => 2, default => $OBSCODE },
+    # v2 stage: stage name to perform query on, allowed values of 'chip', 'warp', 'stack', and 'diff'
+    { name => 'STAGE', type => '20A', writetype => TSTRING, version => 2, default => $STAGE },
 ];
 
@@ -118,19 +168,11 @@
 }
 
-# Read the input file
-
-my $inFits = Astro::FITS::CFITSIO::open_file( $input, READONLY, $status ); # FITS file handle
-check_fitsio($status);
-
-$inFits->movnam_hdu(BINARY_TBL, EXTNAME, 0, $status) and check_fitsio($status);
-
-my $inHeader = $inFits->read_header(); # Header for input
-
-my $numRows;			# Number of rows in table
-$inFits->get_num_rows($numRows, $status) and check_fitsio($status);
-
 foreach my $col (@$column_defs) {
     my ($col_num, $col_type, $col_data);
 
+    if ($col->{version} > $EXTVER) {
+	@{ $colData{$col->{name}} } = map { $col->{default} } (0 .. $numRows);
+	next;
+    }
     $inFits->get_colnum(0, $col->{name}, $col_num, $status) and check_fitsio($status);
     $inFits->get_coltype($col_num, $col_type, undef, undef, $status) and check_fitsio($status);
@@ -138,50 +180,42 @@
                                                                     and check_fitsio($status);
     $colData{$col->{name}} = $col_data;
-}
-
-# Now produce the output
-
-if (!$no_print_header) {
-    my $label;
-    my $data;
-    # I don't do this because I want the keys to be printed in a particular order
-    #foreach my $key (keys %$header) {
-    foreach my $key (@key_array) {
-        my $name = $header->{$key}->{name};
-        my $value = $inHeader->{$name};
-	if (($key eq 'STAGE')&& !(defined($value))) {
-	    $value = 'DIFF';
-	}
-        # get rid of quotes and whitespace
-        $value =~ s/\'//g;
-        if (defined $value) {
-            #print "$key\t\t\t$value\n";
-            $label .= sprintf "%-12s ", $key;
-            $data  .= sprintf "%-12s ", $value;
-        } else {
-            die "keyword $key not found in $input\n";
-        }
-    }
-    print "# " . $label . "\n" unless $no_print_label;
-    print $data  . "\n";
-}
-
-if (!$no_print_rows) {
-    if (!$no_print_label) {
-        print "# ";
-        foreach my $col (@$column_defs) {
-            printf "%-12s ", $col->{name};
-        }
-        print "\n";
-    }
-
-    for (my $i = 0; $i < $numRows; $i++) {
-        foreach my $col (@$column_defs) {
-            printf "%-12s ", $colData{$col->{name}}->[$i];
+    if ($col->{name} eq 'MJD-OBS') {
+	print @{ $col_data } . "\n";
+    }
+}
+
+# Verify uniqueness of important columns:
+my @unique_fields = ('QUERY_ID','OBSCODE','STAGE');
+foreach my $colName (@unique_fields) {
+    my %counter = ();
+    foreach my $row (@{ $colData{$colName} }) {
+	$counter{$row} = 1;
+    }
+    if (scalar(keys(%counter)) != 1) {
+	$parse_error = 3;
+    }
+}
+if ($parse_error) {
+    die "Unable to parse detectability query: $parse_error " . &error_message($parse_error) . "\n";;
+}
+
+# # Now produce the output
+
+
+if (!$no_print_label) {
+    print "# ";
+    foreach my $col (@$column_defs) {
+	printf "%-12s ", $col->{name};
+    }
+    print "\n";
+}
+
+for (my $i = 0; $i < $numRows; $i++) {
+    foreach my $col (@$column_defs) {
+	printf "%-12s ", $colData{$col->{name}}->[$i];
         #foreach my $aref (@col_arrays) {
-            #printf "%-12s ", $aref->[$i];
-        }
-        print "\n";
-    }
+	#printf "%-12s ", $aref->[$i];
+    }
+    print "\n";
 }
 
@@ -202,3 +236,21 @@
 }
 
+sub error_message {
+    my $error = shift;
+    if ($error == 1) {
+	return("Unknown EXTVER/EXTNAME");
+    }
+    if ($error == 2) {
+	return("Required header field not found");
+    }
+    if ($error == 3) {
+	return("Unique column not uniquely specified");
+    }
+    else {
+	return("Unknown fault.");
+    }
+}
+
+
+
 __END__
