Index: trunk/pstamp/scripts/detectability_respond.pl
===================================================================
--- trunk/pstamp/scripts/detectability_respond.pl	(revision 27640)
+++ trunk/pstamp/scripts/detectability_respond.pl	(revision 27642)
@@ -9,7 +9,15 @@
 use warnings;
 
+use Sys::Hostname;
+use Carp;
+use File::Basename;
+use File::Copy;
+use IPC::Cmd 0.36 qw( can_run run );
 use Getopt::Long qw( GetOptions );
 use Pod::Usage qw( pod2usage );
-
+use File::Temp qw( tempfile tempdir);
+
+use PS::IPP::PStamp::RequestFile qw( :standard );
+use PS::IPP::PStamp::Job qw( :standard );
 use PS::IPP::Config qw($PS_EXIT_SUCCESS
                        $PS_EXIT_UNKNOWN_ERROR
@@ -23,16 +31,7 @@
                        caturi
                        );
-
-use Sys::Hostname;
-use Carp;
-use File::Basename;
-use File::Copy;
-use PS::IPP::PStamp::RequestFile qw( :standard );
-use PS::IPP::PStamp::Job qw( :standard );
 use Astro::FITS::CFITSIO qw( :constants );
 Astro::FITS::CFITSIO::PerlyUnpacking(1);
 
-use IPC::Cmd 0.36 qw( can_run run );
-
 #
 # Set up
@@ -41,13 +40,11 @@
 
 my $EXTVER = 1.0;
-my ($missing_tools,$request_file,$tmp_dir);
-my ($req_id,$req_name,$product);
-my ($dbname,$need_magic);
-my ($input,$output,$workdir,$verbose,$save_temps);
+my $EXTNAME = 'MOPS_DETECTABILITY_RESPONSE';
+my ($req_id,$req_name,$product,$need_magic,$missing_tools);
+my ($request_file,$output,$dbname,$verbose,$save_temps);
 GetOptions(
     'input=s'          =>     \$request_file,
     'output=s'        =>      \$output,
     'dbname=s'        =>      \$dbname,
-    'workdir=s'       =>      \$workdir,
     'verbose'         =>      \$verbose,
     'save-temps'      =>      \$save_temps,
@@ -61,5 +58,7 @@
 
 my $detect_query_read = can_run('detect_query_read') or (warn "Can't find detect_query_read" and $missing_tools = 1);
-my $psphotForced = can_run('psphotForced') or (warn "Can't find psphotForced" and $missing_tools = 1);
+my $psphotForced      = can_run('psphotForced') or (warn "Can't find psphotForced" and $missing_tools = 1);
+my $dquery_finish     = can_run('dquery_finish.pl') or (warn "Can't find dquery_finish.pl" and $missing_tools = 1);
+my $ppCoord           = can_run('ppCoord') or (warn "Can't find ppCoord" and $missing_tools = 1);
 if ($missing_tools) {
     warn("Can't find required tools.");
@@ -71,9 +70,9 @@
 }
 
-
 my $ipprc = PS::IPP::Config->new();
-$tmp_dir = "/data/${host}.0/tmp/";
-#
-# Parse Input
+#my $tmp_dir = "/data/${host}.0/tmp/";
+
+#
+# Parse input request file using detect_query_read (as it's already written).
 #
 
@@ -84,31 +83,32 @@
     warn("Unable to perform $dqr_command error code: $error_code");
 }
-
-my @column_names = ();
-my %response = ();
-my $section = '';
+my %query = ();
 my $Nrows = 0;
