IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 33325


Ignore:
Timestamp:
Feb 21, 2012, 4:14:00 PM (14 years ago)
Author:
bills
Message:

split up detectability queries into multiple jobs so that they can be processed in parallel

Location:
tags/ipp-20111222/pstamp
Files:
7 edited
1 copied

Legend:

Unmodified
Added
Removed
  • tags/ipp-20111222/pstamp

  • tags/ipp-20111222/pstamp/scripts/Makefile.am

    r30469 r33325  
    2929        detect_query_create \
    3030        detect_response_create \
     31        dquery_job_run.pl \
    3132        dquery_finish.pl \
    3233        dqueryparse.pl \
  • tags/ipp-20111222/pstamp/scripts/detect_query_read

    r29157 r33325  
    222222    if (($colData{FPA_ID}[$i] eq "Not_Set")&&(($colData{'FILTER'}[$i] ne "Not_Set")&&
    223223                                              ($colData{'MJD-OBS'}[$i] ne "Not_Set"))) {
    224         my $dateobs_begin = mjd_to_dateobs($colData{'MJD-OBS'}[$i]);
    225         my $dateobs_end = mjd_to_dateobs($colData{'MJD-OBS'}[$i] + 1);
     224        my $mjd_obs = int $colData{'MJD-OBS'}[$i];
     225        my $dateobs_begin = mjd_to_dateobs($mjd_obs);
     226        my $dateobs_end = mjd_to_dateobs($mjd_obs + 1);
    226227        my $ra = $colData{'RA1_DEG'}[$i];
    227228        my $dec = $colData{'DEC1_DEG'}[$i];
     
    229230        my $cmd;
    230231        if ($colData{STAGE}[$i] eq 'SSdiff') {
    231             $cmd = "$difftool -listrun -dbname $dbname -filter $filter ";
    232             $cmd .= " -dateobs_begin $dateobs_begin -dateobs_end $dateobs_end ";
    233             $cmd .= " -ra $ra -decl $dec -radius 1.5 -limit 1 -diff_mode 4";
     232            # Assumption: All Stack Stack diffs are for a medium deep field
     233            # go find which one the coordinates are in
     234            # XXX: If we don't find one we'll just get the first SSdiff
     235            # in the filter on the day in question
     236            my $field = find_md_field($ra, $dec, 1.6);
     237            $cmd = "$difftool -listssrun -dbname $dbname -filter $filter ";
     238            $cmd .= " -mjd_obs_begin $mjd_obs -mjd_obs_end " . (1 + $mjd_obs);
     239            $cmd .= " -limit 1";
     240            $cmd .= " -tess_id $field%" if $field;
    234241        }
    235242        elsif ($colData{STAGE}[$i] eq 'WSdiff') {
     
    366373
    367374
     375# Given an RA and  DEC return the MD field that contains it if any.
     376# This is much faster than actuallly examining the tessellation
     377# using dvoImagesAtCoords
     378
     379sub find_md_field {
     380    my $ra_deg = shift;
     381    my $dec_deg = shift;
     382    my $radius_deg = shift;
     383
     384    my @MD     = qw(MD01  MD02    MD03     MD04      MD05    MD06      MD07    MD08    MD09     MD10);
     385    my @MD_RA  = (35.875, 53.10, 130.592, 150.000, 161.917, 185.000, 213.454, 242.787, 333.98, 352.312);
     386    my @MD_DEC = (-4.25,  -27.8,   44.317,   2.20,   58.083,  47.117,  53.243, 54.95,    0.283, -0.433);
     387    my $PS_DEG_RAD = 0.017453292519943;
     388
     389    my $ra     = $ra_deg * $PS_DEG_RAD;
     390    my $dec    = $dec_deg * $PS_DEG_RAD;
     391    my $radius = $radius_deg * $PS_DEG_RAD;
     392
     393    for (my $i = 0; $i < scalar @MD; $i++) {
     394       
     395        my $dist = acos((cos($PS_DEG_RAD * $MD_DEC[$i]) * cos($dec) * cos($PS_DEG_RAD * $MD_RA[$i] - $ra)) +(sin($PS_DEG_RAD * $MD_DEC[$i]) * sin($dec)));
     396
     397        if ($dist < $radius) {
     398            return $MD[$i];
     399        }
     400    }
     401    print STDERR "failed to find MD field containing $ra_deg $dec_deg\n";
     402
     403    return undef;
     404}
     405
     406
    368407__END__
  • tags/ipp-20111222/pstamp/scripts/detectability_respond.pl

    r33251 r33325  
    103103} # End reading wisdom.
    104104else {
    105 #
    106 # Parse input request file using detect_query_read (as it's already written).
    107 #
     105    #
     106    # Parse input request file using detect_query_read (as it's already written).
     107    #
    108108    my $dqr_command = "$detect_query_read --dbname $imagedb --input $request_file";
    109109    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     
    118118    {
    119119        my @column_names = ();
     120        # split output into lines skip until the line which lists the column names is found
     121        # Parse subsequent lines
    120122        foreach my $entry (split /\n/, (join "", @$stdout_buf)) {
    121123            if ($entry =~ /^#/) {
     
    123125                shift(@column_names);  # Dump the hash sign.
    124126            }
    125             else {
     127            elsif (scalar @column_names) {
    126128                # ROWNUM RA1_DEG DEC1_DEG RA2_DEG DEC2_DEG MAG QUERY_ID FPA_ID MJD-OBS FILTER OBSCODE STAGE
    127129                my %row_data;
    128130                @row_data{@column_names} = (split /\s+/, $entry);
    129131                for (my $i = 0; $i <= $#column_names; $i++) {
    130                 push @{ $query{$row_data{"FPA_ID"}}{$column_names[$i]} }, $row_data{$column_names[$i]};
    131                 $Nrows = scalar(keys(%query));
    132 #               print "$row_data{'FPA_ID'} $Nrows $i $column_names[$i] $row_data{$column_names[$i]}\n";
    133             }
    134             }
    135         }
    136     }
    137 #
    138 # Identify target images.  This should properly collate targets on a single imfile.
    139 #
     132                    push @{ $query{$row_data{"FPA_ID"}}{$column_names[$i]} }, $row_data{$column_names[$i]};
     133                    $Nrows = scalar(keys(%query));
     134                    # print "$row_data{'FPA_ID'} $Nrows $i $column_names[$i] $row_data{$column_names[$i]}\n";
     135                }
     136            }
     137        }
     138    }
     139    #
     140    # Identify target images.  This should properly collate targets on a single imfile.
     141    #
    140142    foreach my $fpa_id (keys %query) {
    141143        my %temp_hash;
     
    207209        }
    208210        elsif ($fpa_id eq 'Not_Set') {
     211            # no matching file was found skip
    209212            next;
    210213        }
     
    222225            $need_magic = 0;
    223226        }
    224         my $mjd_min = $mjd;
     227        my $mjd_min = int $mjd;
    225228        my $mjd_max = $mjd + 1;
    226229       
     
    239242       
    240243        foreach my $this_image_ref (@{ $pstamp_images_ref }) {
    241             foreach my $key (sort (keys %{ $this_image_ref } )) {
    242                 my $value = ${ $this_image_ref }{$key};
    243                 if ($key eq 'row_index') {
    244                     $value = join ' ', @{ $this_image_ref->{$key} };
    245                 }
    246 
    247 #               print "$this_image_ref $key $value\n";
    248                 foreach my $valid_index (@{ $this_image_ref->{row_index} }) {
    249                     $query{$fpa_id}{IMAGE}[$valid_index] = $this_image_ref->{image};
    250                     $query{$fpa_id}{MASK}[$valid_index] = $this_image_ref->{mask};
    251                     $query{$fpa_id}{WEIGHT}[$valid_index] = $this_image_ref->{weight};
    252                     $query{$fpa_id}{PSF}[$valid_index] = $this_image_ref->{psf};
    253                     $query{$fpa_id}{STAGE_ID}[$valid_index] = $this_image_ref->{stage_id};
    254                     $query{$fpa_id}{IMAGE_DB}[$valid_index] = $this_image_ref->{imagedb};
    255                     $query{$fpa_id}{NEED_MAGIC}[$valid_index] = $need_magic;
    256                     $query{$fpa_id}{BAD_COMPONENT}[$valid_index] = 0;
    257                    
    258                     if (exists($this_image_ref->{astrom})) {
    259                         $query{$fpa_id}{CATALOG}[$valid_index] = $this_image_ref->{astrom};
    260                     }
    261                     else {
    262                         $query{$fpa_id}{CATALOG}[$valid_index] = $this_image_ref->{cmf};
    263                     }
    264                     if (exists($this_image_ref->{class_id})) {
    265                         $query{$fpa_id}{COMPONENT_ID}[$valid_index] = $this_image_ref->{class_id};
    266                         $query{$fpa_id}{CLASS_ID}[$valid_index] = $this_image_ref->{class_id};
    267                        
    268                     }
    269                     else {
    270                         $query{$fpa_id}{COMPONENT_ID}[$valid_index] = $this_image_ref->{skycell_id};
    271                         $query{$fpa_id}{CLASS_ID}[$valid_index] = 'fpa';
    272                     }
    273                    
    274                     $query{$fpa_id}{STATE}[$valid_index] = $this_image_ref->{state};
    275                     if (exists($this_image_ref->{data_state})) {
    276                         $query{$fpa_id}{DATA_STATE}[$valid_index] = $this_image_ref->{data_state};
    277                     }
    278                     else {
    279                         $query{$fpa_id}{DATA_STATE}[$valid_index] = $this_image_ref->{state};
    280                     }
    281                     $query{$fpa_id}{FAULT}[$valid_index] = 0;
     244
     245            if (0) {
     246                foreach my $key (sort (keys %{ $this_image_ref } )) {
     247                    my $value = ${ $this_image_ref }{$key};
     248                    if ($key eq 'row_index') {
     249                        $value = join ' ', @{ $this_image_ref->{$key} };
     250                    }
     251                    print "$this_image_ref $key $value\n";
     252                }
     253            }
     254
     255
     256            foreach my $valid_index (@{ $this_image_ref->{row_index} }) {
     257                $query{$fpa_id}{IMAGE}[$valid_index] = $this_image_ref->{image};
     258                $query{$fpa_id}{MASK}[$valid_index] = $this_image_ref->{mask};
     259                $query{$fpa_id}{WEIGHT}[$valid_index] = $this_image_ref->{weight};
     260                $query{$fpa_id}{PSF}[$valid_index] = $this_image_ref->{psf};
     261                $query{$fpa_id}{STAGE_ID}[$valid_index] = $this_image_ref->{stage_id};
     262                $query{$fpa_id}{IMAGE_DB}[$valid_index] = $this_image_ref->{imagedb};
     263                $query{$fpa_id}{NEED_MAGIC}[$valid_index] = $need_magic;
     264                $query{$fpa_id}{BAD_COMPONENT}[$valid_index] = 0;
     265               
     266                if (exists($this_image_ref->{astrom})) {
     267                    $query{$fpa_id}{CATALOG}[$valid_index] = $this_image_ref->{astrom};
     268                }
     269                else {
     270                    $query{$fpa_id}{CATALOG}[$valid_index] = $this_image_ref->{cmf};
     271                }
     272                if (exists($this_image_ref->{class_id})) {
     273                    $query{$fpa_id}{COMPONENT_ID}[$valid_index] = $this_image_ref->{class_id};
     274                    $query{$fpa_id}{CLASS_ID}[$valid_index] = $this_image_ref->{class_id};
     275                   
     276                }
     277                else {
     278                    $query{$fpa_id}{COMPONENT_ID}[$valid_index] = $this_image_ref->{skycell_id};
     279                    $query{$fpa_id}{CLASS_ID}[$valid_index] = 'fpa';
     280                }
     281               
     282                $query{$fpa_id}{STATE}[$valid_index] = $this_image_ref->{state};
     283                if (exists($this_image_ref->{data_state})) {
     284                    $query{$fpa_id}{DATA_STATE}[$valid_index] = $this_image_ref->{data_state};
     285                }
     286                else {
     287                    $query{$fpa_id}{DATA_STATE}[$valid_index] = $this_image_ref->{state};
     288                }
     289                $query{$fpa_id}{FAULT}[$valid_index] = 0;
    282290                    $query{$fpa_id}{MAGICKED}[$valid_index] = $this_image_ref->{magicked};
    283                     if ($stage eq 'chip') {
    284                         $query{$fpa_id}{BURNTOOL_STATE}[$valid_index] = $this_image_ref->{burntool_state};
    285                     }
    286                    
    287                     # Determine if the data exists.
    288                     if (($query{$fpa_id}{STATE}[$valid_index] eq 'goto_purged') or
    289                         ($query{$fpa_id}{DATA_STATE}[$valid_index] eq 'purged') or
    290                         ($query{$fpa_id}{STATE}[$valid_index] eq 'drop') or
    291                         ($query{$fpa_id}{STATE}[$valid_index] eq 'error_cleaned') or
    292                         ($query{$fpa_id}{STATE}[$valid_index] eq 'goto_scrubbed') or
    293                         ($query{$fpa_id}{DATA_STATE}[$valid_index] eq 'scrubbed')) {
    294                        
    295                         # image is gone and it's not coming back
    296                         $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_GONE;
    297                     }
    298                     elsif ($need_magic and ($query{$fpa_id}{MAGICKED}[$valid_index] eq 0)) {
    299                         $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_DESTREAKED;
    300                     }
    301                     elsif (($query{$fpa_id}{DATA_STATE}[$valid_index] ne 'full')) {                   
    302                         $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_AVAILABLE;
    303                        
    304                         # updating stacks isn't implemented
    305                         if (($stage eq 'stack')) {
    306                             $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_IMPLEMENTED;
    307                         }
    308                         # updating old burntool data isn't implemented
    309                         elsif ($stage eq 'chip') {
    310                             if ($query{$fpa_id}{BURNTOOL_STATE}[$valid_index] and
    311                                 (abs($query{$fpa_id}{BURNTOOL_STATE}[$valid_index]) < 14)) {
    312                                 $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_IMPLEMENTED;
     291                if ($stage eq 'chip') {
     292                    $query{$fpa_id}{BURNTOOL_STATE}[$valid_index] = $this_image_ref->{burntool_state};
     293                }
     294               
     295                # Determine if the data exists.
     296                if (($query{$fpa_id}{STATE}[$valid_index] eq 'goto_purged') or
     297                    ($query{$fpa_id}{DATA_STATE}[$valid_index] eq 'purged') or
     298                    ($query{$fpa_id}{STATE}[$valid_index] eq 'drop') or
     299                    ($query{$fpa_id}{STATE}[$valid_index] eq 'error_cleaned') or
     300                    ($query{$fpa_id}{STATE}[$valid_index] eq 'goto_scrubbed') or
     301                    ($query{$fpa_id}{DATA_STATE}[$valid_index] eq 'scrubbed')) {
     302                   
     303                    # image is gone and it's not coming back
     304                    $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_GONE;
     305                }
     306                elsif ($need_magic and ($query{$fpa_id}{MAGICKED}[$valid_index] eq 0)) {
     307                    $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_DESTREAKED;
     308                }
     309                elsif (($query{$fpa_id}{DATA_STATE}[$valid_index] ne 'full')) {               
     310                    $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_AVAILABLE;
     311                   
     312                    # updating stacks isn't implemented
     313                    if (($stage eq 'stack')) {
     314                        $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_IMPLEMENTED;
     315                    }
     316                    # updating old burntool data isn't implemented
     317                    elsif ($stage eq 'chip') {
     318                        if ($query{$fpa_id}{BURNTOOL_STATE}[$valid_index] and
     319                            (abs($query{$fpa_id}{BURNTOOL_STATE}[$valid_index]) < 14)) {
     320                            $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_IMPLEMENTED;
    313321                            }
    314                         }
    315                     } # End determining error faults.
    316                 }
    317             }
    318         }
     322                    }
     323                } # End determining error faults.
     324            }
     325        }
    319326    }
    320327} # End calculating wisdom
     
    322329my %processing_request;
    323330
    324 if (!$job_id) {
    325     open(WISDOM,">$wisdom_file") or my_die("failed to open wisdom file $wisdom_file");
    326     foreach my $fpa_id (keys %query) {
    327         for (my $i = 0; $i <= $#{ $query{$fpa_id}{ROWNUM} }; $i++) {
    328             print WISDOM "$fpa_id\t";
    329             foreach my $key (keys %{ $query{$fpa_id} }) {
    330                 print WISDOM "$key $query{$fpa_id}{$key}[$i]\t";
     331if ($job_id) {
     332    $wisdom_file = "$wisdom_file.$job_id";
     333}
     334open(WISDOM,">$wisdom_file") or my_die("failed to open wisdom file $wisdom_file");
     335foreach my $fpa_id (keys %query) {
     336    for (my $i = 0; $i <= $#{ $query{$fpa_id}{ROWNUM} }; $i++) {
     337        print WISDOM "$fpa_id\t";
     338        foreach my $key (keys %{ $query{$fpa_id} }) {
     339            print WISDOM "$key $query{$fpa_id}{$key}[$i]\t";
     340        }
     341        print WISDOM "\n";
     342        my $data_state = $query{$fpa_id}{DATA_STATE}[$i];
     343        if ($query{$fpa_id}{BAD_COMPONENT}[$i] == 0) {
     344            if ($data_state ne 'full') {
     345               
     346                @{ $update_request{$query{$fpa_id}{IMAGE}[$i]}{$query{$fpa_id}{FAULT}[$i]} } =
     347                    ($query{$fpa_id}{STATE}[$i],$query{$fpa_id}{STAGE}[$i],$query{$fpa_id}{STAGE_ID}[$i],
     348                     $query{$fpa_id}{COMPONENT_ID}[$i],$query{$fpa_id}{NEED_MAGIC}[$i],$query{$fpa_id}{IMAGE_DB}[$i]);
    331349            }
    332             print WISDOM "\n";
    333             my $data_state = $query{$fpa_id}{DATA_STATE}[$i];
    334             if ($query{$fpa_id}{BAD_COMPONENT}[$i] == 0) {
    335                 if ($data_state ne 'full') {
    336                    
    337                     @{ $update_request{$query{$fpa_id}{IMAGE}[$i]}{$query{$fpa_id}{FAULT}[$i]} } =
    338                         ($query{$fpa_id}{STATE}[$i],$query{$fpa_id}{STAGE}[$i],$query{$fpa_id}{STAGE_ID}[$i],
    339                          $query{$fpa_id}{COMPONENT_ID}[$i],$query{$fpa_id}{NEED_MAGIC}[$i],$query{$fpa_id}{IMAGE_DB}[$i]);
    340                 }
    341                 push @{ $processing_request{$fpa_id}{$query{$fpa_id}{IMAGE}[$i]} }, $i;
    342             }
     350            push @{ $processing_request{$fpa_id}{$query{$fpa_id}{IMAGE}[$i]} }, $i;
    343351        }
    344352    }
    345     close(WISDOM);
    346 
     353}
     354close(WISDOM);
     355
     356if (! defined $job_id) {
    347357    # If there is anything that needs to be updated, create the update request list, and then exit the program.
    348358    my $exit_code = 0;
     
    399409        # if (($fault != 0)||($query{$fpa_id}{BAD_COMPONENT}[$index] == 1)) {
    400410        if ($fault = check_component($stage, $stage_id, $component, $imagedb)) {
    401             $query{$fpa_id}{PROC_ERROR}[$index] = $fault;
    402            
    403             $query{$fpa_id}{NPIX}[$index] = 0;
    404             $query{$fpa_id}{QFACTOR}[$index] = 0.0;
    405             $query{$fpa_id}{FLUX}[$index] = 0.0;
    406             $query{$fpa_id}{FLUX_SIG}[$index] = 0.0;
     411            foreach my $i (@{ $processing_request{$fpa_id}{$image} }) {
     412                $query{$fpa_id}{PROC_ERROR}[$i] = $fault;
     413               
     414                $query{$fpa_id}{NPIX}[$i] = 0;
     415                $query{$fpa_id}{QFACTOR}[$i] = 0.0;
     416                $query{$fpa_id}{FLUX}[$i] = 0.0;
     417                $query{$fpa_id}{FLUX_SIG}[$i] = 0.0;
     418            }
    407419
    408420            next;
     
    704716            $inHeader->{FPA_ID}->{value} = $fpa_id;
    705717        }
     718
     719        my @keysa = keys %{$query{$fpa_id}};
     720
     721        print "$fpa_id: @keysa\n";
    706722       
    707723        push @{$colData{'ROWNUM'}}, @{ $query{$fpa_id}{ROWNUM} };
  • tags/ipp-20111222/pstamp/scripts/dquery_finish.pl

    r33174 r33325  
    1313use File::Temp qw( tempfile );
    1414use File::Copy;
     15use Astro::FITS::CFITSIO qw( :constants );
     16Astro::FITS::CFITSIO::PerlyUnpacking(1);
    1517
    1618use PS::IPP::Metadata::Config;
     
    6971    exit 0;
    7072}
    71 if (0) {
    72 my $prod_dir = "$outputDataStoreRoot/$product";
    73 if (! -e $prod_dir ) {
    74     # something must have gone wrong at the parse stage
    75     update_request($req_id, $PS_EXIT_SYS_ERROR, $verbose);
    76     die "product directory does not exist $prod_dir";
    77 }
    78 my $outdir = "$prod_dir/$req_name";
    79 }
     73
    8074if (! -e $outdir ) {
    8175    # something must have gone wrong at the parse stage
     
    9791{
    9892    my $command = "$pstamptool -listjob -req_id $req_id";
     93    $command .= " -jobType detect_query";   # temporary
    9994    $command .= " -dbname $dbname" if $dbname;
    10095    $command .= " -dbserver $dbserver" if $dbserver;
     
    117112}
    118113
    119 # XXX: have the jobs produce the reglist as with postage stamp requests
    120 my ($REGLIST, $reg_list) = tempfile("$outdir/reqlist.XXXX", UNLINK => !$save_temps);
    121 
     114my ($REGLIST, $reg_list) = tempfile("$outdir/reglist.XXXX", UNLINK => !$save_temps);
     115my $response_file = "response.$req_id.fits";
     116my $response_path = "$outdir/$response_file";
     117
     118print $REGLIST "$response_file|||table|\n";
     119
     120my @columns = qw(ROWNUM PROC_ERROR NPIX QFACTOR FLUX FLUX_SIG FPA_ID STAGE STAGE_ID COMPONENT CMFFILE);
     121my %colData;
     122foreach my $col (@columns) {
     123    $colData{$col} = [];
     124}
     125   
     126my $i = 0;
    122127foreach my $job (@jobs) {
    123     next if $job->{parent_id};
    124128    my $job_id = $job->{job_id};
    125     my $response_file = "response.${job_id}.fits";
    126     my $response_path = "$outdir/$response_file";
    127 
    128     if (-e $response_path) {
    129         # the job generated a response file put it into the Data Store
    130         print $REGLIST "$response_file|||table|\n";
    131 
    132         # do the same if we have an error file.  Should the parse data be uploaded as well?
    133         my $err_file = "parse_error.txt";
    134         if (-e "$outdir/$err_file") {
    135             print $REGLIST "$err_file|||text|\n";
    136         }
    137     } else  {
    138         print STDERR "detect_query response file for job $job_id not found\n" if $verbose;
    139         $request_fault = $PS_EXIT_UNKNOWN_ERROR;
    140     }
     129
     130    my $outputBase = $job->{outputBase};
     131    my $results = "${outputBase}results.txt";
     132
     133    read_results($results, \%colData);
     134
     135    my $cmf = $colData{CMFFILE}->[$i];
     136    print $REGLIST "$cmf|||table|\n";
     137
     138    $i++;
    141139}
    142140close $REGLIST;
     141
     142write_response_file($response_path, $req_name, \%colData);
    143143
    144144if (-s $reg_list) {
     
    162162exit 0;
    163163
     164sub read_results {
     165    my $results_file = shift;
     166    my $results = shift;
     167
     168    open IN, "<$results_file" or my_die("failed to open $results_file", $PS_EXIT_UNKNOWN_ERROR);
     169
     170    foreach my $line (<IN>) {
     171        # skip header
     172        next if $line =~ /ROWNUM/;
     173        chomp $line;
     174        my @words = split " ", $line;
     175        my ($rownum, $proc_error, $npix, $qfactor, $flux, $flux_sig, $fpa_id, $stage, $stage_id, $component, $cmf) = @words;
     176        push @{$results->{ROWNUM}}, $rownum;
     177        push @{$results->{PROC_ERROR}}, $proc_error;
     178        push @{$results->{NPIX}}, $npix;
     179        push @{$results->{QFACTOR}}, $qfactor;
     180        push @{$results->{FLUX}}, $flux;
     181        push @{$results->{FLUX_SIG}}, $flux_sig;
     182        push @{$results->{FPA_ID}}, $fpa_id;
     183        push @{$results->{STAGE}}, $stage;
     184        push @{$results->{STAGE_ID}}, $stage_id;
     185        push @{$results->{COMPONENT}}, $component;
     186        push @{$results->{CMFFILE}}, $cmf;
     187    }
     188    # XXX: make sure that the size of each of these arrays is the same
     189}
     190
     191sub write_response_file {
     192    my $output = shift;
     193    my $query_id = shift;
     194    my $results = shift;
     195
     196    my $columns;
     197    my $headers;
     198
     199    my $EXTVER_IS_1 = 0 ; # (scalar(keys(%query)) == 1);
     200#    print "EXTVER: $EXTVER_IS_1\n";
     201    my ($FPA_ID,$MJD_OBS,$filter,$obscode,$status);
     202    if ($EXTVER_IS_1 == 1) {
     203        # Specification of columns to write
     204        $columns = [
     205            # matching rownum from detectability original request
     206            { name => 'ROWNUM',   type => '20A', writetype => TSTRING },
     207            # any errors that occurred during processing
     208            { name => 'ERROR_CODE',   type => 'V', writetype => TULONG },
     209            # number of pixels used in hypothetical PSF for the query detection
     210            { name => 'DETECT_N', type => 'V',   writetype => TULONG },
     211            # detectibility, indicating the fraction of PSF pixels detetable by IPP
     212            { name => 'DETECT_F', type => 'D',   writetype => TDOUBLE },
     213            # flux of the target source
     214            { name => 'TARGET_FLUX', type => 'D', writetype => TDOUBLE },
     215            # error in the flux of the target source
     216            { name => 'TARGET_FLUX_SIG', type => 'D', writetype => TDOUBLE },
     217            ];
     218       
     219        # Header translation table
     220        $headers = {
     221            'QUERY_ID' => { name => 'QUERY_ID', type => TSTRING,
     222                            comment => 'MOPS Query ID for this batch query' },
     223            'FPA_ID' => { name => 'FPA_ID',   type => TSTRING,
     224                          comment => 'original FPA_ID used at ingest' },
     225#           'MJD-OBS' => { name => 'FPA_ID',   type => TSTRING,
     226#                         comment => 'original FPA_ID used at ingest' },
     227#           'FILTER' => { name => 'FPA_ID',   type => TSTRING,
     228#                         comment => 'original FPA_ID used at ingest' },
     229#           'OBSCODE' => { name => 'FPA_ID',   type => TSTRING,
     230#                         comment => 'original FPA_ID used at ingest' },
     231        };
     232    }
     233    else {
     234        # Specification of columns to write
     235        $columns = [
     236            # matching rownum from detectability original request
     237            { name => 'ROWNUM',   type => '20A', writetype => TSTRING},
     238            # any errors that occurred during processing
     239            { name => 'ERROR_CODE',   type => 'V', writetype => TULONG },
     240            # number of pixels used in hypothetical PSF for the query detection
     241            { name => 'DETECT_N', type => 'V',   writetype => TULONG },
     242            # detectibility, indicating the fraction of PSF pixels detetable by IPP
     243            { name => 'DETECT_F', type => 'D',   writetype => TDOUBLE },
     244            # flux of the target source
     245            { name => 'TARGET_FLUX', type => 'D', writetype => TDOUBLE },
     246            # error in the flux of the target source
     247            { name => 'TARGET_FLUX_SIG', type => 'D', writetype => TDOUBLE },
     248            # The FPA That would be in the header if it were to be there.
     249            { name => 'FPA_ID',   type => '20A', writetype => TSTRING },
     250            ];
     251       
     252        # Header translation table
     253        $headers = {
     254            'QUERY_ID' => { name => 'QUERY_ID', type => TSTRING,
     255                            comment => 'MOPS Query ID for this batch query' },
     256        };
     257    }   
     258
     259    # Parse the list of columns
     260    my @colNames;                   # Names of columns
     261    my @colTypes;                   # Types of columns
     262    my %colData;                    # Data for each column
     263    my @colWriteType;                 # type to use to write
     264    foreach my $colSpec ( @$columns) {
     265        push @colNames, $colSpec->{name};
     266        push @colTypes, $colSpec->{type};
     267        push @colWriteType, $colSpec->{writetype};
     268        $colData{$colSpec->{name}} = [];
     269    }
     270
     271    my $inHeader = { };
     272
     273    # Hack to force the data to match the detect_response_create formats
     274
     275    $inHeader->{QUERY_ID}->{value} = $query_id;
     276    if ($EXTVER_IS_1 == 1) {
     277        my $fpa_id = $results->{FPA_ID}->[0];
     278        $inHeader->{FPA_ID}->{value} = $fpa_id;
     279    }
     280   
     281    # Fill the table columns with the data, making sure the flux is defined
     282
     283    @{$colData{'ROWNUM'}} = @{ $results->{ROWNUM} };
     284    @{$colData{'ERROR_CODE'}} = @{ $results->{PROC_ERROR} };
     285    @{$colData{'DETECT_N'}} = @{ $results->{NPIX} };
     286    @{$colData{'DETECT_F'}} = @{ $results->{QFACTOR} };
     287    @{$colData{'TARGET_FLUX'}} = @{ $results->{FLUX} };
     288    @{$colData{'TARGET_FLUX_SIG'}} = @{ $results->{FLUX_SIG} };
     289    @{$colData{'FPA_ID'}} = @{ $results->{FPA_ID} };
     290
     291    my $numRows = 0;
     292    # Back to detect_response_create:
     293    $status = 0;
     294#    print "$output\n";
     295    if (-e $output) {
     296        unlink $output or die "failed to unlink existing response file $output\n";
     297    }
     298    my $outFits = Astro::FITS::CFITSIO::create_file( $output, $status );
     299    check_fitsio( $status );
     300    $outFits->create_img( 16, 0, undef, $status );
     301    check_fitsio( $status );
     302    my $EXTNAME = 'MOPS_DETECTABILITY_RESPONSE';
     303   
     304    $outFits->create_tbl( BINARY_TBL(), $numRows, scalar @colNames, \@colNames, \@colTypes, undef, $EXTNAME, $status);
     305    check_fitsio( $status );
     306
     307    # TODO: get the extension version number from somewhere common
     308    $outFits->write_key( TINT, 'EXTVER', 2, 'Version of this Extension', $status );
     309    check_fitsio( $status );
     310
     311    # Write the Extension keywords
     312    foreach my $keyword ( keys %$headers ) {
     313        my $value = $inHeader->{$keyword}->{value}; # Header keyword value
     314        unless (defined $value) {
     315            print "Can't find header keyword $keyword\n";
     316            next;
     317        }
     318        $value =~ s/\'//g;
     319        my $name    = $headers->{$keyword}->{name}; # New name
     320        my $type    = $headers->{$keyword}->{type}; # Type
     321        my $comment = $headers->{$keyword}->{comment}; # Comment
     322        $outFits->write_key( $type, $name, $value, $comment, $status );
     323        check_fitsio( $status );
     324    }
     325
     326    for (my $i = 0; $i < scalar @colNames; $i++) {
     327        my $colName = $colNames[$i];# Column name
     328        my $writeType = $colWriteType[$i];
     329        my $numRows = scalar(@{$colData{$colName}});
     330        unless(defined($writeType)) {
     331            print "write type undefined for $colName\n";
     332        }
     333        unless(defined($numRows)) {
     334            print "num Rows undefined for $colName\n";
     335        }
     336        unless(defined($status)) {
     337            print "status undefined for $colName\n";
     338        }
     339        unless(defined($colData{$colName})) {
     340            print "col data undefined for $colName\n";
     341        }
     342        unless(defined($colName)) {
     343            print "column name undefined for $i\n";
     344        }
     345        print STDERR "$writeType $i $numRows $colName $status @{ $colData{$colName} }\n";
     346        $outFits->write_col( $writeType, $i + 1, 1, 1, $numRows, $colData{$colName}, $status );
     347        print STDERR "$writeType $i $numRows $colName $status\n";
     348        check_fitsio( $status );
     349    }
     350    $outFits->close_file( $status );
     351    return($status);
     352}
     353
     354# From Astro::FITS::CFITSIO demo
     355sub check_fitsio
     356{
     357    my $status = shift;         # Status of FITSIO calls
     358
     359    if ($status != 0) {
     360        my $msg;                # Message to output
     361        Astro::FITS::CFITSIO::fits_get_errstatus( $status , $msg );
     362        carp("CFITSIO error: $status => $msg");
     363        die "CFITSIO error: $msg\n";
     364    }
     365}
    164366sub update_request {
    165367    my $req_id = shift;
     
    181383    }
    182384}
     385
     386sub my_die {
     387    my $msg = shift;
     388    my $fault = shift;
     389
     390    print STDERR $msg;
     391
     392    update_request($req_id, $fault);
     393
     394    exit $fault;
     395}
  • tags/ipp-20111222/pstamp/scripts/dqueryparse.pl

    r33174 r33325  
    1 #!/usr/bin/env perl
    2 #
    3 # parse a MOPS_DETCTABILITY_QUERY table and create a results file
     1#! /usr/bin/env perl
     2#
     3#
     4# Create a response to a MOPS_DETECTABILITY_QUERY
     5#
    46#
    57
    68use strict;
    79use warnings;
     10
     11use Sys::Hostname;
    812use Carp;
     13use File::Basename;
     14use File::Copy;
     15use IPC::Cmd 0.36 qw( can_run run );
    916use Getopt::Long qw( GetOptions );
    1017use Pod::Usage qw( pod2usage );
    11 use IPC::Cmd 0.36 qw( can_run run );
     18use File::Temp qw( tempfile tempdir);
    1219
    1320use PS::IPP::PStamp::RequestFile qw( :standard );
    1421use PS::IPP::PStamp::Job qw( :standard );
    15 use PS::IPP::Config qw($PS_EXIT_SUCCESS
    16                        $PS_EXIT_UNKNOWN_ERROR
    17                        $PS_EXIT_SYS_ERROR
    18                        $PS_EXIT_CONFIG_ERROR
    19                        $PS_EXIT_PROG_ERROR
    20                        $PS_EXIT_DATA_ERROR
    21                        $PS_EXIT_TIMEOUT_ERROR
    22                        metadataLookupStr
    23                        metadataLookupBool
    24                        caturi
    25                        );
    26 
    27 my ($no_update, $imagedb, $label);
    28 my ($req_file, $req_id, $outdir, $product, $mode, $dbname, $dbserver, $verbose, $save_temps);
    29 my ($job_id,$rownum); # stuff from the post-update world
    30 #
    31 # parse args
    32 #
    33 
     22use PS::IPP::Config qw( :standard );
     23use PS::IPP::Metadata::List qw( parse_md_list );
     24
     25# use Astro::FITS::CFITSIO qw( :constants );
     26# Astro::FITS::CFITSIO::PerlyUnpacking(1);
     27
     28my $host = hostname();
     29
     30my $mode = 'queue_job';
     31
     32my ($req_id, $product, $need_magic, $missing_tools, $project, $label);
     33my ($request_file, $outdir, $dbname, $dbserver, $verbose, $save_temps, $no_update);
    3434GetOptions(
    35         'file=s'          =>      \$req_file,
    36         'req_id=s'        =>      \$req_id,
    37         'job_id=s'        =>      \$job_id,
    38         'rownum=s'        =>      \$rownum,
    39         'outdir=s'       =>      \$outdir,
    40         'label=s'         =>      \$label,
    41         'product=s'       =>      \$product,
    42         'mode=s'          =>      \$mode,
    43         'dbname=s'        =>      \$dbname,
    44         'dbserver=s'      =>      \$dbserver,
    45         'verbose'         =>      \$verbose,
    46         'save-temps'      =>      \$save_temps,
    47 ) or pod2usage(2);
    48 
    49 die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "queue_job");
    50 die "--file or --job_id is required" if !$req_file;
    51 
    52 if ($mode ne "list_uri") {
    53     die "req_id is required" if !$req_id;
    54     die "outdir is required" if !$outdir;
    55     die "product is required" if !$product;
    56 }
    57 my $missing_tools;
    58 my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools =1);
    59 my $detectresponse = can_run('detectability_respond.pl') or
    60     (warn "Can't find detectability_respond.pl" and $missing_tools = 1);
    61 my $fields = can_run('fields') or (warn "Can't find fields" and $missing_tools =1);
    62 
     35    'file=s'          =>      \$request_file,
     36    'req_id=s'        =>      \$req_id,
     37    'outdir=s'        =>      \$outdir,
     38    'label=s'         =>      \$label,
     39    'product=s'       =>      \$product,
     40    'mode=s'          =>      \$mode,
     41    'dbname=s'        =>      \$dbname,
     42    'dbserver=s'      =>      \$dbserver,
     43    'verbose'         =>      \$verbose,
     44    'save-temps'      =>      \$save_temps,
     45    'no-update'       =>      \$no_update,
     46    ) or pod2usage(2);
     47
     48pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
     49pod2usage( -msg => "Required options: --file --req_id --outdir --dbname",
     50           -exitval => 3,
     51    ) unless
     52    defined $request_file and defined $outdir and defined $dbname and defined $req_id;
     53
     54my $detect_query_read = can_run('detect_query_read') or (warn "Can't find detect_query_read" and $missing_tools = 1);
     55my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools = 1);
     56my $fields = can_run('fields') or (warn "Can't find fields" and $missing_tools = 1);
    6357if ($missing_tools) {
    6458    warn("Can't find required tools.");
    65     exit ($PS_EXIT_CONFIG_ERROR);
    66 }
     59    exit($PS_EXIT_CONFIG_ERROR);
     60}
     61
     62unless (defined $verbose) {
     63    $verbose = 0;
     64}
     65
     66my $ipprc = PS::IPP::Config->new();
     67my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
     68
    6769
    6870if (!$dbserver) {
    69     my $ipprc = PS::IPP::Config->new();
    70     $dbserver =  metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
    71 }
    72 
    73 # just deal with these arguments once and for all
    74 $pstamptool .= " -dbname $dbname" if $dbname;
    75 $pstamptool .= " -dbserver $dbserver" if $dbserver;
    76 $detectresponse .= " --dbname $dbname" if $dbname;
    77 
    78 $no_update = 1 if $mode eq "list_job";
    79 
    80 # Unless we're running as a job, write the parse arguments in case we need to rerun this parsing.
    81 if (!$job_id) {
    82     my $argslist = "$outdir/parse.args";
    83     open ARGSLIST, ">$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
    84     print ARGSLIST "--label $label --mode $mode --req_id $req_id --product $product --outdir $outdir --file $req_file\n";
    85     close ARGSLIST;
     71    $dbserver = metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
     72}
     73
     74$pstamptool .= " -dbname $dbname -dbserver $dbserver";
     75
     76# Project name is hardcoded to gpc1 for the moment.
     77$project = resolve_project($ipprc,"gpc1",$dbname,$dbserver);
     78my $imagedb = $project->{dbname};
     79if (!$imagedb) {
     80    my_die("failed to find imagedb for project: $project", $PS_EXIT_CONFIG_ERROR);
    8681}
    8782
     
    8984my $fields_output;
    9085{
    91     my $command = "echo $req_file | $fields -x 0 EXTNAME EXTVER QUERY_ID";
     86    my $command = "echo $request_file | $fields -x 0 EXTNAME EXTVER QUERY_ID";
    9287    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    9388        run(command => $command, verbose => $verbose);
     
    9792my (undef, $extname, $extver, $req_name) = split " ", $fields_output;
    9893
    99 my_die("$req_file is missing one of EXTNAME EXTVER or QUERY_ID", $PS_EXIT_PROG_ERROR)
     94my_die("$request_file is missing one of EXTNAME EXTVER or QUERY_ID", $PS_EXIT_PROG_ERROR)
    10095    if !(defined($extname) and defined($extver) and defined($req_name));
    101 my_die("$req_file has EXTNAME $extname not MOPS_DETECTABILITY_QUERY table", $PS_EXIT_PROG_ERROR)
     96my_die("$request_file has EXTNAME $extname not MOPS_DETECTABILITY_QUERY table", $PS_EXIT_PROG_ERROR)
    10297    if $extname ne "MOPS_DETECTABILITY_QUERY";
    103 my_die("$req_file is version $extver expecting 1", $PS_EXIT_PROG_ERROR)
     98my_die("$request_file is version $extver expecting 1 or 2", $PS_EXIT_PROG_ERROR)
    10499    if ($extver ne 1) and ($extver ne 2);
    105100
    106 # Set up the workdir for this query.
    107 if (! -e $outdir ) {
    108     mkdir $outdir or my_die("cannot create output directory $outdir", $PS_EXIT_PROG_ERROR);
    109 } elsif (! -d $outdir ) {
    110     my_die ("output fileset directory $outdir exists but is not a directory", $PS_EXIT_PROG_ERROR);
    111 }
    112 
    113 
    114 # Pass along the request file to the response generator.
    115 my $response_file = "$outdir/${req_name}.dresponse.${req_id}.fits";
    116 my $fault;
    117 # my $data_to_update = '';
     101
     102#
     103# query is a hash which uses $fpa_id as the key
     104# The values are hash references which have the various parameter name as the key
     105#   The values of the parameter hashes are arrays which contain the values for individual rows
     106#   in the detectabilty query request
     107my %query = ();
     108
    118109{
    119     my $command = "$detectresponse --input $req_file --output $response_file --workdir $outdir";
    120     if ($job_id) {
    121         $command .= " --job_id $job_id";
    122     } else {
    123         $command .= " --ignore-wisdom";
    124     }
    125     $command .= " --save-temps" if $save_temps;
    126     $command .= " --verbose" if $verbose;
    127 
     110    #
     111    # Parse input request file using detect_query_read
     112    # result is a simple text file
     113    #
     114    my $dqr_command = "$detect_query_read --dbname $imagedb --input $request_file";
    128115    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    129         run(command => $command, verbose => $verbose);
     116        run(command => $dqr_command, verbose => $verbose);
    130117    unless ($success) {
    131         warn("Warn! Unable to perform $command error code: $error_code");
    132     }
    133     # Use the fault code to see if we can regenerate the missing data.
    134     $fault = $error_code >> 8;
    135     if ($fault == $PSTAMP_NOT_AVAILABLE) {
    136         unless (-e "$outdir/update_request.dat") {
    137             my_die ("Update request indicated, but unable to find actual request!", $PS_EXIT_PROG_ERROR);
    138         }
    139         warn("Some inputs are not available and must be updated.");
    140     }   
    141    
    142 }
    143 
    144 my $result;
    145 unless ($job_id) {
    146     # We are running as a parse job
    147     # If we returned correctly with a valid response file, get a job ID
    148     # for the completed work, and move the response to a standardized name.
    149     if ($fault == 0) {
    150         my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir";
    151         $command .= " -job_type detect_query -state stop -fault 0";
    152         $command .= " -rownum 1";
    153 
    154         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    155             run(command => $command, verbose => $verbose);
    156         if ($success) {
    157             $job_id = join "", @$stdout_buf;
    158             chomp $job_id;
    159             if ($job_id && -e $response_file) {
    160                 rename $response_file, "$outdir/response.${job_id}.fits";
     118        # This is a problem, because I'm not sure how we handle a failure to read something.
     119        # We need to return a $PSTAMP_INVALID_REQUEST, I think, but if we can't read it,
     120        # we can't send that response back.
     121        die("Unable to perform $dqr_command error code: $error_code");
     122    }
     123    my $Nrows = 0;
     124    {
     125        my @column_names = ();
     126        # split output into lines skip until the line which lists the column names is found
     127        # Parse subsequent lines
     128        foreach my $entry (split /\n/, (join "", @$stdout_buf)) {
     129            if ($entry =~ /^#/) {
     130                @column_names = split /\s+/, $entry;
     131                shift(@column_names);  # Dump the hash sign.
     132            }
     133            elsif (scalar @column_names) {
     134                # ROWNUM RA1_DEG DEC1_DEG RA2_DEG DEC2_DEG MAG QUERY_ID FPA_ID MJD-OBS FILTER OBSCODE STAGE
     135                my %row_data;
     136                @row_data{@column_names} = (split /\s+/, $entry);
     137                for (my $i = 0; $i <= $#column_names; $i++) {
     138                    push @{ $query{$row_data{"FPA_ID"}}{$column_names[$i]} }, $row_data{$column_names[$i]};
     139                    $Nrows = scalar(keys(%query));
     140                    # print "$row_data{'FPA_ID'} $Nrows $i $column_names[$i] $row_data{$column_names[$i]}\n";
     141                }
     142            }
     143        }
     144    }
     145    #
     146    # Identify target components.  This should properly collate targets on a single imfile.
     147    #
     148    my $query_id;
     149    foreach my $fpa_id (keys %query) {
     150        my %temp_hash;
     151        my $query_style = 'byexp';
     152        my $stage;
     153        my $filter;
     154        my $mjd;
     155        # Confirm that we only have one stage/filter/mjd
     156        if ($fpa_id ne 'Not_Set') {   # We only need to check things that aren't the known odd case.
     157            for (my $i = 0; $i <= $#{ $query{$fpa_id}{STAGE} }; $i++) {
     158                $temp_hash{STAGE}{$query{$fpa_id}{STAGE}[$i]} = 1;
     159                $temp_hash{FILTER}{$query{$fpa_id}{FILTER}[$i]} = 1;
     160                $temp_hash{'MJD-OBS'}{$query{$fpa_id}{'MJD-OBS'}[$i]} = 1;
     161            }
     162            if (scalar(keys(%{ $temp_hash{STAGE} })) == 1) {
     163                $stage = (keys(%{ $temp_hash{STAGE} }))[0];
     164            }
     165            else {
     166                exit_with_failure(21,"Too many STAGEs specified");
     167            }
     168            if (scalar(keys(%{ $temp_hash{FILTER} })) == 1) {
     169                $filter = (keys(%{ $temp_hash{FILTER} }))[0];
     170            }
     171            else {
     172                exit_with_failure(21,"Too many FILTERs specified");
     173            }
     174            if (scalar(keys(%{ $temp_hash{'MJD-OBS'} })) == 1) {
     175                $mjd = (keys(%{ $temp_hash{'MJD-OBS'} }))[0];
     176            }
     177            else {
     178                exit_with_failure(21,"Too many MJD-OBS specified");
     179            }
     180        }
     181
     182        # Set up a rowList with default values
     183        my @rowList;
     184        for (my $i = 0; $i <= $#{ $query{$fpa_id}{STAGE} }; $i++) {
     185            $rowList[$i]->{CENTER_X} = $query{$fpa_id}{RA1_DEG}[$i];
     186            $rowList[$i]->{CENTER_Y} = $query{$fpa_id}{DEC1_DEG}[$i];
     187            $rowList[$i]->{ID} = $query{$fpa_id}{ROWNUM}[$i];
     188            $rowList[$i]->{COORD_MASK} = 0;
     189            # Set default values
     190            $query{$fpa_id}{BAD_COMPONENT}[$i] = 1;
     191            $query{$fpa_id}{IMAGE}[$i] = 'no_image';
     192            $query{$fpa_id}{MASK}[$i] = 'no_mask';
     193            $query{$fpa_id}{WEIGHT}[$i] = 'no_weight';
     194            $query{$fpa_id}{PSF}[$i] = 'no_psf';
     195
     196            $query{$fpa_id}{STAGE_ID}[$i] = 'no_id';
     197            $query{$fpa_id}{IMAGE_DB}[$i] = 'no_imdb';
     198            $query{$fpa_id}{NEED_MAGIC}[$i] = 'no_magic';
     199            $query{$fpa_id}{MAGICKED}[$i] = 'no_magic';
     200            $query{$fpa_id}{CATALOG}[$i] = 'no_catalog';
     201            $query{$fpa_id}{COMPONENT_ID}[$i] = 'no_component';
     202            $query{$fpa_id}{CLASS_ID}[$i] = 'no_class';
     203
     204            $query{$fpa_id}{STATE}[$i] = 'no_state';
     205            $query{$fpa_id}{DATA_STATE}[$i] = 'no_dstate';
     206            $query{$fpa_id}{FAULT}[$i] = 'no_fault';
     207            $query{$fpa_id}{BURNTOOL_STATE}[$i] = 'no_btstate';
     208        }
     209
     210        # Determine the query style for this fpa_id
     211        if ($fpa_id =~ /o.*g.*o/) {
     212            $query_style = 'byexp';
     213        }
     214        elsif ($fpa_id =~ /\d+/) {
     215            $query_style = 'byid';
     216        }
     217        elsif ($fpa_id eq 'Not_Set') {
     218            # no matching file was found skip
     219            next;
     220        }
     221        else {
     222            exit_with_failure(21,"Parse error in request file");
     223        }
     224        # Set common request components
     225        my $option_mask |= 1;
     226        $option_mask |= $PSTAMP_SELECT_IMAGE;
     227        $option_mask |= $PSTAMP_SELECT_MASK;
     228        $option_mask |= $PSTAMP_SELECT_VARIANCE;
     229        $option_mask |= $PSTAMP_SELECT_PSF;
     230
     231        # magic is dead
     232        my $need_magic = 0;
     233        if ($stage eq 'stack') {
     234            $need_magic = 0;
     235        }
     236        my $mjd_min = int $mjd;
     237        my $mjd_max = $mjd + 1;
     238       
     239        my $req_filter;
     240        if ($filter ne 'Not_Set') {
     241            $req_filter = $filter . '%';
     242        }
     243       
     244        # Call the PStamp code to find the images that contain the target on the given MJD in the specified filter.
     245        my $pstamp_images_ref = locate_images($ipprc,$imagedb,
     246                                          \@rowList,
     247                                          $query_style,$stage,
     248                                          $fpa_id,undef,undef,
     249                                          $option_mask,$need_magic,
     250                                          $mjd_min,$mjd_max,$req_filter,undef,$verbose); 
     251       
     252        foreach my $this_image_ref (@{ $pstamp_images_ref }) {
     253
     254            # loop over the rows that this component matched
     255            foreach my $valid_index (@{ $this_image_ref->{row_index} }) {
     256                $query{$fpa_id}{IMAGE}[$valid_index] = $this_image_ref->{image};
     257                $query{$fpa_id}{MASK}[$valid_index] = $this_image_ref->{mask};
     258                $query{$fpa_id}{WEIGHT}[$valid_index] = $this_image_ref->{weight};
     259                $query{$fpa_id}{PSF}[$valid_index] = $this_image_ref->{psf};
     260                $query{$fpa_id}{STAGE_ID}[$valid_index] = $this_image_ref->{stage_id};
     261                $query{$fpa_id}{IMAGE_DB}[$valid_index] = $this_image_ref->{imagedb};
     262                $query{$fpa_id}{NEED_MAGIC}[$valid_index] = $need_magic;
     263                $query{$fpa_id}{BAD_COMPONENT}[$valid_index] = 0;
     264               
     265                if (exists($this_image_ref->{astrom})) {
     266                    $query{$fpa_id}{CATALOG}[$valid_index] = $this_image_ref->{astrom};
     267                }
     268                else {
     269                    $query{$fpa_id}{CATALOG}[$valid_index] = $this_image_ref->{cmf};
     270                }
     271                if (exists($this_image_ref->{class_id})) {
     272                    $query{$fpa_id}{COMPONENT_ID}[$valid_index] = $this_image_ref->{class_id};
     273                    $query{$fpa_id}{CLASS_ID}[$valid_index] = $this_image_ref->{class_id};
     274                   
     275                }
     276                else {
     277                    $query{$fpa_id}{COMPONENT_ID}[$valid_index] = $this_image_ref->{skycell_id};
     278                    $query{$fpa_id}{CLASS_ID}[$valid_index] = 'fpa';
     279                }
     280               
     281                $query{$fpa_id}{STATE}[$valid_index] = $this_image_ref->{state};
     282                if (exists($this_image_ref->{data_state})) {
     283                    $query{$fpa_id}{DATA_STATE}[$valid_index] = $this_image_ref->{data_state};
     284                }
     285                else {
     286                    $query{$fpa_id}{DATA_STATE}[$valid_index] = $this_image_ref->{state};
     287                }
     288                $query{$fpa_id}{FAULT}[$valid_index] = 0;
     289                    $query{$fpa_id}{MAGICKED}[$valid_index] = $this_image_ref->{magicked};
     290                if ($stage eq 'chip') {
     291                    $query{$fpa_id}{BURNTOOL_STATE}[$valid_index] = $this_image_ref->{burntool_state};
     292                }
     293               
     294                # Determine if the data exists.
     295                if (($query{$fpa_id}{STATE}[$valid_index] eq 'goto_purged') or
     296                    ($query{$fpa_id}{DATA_STATE}[$valid_index] eq 'purged') or
     297                    ($query{$fpa_id}{STATE}[$valid_index] eq 'drop') or
     298                    ($query{$fpa_id}{STATE}[$valid_index] eq 'error_cleaned') or
     299                    ($query{$fpa_id}{STATE}[$valid_index] eq 'goto_scrubbed') or
     300                    ($query{$fpa_id}{DATA_STATE}[$valid_index] eq 'scrubbed')) {
     301                   
     302                    # image is gone and it's not coming back
     303                    $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_GONE;
     304                }
     305                elsif ($need_magic and ($query{$fpa_id}{MAGICKED}[$valid_index] eq 0)) {
     306                    $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_DESTREAKED;
     307                }
     308                elsif (($query{$fpa_id}{DATA_STATE}[$valid_index] ne 'full')) {               
     309                    $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_AVAILABLE;
     310                   
     311                    # updating stacks isn't implemented
     312                    if (($stage eq 'stack')) {
     313                        $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_IMPLEMENTED;
     314                    }
     315                    # updating old burntool data isn't implemented
     316                    elsif ($stage eq 'chip') {
     317                        if ($query{$fpa_id}{BURNTOOL_STATE}[$valid_index] and
     318                            (abs($query{$fpa_id}{BURNTOOL_STATE}[$valid_index]) < 14)) {
     319                            $query{$fpa_id}{FAULT}[$valid_index] = $PSTAMP_NOT_IMPLEMENTED;
     320                            }
     321                    }
     322                } # End determining error faults.
    161323            }
    162             $result = 0;
     324        }
     325    }
     326}
     327
     328my %update_request;
     329my %rows_for_component;
     330my %faulted_rows;
     331
     332# now build a hash using image name as key which contains the list of rows for that image
     333foreach my $fpa_id (keys %query) {
     334    for (my $i = 0; $i <= $#{ $query{$fpa_id}{ROWNUM} }; $i++) {
     335        if ($query{$fpa_id}{BAD_COMPONENT}[$i] == 0) {
     336            push @{ $rows_for_component{$fpa_id}{$query{$fpa_id}{IMAGE}[$i]} }, $i;
    163337        } else {
    164             warn("Unable to perform $command error code: $error_code");
    165             $result = $error_code >> 8;
    166         }
    167     }
    168     elsif ($fault == $PSTAMP_NOT_AVAILABLE) {
    169         # Failed to run correctly, which means that we need to queue a job and flag data for updating.
    170         # first create a parent job for the actual detectabilty query
    171         my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir/1_";
    172         $command .= " -job_type detect_query -state run -fault 0 -is_parent";
    173         $command .= " -rownum 1";
    174 
    175         my $parent_job_id;
    176         my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    177             run(command => $command, verbose => $verbose);
    178         if ($success) {
    179             # pstamptool returns the job_id of the new job
    180             $parent_job_id = join "", @$stdout_buf;
    181             chomp $parent_job_id;
    182             if ($parent_job_id) {
    183                 $result = 0;
     338            $faulted_rows{$query{$fpa_id}{ROWNUM}[$i]} = $query{$fpa_id}{FAULT}[$i];
     339        }
     340    }
     341}
     342
     343#
     344# Finally build the parameter lists and queue jobs for each component
     345#
     346
     347my $job_num = 1;
     348foreach my $fpa_id (keys %rows_for_component) {
     349    foreach my $component (keys % {$rows_for_component{$fpa_id} } ) {
     350        my $i = $rows_for_component{$fpa_id}{$component}[0];
     351        my $dep_id = 0;
     352        my $data_state = $query{$fpa_id}{DATA_STATE}[$i];
     353        if ($data_state ne 'full') {
     354            # Queue this data to be updated
     355            my $stage = $query{$fpa_id}{STAGE}[$i];
     356            my $stage_id = $query{$fpa_id}{STAGE_ID}[$i];
     357            my $component = $query{$fpa_id}{COMPONENT_ID}[$i];
     358            print "Need to UPDATE $stage $stage_id $component from $data_state\n";
     359    ####                           my ($req_id, $outdir, $label, $state, $stage, $stage_id, $component, $need_magic, $imagedb) = @_;
     360            $dep_id = queue_update_run($req_id, $outdir, $label, $data_state, $stage, $stage_id, $component, 0, $imagedb);
     361        }
     362
     363        my $outputBase = "$outdir/$job_num" . "_";
     364
     365        # params_file is an mdc description containing the parameters for the job
     366        my $params_file = $outputBase . "params.mdc";
     367
     368        open PARAMS, ">$params_file" or my_die("failed to create $params_file", $PS_EXIT_UNKNOWN_ERROR);
     369
     370        # first the job params
     371        print PARAMS "dqueryJobParams METADATA\n";
     372        foreach my $key (keys %{ $query{$fpa_id} } ) {
     373            my $value = $query{$fpa_id}{$key}[0];
     374            print PARAMS "\t$key\t\tSTR\t$value\n";
     375        }
     376        print PARAMS "END\n\n";
     377
     378        # then one structure with the coordinates for each row
     379        print PARAMS "dqueryCoord MULTI\n";
     380
     381        my @coordkeys = qw(ROWNUM RA1_DEG DEC1_DEG RA2_DEG DEC2_DEG MAG);
     382        foreach my $row ( @{ $rows_for_component{$fpa_id}{$component} }) {
     383            print PARAMS "\ndqueryCoord METADATA\n";
     384            foreach my $key (@coordkeys) {
     385                my $value = $query{$fpa_id}{$key}[$row];
     386                print PARAMS "\t$key\t\tSTR\t$value\n";
     387            }
     388            print PARAMS "END\n";
     389        }
     390        close(PARAMS);
     391
     392        # use first rownum for this component as the rownum for the job
     393        my $rownum = $query{$fpa_id}{ROWNUM}[$rows_for_component{$fpa_id}{$component}[0]];
     394
     395        my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outputBase -job_type detect_query -state run -rownum $rownum";
     396        $command .= " -dep_id $dep_id" if $dep_id;
     397        unless ($no_update) {
     398            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     399                run(command => $command, verbose => $verbose);
     400            if ($success) {
     401                my $job_id = join "", @$stdout_buf;
     402                print "   Queued job: $job_id\n";
    184403            } else {
    185                 print STDERR "pstamptool did not return a valid job_id for parent job\n";
    186                 $result = $PS_EXIT_UNKNOWN_ERROR;
     404                my $exit_status = $error_code >> 8;
     405                $exit_status = $PS_EXIT_UNKNOWN_ERROR unless $exit_status;
     406                my_die("Unable to perform $command error code: $error_code", $exit_status);
    187407            }
    188408        } else {
    189             warn("Unable to perform $command error code: $error_code");
    190             $result = $error_code >> 8;
    191         }
    192         # now create child jobs for each dependent. All these jobs do is finish once the dependency
    193         # is satisfied
    194         if (!$result) {
    195             # Get the dependency id for the data we need to have updated.
    196             my $job_num = 2;
    197             open(UPDATE_REQUEST,"$outdir/update_request.dat") || my_die ("Update request indicated, but unable to find actual request!", $PS_EXIT_PROG_ERROR);
    198             while (<UPDATE_REQUEST>) {
    199                 my $data_to_update = $_;
    200                 chomp($data_to_update);
    201                 my $dep_id = queue_update_run($req_id,$job_id,$outdir,$label,$data_to_update);
    202 
    203                 # Link this request to a job and link that job to the dependent
    204                 my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir/${job_num}_";
    205                 $command .= " -job_type child -state run -fault 0 -parent_id $parent_job_id";
    206                 $command .= " -rownum 1"; # XXX: we should choose a correct rownum
    207                 $command .= " -dep_id $dep_id" if $dep_id;
    208 
    209                 $job_num++;
    210 
    211                 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    212                     run(command => $command, verbose => $verbose);
    213 
    214                 if ($success) {
    215                     $job_id = join "", @$stdout_buf;
    216                     chomp $job_id;
    217                     $result = 0;
    218                 } else {
    219                     warn("Unable to perform $command error code: $error_code");
    220                     $result = $error_code >> 8;
    221                     last;
    222                 }
    223             }
    224             close(UPDATE_REQUEST);
    225         }
    226     }
    227     else {
    228         my_die ("Parse fault!!", $fault);
    229     }
    230     # This does not set the request state to stop.  That will happen with the request_finish.pl script,
    231     # which will notice that we've inserted the stopped job and decide we're finished. Easy enough.
    232     {
    233         my $command = "$pstamptool -updatereq -req_id $req_id -set_name $req_name -set_outProduct $product";
    234         $command .= " -set_fault $result" if $result;
    235 
     409            print STDERR "skipping $command\n";
     410        }
     411        $job_num++;
     412    }
     413}
     414
     415# XXX: flesh this out once we have a request without duplicate ROWNUMS
     416foreach my $rownum (keys %faulted_rows ) {
     417    my $fault = $faulted_rows{$rownum};
     418    $fault = $PSTAMP_NO_IMAGE_MATCH if ($fault eq 'no_fault');
     419    print STDERR "insert faulted job for $rownum: $fault\n";
     420}
     421
     422{
     423    my $command = "$pstamptool -updatereq -req_id $req_id -set_name $req_name -set_outProduct $product";
     424    # $command .= " -set_fault $result" if $result;
     425
     426    unless ($no_update) {
    236427        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    237428            run(command => $command, verbose => $verbose);
    238429        unless ($success) {
    239             my_die("$command failed",$PS_EXIT_UNKNOWN_ERROR);
    240         }
    241     }
    242 } else {
    243     # We are running as a job presumably because an input needed
    244     # to be regenerated
    245     if ($fault) {
    246         # in some cases we will need to finish off the request
    247         my_die ("Run fault!!", $fault);
    248     }
    249     if (-e $response_file) {
    250         rename $response_file, "$outdir/response.${job_id}.fits";
    251     }
    252 }
    253 
    254  
     430        my_die("$command failed",$PS_EXIT_UNKNOWN_ERROR);
     431        }
     432    } else {
     433        print STDERR "Skipping $command\n";
     434    }
     435}
     436
    255437exit 0;
    256438
    257 
    258 # If we have to queue an update run, do so and create a new dependent
    259439sub queue_update_run {
    260     my ($req_id, $job_id, $outdir, $label, $data_to_update) = @_;
    261 
    262     my ($state, $stage, $stage_id, $component, $need_magic, $imagedb) = split /\s+/, $data_to_update;
     440    my ($req_id, $outdir, $label, $state, $stage, $stage_id, $component, $need_magic, $imagedb) = @_;
     441
     442#    my ($state, $stage, $stage_id, $component, $need_magic, $imagedb) = split /\s+/, $data_to_update;
    263443   
    264444    if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) {
     
    293473    return($dep_id);
    294474}
    295        
    296    
     475
    297476
    298477sub my_die {
    299     my $msg = shift;
    300     my $fault = shift;
    301 
    302     carp $msg;
    303 
    304     # we don't fault the request here pstamp_parser_run.pl handles that if necessary
    305     exit $fault;
    306 }
     478    my $message = shift;
     479    my $exit_code = shift;
     480
     481    $exit_code = $PS_EXIT_PROG_ERROR unless defined $exit_code;
     482
     483    carp("$message");
     484    exit($exit_code);
     485}
     486
     487sub exit_with_failure {
     488    my $status = shift;
     489    my $message = shift;
     490    my_die($message, $status);
     491}
     492
  • tags/ipp-20111222/pstamp/scripts/pstamp_job_run.pl

    r33174 r33325  
    7979my $ppstamp    = can_run('ppstamp') or (warn "Can't find ppstamp" and $missing_tools = 1);
    8080my $pstamp_get_image_job    = can_run('pstamp_get_image_job.pl') or (warn "Can't find pstamp_get_image_job.pl" and $missing_tools = 1);
    81 my $dqueryparse = can_run('dqueryparse.pl') or (warn "Can't find dqueryparse.pl" and $missing_tools = 1);
     81my $dquery_job_run = can_run('dquery_job_run.pl') or (warn "Can't find dquery_job_run.pl" and $missing_tools = 1);
    8282my $streaksreplace = can_run('streaksreplace')  or (warn "Can't find streaksreplace"  and $missing_tools = 1);
    8383my $magicdstool = can_run('magicdstool')  or (warn "Can't find magicdstool"  and $missing_tools = 1);
     
    303303    }
    304304} elsif ($jobType eq "detect_query") {
    305     # detect_query jobs are basically holders to note that we need a file updated before we can continue.
    306     # Load the argument list that dqueryparse should have created the first time it ran, so we know how to
    307     # run it again the same way.
    308     my $outdir = dirname($outputBase);
    309     my $argslist = "$outdir/parse.args";
    310     open ARGSLIST, "<$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
    311     my $argString = <ARGSLIST>;
    312     close ARGSLIST;
    313     chomp $argString;
     305    # my $outdir = dirname($outputBase);
     306    # my $argslist = "$outdir/parse.args";
     307    # open ARGSLIST, "<$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
     308    # my $argString = <ARGSLIST>;
     309    # close ARGSLIST;
     310    # chomp $argString;
    314311
    315312    # XXX: should we do any other sanity checking?
    316     my_die("arglist file $argslist is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
    317 
    318     my $command = "$dqueryparse --job_id $job_id $argString";
     313    # my_die("arglist file $argslist is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
     314
     315    my $command = "$dquery_job_run --job_id $job_id --output_base $outputBase";
    319316    $command .= " --dbname $dbname" if $dbname;
    320317    $command .= " --dbserver $dbserver" if $dbserver;
     
    329326    } else {
    330327        $jobStatus = $error_code >> 8;
    331         my_die("dqueryparse.pl failed with error code: $jobStatus", $job_id, $jobStatus);
     328        my_die("dquery_job_run.pl failed with error code: $jobStatus", $job_id, $jobStatus);
    332329    }
    333330} elsif ($jobType eq "child") {
Note: See TracChangeset for help on using the changeset viewer.