-foreach my $entry (split /\n/, (join "", @$stdout_buf)) {
-    if ($entry =~ /^#/) {
-	@column_names = split /\s+/, $entry;
-	shift(@column_names);  # Dump the hash sign.
-	if ($section eq 'HEADER') {
-	    $section = 'CONTENT';
+{
+    my @column_names = ();
+    my $section = '';
+    foreach my $entry (split /\n/, (join "", @$stdout_buf)) {
+	if ($entry =~ /^#/) {
+	    @column_names = split /\s+/, $entry;
+	    shift(@column_names);  # Dump the hash sign.
+	    if ($section eq 'HEADER') {
+		$section = 'CONTENT';
+	    }
+	    else {
+		$section = 'HEADER';
+	    }
 	}
 	else {
-	    $section = 'HEADER';
-	}
-    }
-    else {
-	# HEADER: 
-	# QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE STAGE
-	# CONTENT:
-	# ROWNUM RA1_DEG DEC1_DEG RA2_DEG DEC2_DEG MAG
-	my @columns = split /\s+/, $entry;
-	for (my $i = 0; $i <= $#columns; $i++) {
-	    $response{$section}{$column_names[$i]}[$Nrows] = $columns[$i];
-	    print "$section $column_names[$i] $Nrows $columns[$i]\n";
-	}
-	$Nrows++;
+	    # HEADER: 
+	    # QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE STAGE
+	    # CONTENT:
+	    # ROWNUM RA1_DEG DEC1_DEG RA2_DEG DEC2_DEG MAG
+	    my @columns = split /\s+/, $entry;
+	    for (my $i = 0; $i <= $#columns; $i++) {
+		$query{$section}{$column_names[$i]}[$Nrows] = $columns[$i];
+#		print "$section $column_names[$i] $Nrows $columns[$i]\n";
+	    }
+	    $Nrows++;
+	}
     }
 }
@@ -119,54 +119,60 @@
 my %image_list_hash;
 for (my $i = 1; $i < $Nrows; $i++) {
-    print "$i $Nrows $response{CONTENT}{RA1_DEG}[$i] $response{CONTENT}{DEC1_DEG}[$i]\n";
-
-    my $image_set_tmp  = find_image_set($response{HEADER}{FPA_ID}[0],$response{HEADER}{STAGE}[0],
-					$response{HEADER}{MJD_OBS}[0],$response{HEADER}{FILTER}[0],
-					$response{CONTENT}{RA1_DEG}[$i],
-					$response{CONTENT}{DEC1_DEG}[$i],
-					$response{CONTENT}{ROWNUM}[$i],$verbose);
-    print "=== $image_set_tmp->{IMAGE}\n    $image_set_tmp->{PSF}\n    $image_set_tmp->{MASK}\n    $image_set_tmp->{WEIGHT}\n    $image_set_tmp->{COORDINATES}\n    $image_set_tmp->{ROWNUM}\n";
+#    print "$i $Nrows $query{CONTENT}{RA1_DEG}[$i] $query{CONTENT}{DEC1_DEG}[$i]\n";
+
+    my $image_set_tmp  = find_image_set($query{HEADER}{FPA_ID}[0],$query{HEADER}{STAGE}[0],
+					$query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],
+					$query{CONTENT}{RA1_DEG}[$i],$query{CONTENT}{DEC1_DEG}[$i],
+					$query{CONTENT}{ROWNUM}[$i],$verbose);
+    print "=== $image_set_tmp->{IMAGE}\n    $image_set_tmp->{PSF}\n    $image_set_tmp->{MASK}\n    $image_set_tmp->{WEIGHT}\n    $image_set_tmp->{SKY_COORDINATES}\n    $image_set_tmp->{ROWNUM}\n";
     # This appends, assuming that if we get an image, we also get the identical psf/mask/weight/etc.
-    $image_list_hash{$image_set_tmp->{IMAGE}}{IMAGE} = $image_set_tmp->{IMAGE};
-    $image_list_hash{$image_set_tmp->{IMAGE}}{PSF} = $image_set_tmp->{PSF};
-    $image_list_hash{$image_set_tmp->{IMAGE}}{MASK} = $image_set_tmp->{MASK};
-    $image_list_hash{$image_set_tmp->{IMAGE}}{WEIGHT} = $image_set_tmp->{WEIGHT};
+    $image_list_hash{$image_set_tmp->{IMAGE}}{IMAGE}    = $image_set_tmp->{IMAGE};
+    $image_list_hash{$image_set_tmp->{IMAGE}}{PSF}      = $image_set_tmp->{PSF};
+    $image_list_hash{$image_set_tmp->{IMAGE}}{MASK}     = $image_set_tmp->{MASK};
+    $image_list_hash{$image_set_tmp->{IMAGE}}{WEIGHT}   = $image_set_tmp->{WEIGHT};
+    $image_list_hash{$image_set_tmp->{IMAGE}}{CATALOG}  = $image_set_tmp->{CATALOG};
     $image_list_hash{$image_set_tmp->{IMAGE}}{CLASS_ID} = $image_set_tmp->{CLASS_ID};
-    $image_list_hash{$image_set_tmp->{IMAGE}}{EXTENSION_BASE} = $image_set_tmp->{EXTENSION_BASE};
-    push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{COORDINATES} }, $image_set_tmp->{COORDINATES};
+    push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{SKY_COORDINATES} }, $image_set_tmp->{SKY_COORDINATES};
     push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{ROWNUM} }, $image_set_tmp->{ROWNUM};
-    $image_list_hash{$image_set_tmp->{IMAGE}}{TARGETS} = 
-	"$tmp_dir/detectability.$response{HEADER}{STAGE}[0].$response{HEADER}{FPA_ID}[0].targets";
-    $image_list_hash{$image_set_tmp->{IMAGE}}{OUTROOT} = 
-	"$tmp_dir/detectability.$response{HEADER}{STAGE}[0].$response{HEADER}{FPA_ID}[0]";
-}
-#exit(2);
+}
 my $i = 0;
-my @image_list;
+
 foreach my $k (keys %image_list_hash) {
-    # write coordinates for photometry to a disk file.  Probably need to do this as a tempfile object.
-    open(T,">$image_list_hash{$k}{TARGETS}") || die "Could not open output TARGET file $image_list_hash{$k}{TARGETS}";
-    for (my $j = 0; $j <= $#{ $image_list_hash{$k}{COORDINATES} }; $j++) {
-	print T "$image_list_hash{$k}{COORDINATES}[$j]\n";
-    }
-    close(T);
-    $image_list[$i] = $image_list_hash{$k};
-    $i++;
-}
-
-#
-# Construct and run psphot
-#
-for (my $i = 0; $i <= $#image_list; $i++) {
-    my $psf_file    = $image_list[$i]->{PSF};
-    my $image_file  = $image_list[$i]->{IMAGE};
-    my $mask_file   = $image_list[$i]->{MASK};
-    my $weight_file = $image_list[$i]->{WEIGHT};
-    my $target_file = $image_list[$i]->{TARGETS};
-    my $out_root    = $image_list[$i]->{OUTROOT};
-    my $psphot_cmd = "$psphotForced -psf $psf_file ";
-    $psphot_cmd .= "-file $image_file -mask $mask_file -variance $weight_file ";
-    $psphot_cmd .= "-srctext $target_file $out_root";
+    # Write coordinates of the requested targets to a file.
+    my ($coordfile,$coordname) = tempfile("/tmp/detect.coords.$i.XXXX", 
+					    UNLINK => !$save_temps);
+    my ($targetfile,$targetname) = tempfile("/tmp/detect.targets.$i.XXXX", 
+					    UNLINK => !$save_temps);
+
+    for (my $j = 0; $j <= $#{ $image_list_hash{$k}{SKY_COORDINATES} }; $j++) {
+	print $coordfile "$image_list_hash{$k}{SKY_COORDINATES}[$j]\n";
+    }
+
+    # Convert the sky coordinates to image coordinates with ppCoord.
+    my $command = "ppCoord -astrom $image_list_hash{$k}{CATALOG} -radec $coordname";
     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
+	run(command => $command, verbose => $verbose);
+    unless ($success) {
+	warn("Unable to perform $command error code: $error_code");
+    }
+    my @response = split /\n/, (join "", @$stdout_buf);
+    foreach my $line (@response) {
+	my ($r_ra,$r_dec,$trash,$r_x,$r_y,$r_chip) = split /\s+/, $line;
+	print $targetfile "$r_x $r_y\n";
+	$image_list_hash{$k}{EXTENSION_BASE} = $r_chip;
+    }
+
+    
+    # Run psphotForced on the target list.
+    my $tmpdir  = tempdir("detect.$i.XXXX", DIR => "/tmp/", CLEANUP => !$save_temps);
+    $image_list_hash{$k}{OUTROOT} = "$tmpdir/detectability.$query{HEADER}{STAGE}[0].$query{HEADER}{FPA_ID}[0]";
+    
+    my $psphot_cmd = "$psphotForced -psf $image_list_hash{$k}{PSF} ";
+    $psphot_cmd .= "-file $image_list_hash{$k}{IMAGE} ";
+    $psphot_cmd .= "-mask $image_list_hash{$k}{MASK} ";
+    $psphot_cmd .= "-variance $image_list_hash{$k}{WEIGHT} ";
+    $psphot_cmd .= "-srctext $targetname $image_list_hash{$k}{OUTROOT}";
+
+    ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
 	run(command => $psphot_cmd, verbose => $verbose);
     unless ($success) {
@@ -178,26 +184,24 @@
 # Convert psphot output to response
 #
-my @response_entries = ();
-
+my @rownums = ();
+my @psphot_Npix = ();
+my @psphot_Qfact= ();
+my @psphot_flux = ();
 foreach my $k (keys %image_list_hash) {
-    my $class_id = $image_list_hash{$k}{CLASS_ID};
-    my $cmf = $image_list_hash{$k}{OUTROOT} . ".${class_id}.cmf";
-    my ($detect_N_col,$detect_F_col,@detectability_data) = read_cmf_file($cmf,$image_list_hash{$k}{EXTENSION_BASE});
-    
-    if ($#detectability_data != $#{ $image_list_hash{$k}{ROWNUM} }) {
-	my_die("Number of measured values does not match number of requested values.");
-    }
-    for (my $i = 0; $i < $#detectability_data; $i++) {
-	push @response_entries, create_response_entry($image_list_hash{$k}{ROWNUM}[$i],
-						      $detect_N_col,$detect_F_col,
-						      $detectability_data[$i]);
-    }
+    my $cmf = "$image_list_hash{$k}{OUTROOT}.$image_list_hash{$k}{CLASS_ID}.cmf";
+    
+    my ($tmp_Npix,$tmp_Qfact,$tmp_flux) = read_cmf_file($cmf,$image_list_hash{$k}{EXTENSION_BASE});
+
+    push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
+    push @psphot_Npix,    @{ $tmp_Npix };
+    push @psphot_Qfact,   @{ $tmp_Qfact };
+    push @psphot_flux,    @{ $tmp_flux };
 }
 
 write_response_file($output,
-		    $response{HEADER}{QUERY_ID}[0],$response{HEADER}{FPA_ID}[0],
-		    $response{HEADER}{MJD_OBS}[0],$response{HEADER}{filter}[0],
-		    $response{HEADER}{obscode}[0],
-		    @response_entries);
+		    $query{HEADER}{QUERY_ID}[0],$query{HEADER}{FPA_ID}[0],
+		    $query{HEADER}{MJD_OBS}[0],$query{HEADER}{filter}[0],
+		    $query{HEADER}{obscode}[0],
+		    \@rownums, \@psphot_Npix, \@psphot_Qfact, \@psphot_flux);
 
 #
@@ -214,4 +218,5 @@
 # Cleanup
 #
+# Since everything is written to temporary files, there should be nothing to cleanup.
 #
 # Utilities
@@ -236,117 +241,108 @@
     my $mjd_max = $mjd + 1;
 
+    # Call the PStamp code to find the images that contain the target on the given MJD in the specified filter.
     my @images = locate_images($ipprc,$dbname,"bycoord",$stage,
 			       undef,undef,undef,$option_mask,$need_magic,
 			       $ra,$dec,$mjd_min,$mjd_max,$filter . ".00000",undef,$verbose);  
-#     my @images = lookup($ipprc,$dbname,$req_type,$img_type,
-# 			$id,$tess_id,$componenent,$need_magic,$dateobs_begin,$dateobs_end,
-# 			$filter,$data_group,$option_mask,$verbose);
-    my @keys_i_care = ('image','mask','psf','exp_name','stage','weight','cmf','smf');
-    foreach my $i (@images) {
-	foreach my $j (@{ $i }) {
-#	    foreach my $k (keys %{ ${ $i }[$j] }) {
-	}
-    }
 
     my %image_info  = ();
-
-    foreach my $i (@images) {
-	foreach my $j (@{ $i }) {
+    foreach my $i (@images) {           # Scan over each result
+	foreach my $j (@{ $i }) {       # Scan over each image in the result
+	    # We only care about an image if it matches the FPA_ID in the request
 	    if ($stage eq 'diff') {
-		#Diffs hold both exposure names, if they are defined (so a WW or WS diff).  
+		# Diffs match if either exposure name is defined and matches the FPA_ID
 		unless ((defined(${ $j }{exp_name_1}) && (${ $j }{exp_name_1} eq $FPA_ID))||
 			(defined(${ $j }{exp_name_2}) && (${ $j }{exp_name_2} eq $FPA_ID))) {
 		    next;
 		}
-		push @keys_i_care, 'exp_name_1','exp_name_2';
 	    }
 	    elsif ($stage eq 'stack') {
-		# Stacks do not store the exposure name information...I'll have to think up something smart here.
-		next;
+		# Stacks hide the exposure name very well, so I'm
+		# choosing the stack_id as the FPA_ID to match. This
+		# probably needs to be approved somehow.
+		if (${ $j }{stage_id} ne $FPA_ID) {
+		    next;
+		}
 	    }
 	    else {
+		# For all the other stages (warp and chip are the ones I've tested), we can simply 
+		# directly match the exposure name to the FPA_ID
 		if (${ $j }{exp_name} ne $FPA_ID) {
 		    next;
 		}
 	    }
-#	    foreach my $k (@keys_i_care) {
- 	    foreach my $k (keys %{ $j }) {
-		print "$i $j $k ${ $j }{$k}\n";
-	    }
-
-	    my $image_name = ${ $j }{image};
-	    $image_info{IMAGE} = $image_name;
-	    $image_info{PSF} = ${ $j }{psf};
-	    $image_info{MASK} = ${ $j }{mask};
+	    # Debug prints of all the components of this image
+#  	    foreach my $k (keys %{ $j }) {
+# 		print "$i $j $k ${ $j }{$k}\n";
+# 	    }
+	    
+	    # This image matches, so we want to save the information into our output structure
+	    $image_info{ROWNUM} = $index;
+	    $image_info{IMAGE}  = ${ $j }{image};
+	    $image_info{PSF}    = ${ $j }{psf};
+	    $image_info{MASK}   = ${ $j }{mask};
 	    $image_info{WEIGHT} = ${ $j }{weight};
+	    $image_info{SKY_COORDINATES} = "$ra $dec";
+	    # To do sky->image coordinate transformations, we need to use the cmf/smf file. If 
+	    # an astrom reference (the camera stage smf file) exists, then use that, as we're dealing with
+	    # with the chip stage. Otherwise, use the stage-dependent cmf (and set the class_id to fpa).
+	    # The EXTENSION_BASE stores the basename of the extension that will be generated by psphotForced.
 	    if (exists(${ $j }{astrom})) {
-		($image_info{COORDINATES},$image_info{EXTENSION_BASE}) = 
-		    calculate_image_coordinates(${ $j }{astrom},$ra,$dec);
+		$image_info{CATALOG} = ${ $j }{astrom};
 		$image_info{CLASS_ID} = ${ $j }{class_id};
+
 	    }
 	    else {
-		($image_info{COORDINATES},$image_info{EXTENSION_BASE}) = 
-		    calculate_image_coordinates(${ $j }{cmf},$ra,$dec);
+		$image_info{CATALOG} = ${ $j }{cmf};
 		$image_info{CLASS_ID} = 'fpa';
-	    }
-	    $image_info{ROWNUM} = $index;
+
+	    }
+
 	}
     }
     return(\%image_info);
 }
+
 # Taken largely from detect_query_read
-sub calculate_image_coordinates {
-    my $cmf = shift;
-    my $ra = shift;
-    my $dec = shift;
-    my $x = $ra;
-    my $y = $dec;
-    my $c = '';
-    
-    my $tempfile = "$tmp_dir/detect.cic.$$";
-    open(TEMP,">$tempfile");
-    print TEMP "$ra $dec\n";
-    close(TEMP);
-    my $command = "ppCoord -astrom $cmf -radec $tempfile";
-    
-    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
-	run(command => $command, verbose => $verbose);
-    unless ($success) {
-	warn("Unable to perform $command error code: $error_code");
-    }
-    print ">>>$command<<<\n";
-    my @response = split /\n/, (join "", @$stdout_buf);
-    foreach my $line (@response) {
-	print ">>$line<<\n";
-	my ($r_ra,$r_dec,$trash,$r_x,$r_y,$r_chip) = split /\s+/, $line;
-	if (($r_ra == $ra)&&($r_dec == $dec)) {
-	    $x = $r_x;
-	    $y = $r_y;
-	    $c = $r_chip;
-	}
-    }
-    unlink($tempfile);
-    return("$x $y",$c);
-}
 sub read_cmf_file {
     my $cmf_file = shift;
     my $class_id = shift;
-    my @outdata = ();
     my $extname = $class_id . ".psf";
 
-    my ($detect_F_col,$detect_N_col,$detect_flux_col);
-    print "RCF: $cmf_file $class_id $extname\n";
+    my @tmp_Npix = ();
+    my @tmp_Qfact = ();
+    my @tmp_flux = ();
+
+    my ($detect_F_col,$detect_N_col,$detect_flux_col,$detect_mag_col) = (-1, -1, -1, -1);
+
+    
     my $status = 0;
     my $inFits = Astro::FITS::CFITSIO::open_file( $cmf_file, READONLY, $status ); # Open CMF
     check_fitsio($status);
-
     $inFits->movnam_hdu(BINARY_TBL, $extname, 0, $status) and check_fitsio($status);
 
+    my $inHeader = $inFits->read_header();
+
+    my $CMFversion = $inHeader->{EXTTYPE};
+    $CMFversion =~ s/\'//g;
+    $CMFversion =~ s/\s+//g;
+
     # This is the only data we actually care about
-    my $column_defs = [
-	{ name => 'PSF_QF',   type => '1E', writetype => TDOUBLE },
-	{ name => 'PSF_NPIX', type => '1J', writetype => TLONG },
-	{ name => 'PSF_INST_MAG', type => '1E', writetype => TDOUBLE },
-	];
+    my $column_defs;
+    if ($CMFversion eq 'PS1_V2') {
+	$column_defs = [
+	    { name => 'PSF_QF',   type => '1E', writetype => TDOUBLE },
+	    { name => 'PSF_NPIX', type => '1J', writetype => TLONG },
+	    { name => 'PSF_INST_MAG', type => '1E', writetype => TDOUBLE },
+	    ];
+    }
+    elsif ($CMFversion eq 'PS1_DV2') {
+	$column_defs = [
+	    { name => 'PSF_QF',   type => '1E', writetype => TDOUBLE },
+	    { name => 'PSF_NPIX', type => '1J', writetype => TLONG },
+	    { name => 'PSF_INST_FLUX', type => '1E', writetype => TDOUBLE },
+	    ];
+    }
+
     my @colNames; 
     my @colTypes;
@@ -364,50 +360,28 @@
 	my ($col_num,$col_type,$col_data);
 	$inFits->get_colnum(0, $col->{name}, $col_num, $status) and check_fitsio($status);
+	if ($status != 0) {
+	    $status = 0;
+	    next;
+	}
 	$inFits->get_coltype($col_num, $col_type, undef, undef, $status) and check_fitsio($status);
 	$inFits->read_col($col_type, $col_num, 1, 1, $numRows, 0, $col_data, undef, $status) and check_fitsio($status);
-	$colData{$col->{name}} = $col_data;
+	
 	if ($col->{name} eq 'PSF_QF') {
-	    $detect_F_col = $col_num;
-	}
-	if ($col->{name} eq 'PSF_NPIX') {
-	    $detect_N_col = $col_num;
-	}
-	if ($col->{name} eq 'PSF_INST_MAG') {
-	    $detect_flux_col = $col_num;
+	    @tmp_Qfact = @{ $col_data };
+	}
+	elsif ($col->{name} eq 'PSF_NPIX') {
+	    @tmp_Npix = @{ $col_data };
+	}
+	elsif ($col->{name} eq 'PSF_INST_MAG') {
+	    @tmp_flux = map { $_ = 10**(-0.4 * $_) } @{ $col_data };
+	}
+	elsif ($col->{name} eq 'PSF_INST_FLUX') {
+	    @tmp_flux = @{ $col_data };
 	}
     }
     $inFits->close_file( $status ) and check_fitsio($status);    
-
-    for (my $i = 0; $i < $numRows; $i++) {
-	for (my $j = 0; $j <= $#colNames; $j++) {
-	    if ($j == $detect_flux_col) {
-		$outdata[$i][$j] = 10**(-0.4 * $colData{$colNames[$j]}->[$i]);
-	    }
-	    else {
-		$outdata[$i][$j] = $colData{$colNames[$j]}->[$i];
-	    }
-	}
-    }
-
-    return($detect_N_col,$detect_F_col,@outdata);
-}
-
-sub create_response_entry {
-    my $rownum = shift;
-    my $detect_N_col = shift;
-    my $detect_F_col = shift;
-
-    my @cmf_data = @_;
-    
-    my $entry;
-    @{ $entry } = ();
-    
-    
-    push @{ $entry }, $rownum;
-    push @{ $entry }, $cmf_data[$detect_N_col];
-    push @{ $entry }, $cmf_data[$detect_F_col];
-    
-    return($entry);
-}
+    return(\@tmp_Npix, \@tmp_Qfact, \@tmp_flux);
+}
+
 # A lot of this pulled verbatim from Bill's detect_response_create file
 sub write_response_file {
@@ -418,7 +392,10 @@
     my $filter = shift;
     my $obscode = shift;
-    my @response_entries = @_;
-#    my ($query_id,$FPA_ID,$MJD_OBS,$filter,$obscode);
+    my $rownum_ref = shift;
+    my $psphot_Npix_ref = shift;
+    my $psphot_Qfact_ref = shift;
+    my $psphot_flux_ref = shift;
     my $status = 0;
+
     # Specification of columns to write
     my $columns = [
@@ -429,4 +406,6 @@
         # detectibility, indicating the fraction of PSF pixels detetable by IPP
         { name => 'DETECT_F', type => 'D',   writetype => TDOUBLE },
+	# flux of the target source
+	{ name => 'TARGET_FLUX', type => 'D', writetype => TDOUBLE },
 	];
     
@@ -451,8 +430,8 @@
     }
 
-    my $numRows = $#response_entries + 1;
+    my $numRows = $#{ $rownum_ref } + 1;
     my $inHeader = { };
 
-    # Hack to force the data to match teh detect_response_create formats
+    # Hack to force the data to match the detect_response_create formats
     $inHeader->{QUERY_ID}->{value} = $query_id;
     $inHeader->{FPA_ID}->{value} = $FPA_ID;
@@ -461,8 +440,13 @@
     $inHeader->{OBSCODE}->{value} = $obscode;
     
-    for (my $i = 0; $i <= $#response_entries; $i++) {
-	push @{$colData{'ROWNUM'}}, $response_entries[$i][0];
-	push @{$colData{'DETECT_N'}}, $response_entries[$i][1];
-	push @{$colData{'DETECT_F'}}, $response_entries[$i][2];
+    # Fill the table columns with the data, making sure the flux is defined
+    for (my $i = 0; $i < $numRows; $i++) {
+	push @{$colData{'ROWNUM'}},      ${ $rownum_ref }[$i];
+	push @{$colData{'DETECT_N'}},    ${ $psphot_Npix_ref }[$i];
+	push @{$colData{'DETECT_F'}},    ${ $psphot_Qfact_ref }[$i];
+	push @{$colData{'TARGET_FLUX'}}, ${ $psphot_flux_ref }[$i];
+	unless (defined(${ $colData{'TARGET_FLUX'}}[-1])) {
+	    $colData{'TARGET_FLUX'}[-1] = 0.0;
+	}
     }
 
@@ -470,5 +454,4 @@
     my $outFits = Astro::FITS::CFITSIO::create_file( $output, $status );
     check_fitsio( $status );
-
     $outFits->create_img( 16, 0, undef, $status );
     check_fitsio( $status );
@@ -498,7 +481,5 @@
 	my $colName = $colNames[$i];# Column name
 	my $writeType = $colWriteType[$i];
-	print "$colName $writeType $i $colData{$colName}[$i] $status $numRows\n";
 	$outFits->write_col( $writeType, $i + 1, 1, 1, $numRows, $colData{$colName}, $status );
-	print "$colName $writeType $i $colData{$colName}[$i] $status $numRows\n";
 	check_fitsio( $status );
     }
