IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 28003 for branches/pap/pstamp


Ignore:
Timestamp:
May 18, 2010, 12:49:05 PM (16 years ago)
Author:
eugene
Message:

merging changes from trunk into branches/pap

Location:
branches/pap
Files:
18 edited
2 copied

Legend:

Unmodified
Added
Removed
  • branches/pap

  • branches/pap/pstamp/scripts/Makefile.am

    r27704 r28003  
    33
    44install_files = \
     5        pstamp_cleanup.pl \
    56        pstamp_finish.pl \
    67        pstamp_insert_request.pl \
    … …  
    2021        pstamp_checkdependent.pl \
    2122        request_finish.pl \
     23        detectability_respond.pl \
    2224        detect_query_read \
    2325        detect_response_create \
  • branches/pap/pstamp/scripts/detect_query_read

    r18587 r28003  
    7878                        comment => 'site identifier (MPC observatory code)',
    7979                        value => undef
    80               }
     80                      },
     81        'STAGE'    => {
     82                        name => 'STAGE',
     83                        writetype => TSTRING,
     84                        comment => 'processing stage to examine',
     85                        value => undef
     86                      }
    8187};
    8288
    8389# key_array insures that the order that the keywords is printed out is
    8490# the same as the ICD
    85 my @key_array = qw( QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE );
     91my @key_array = qw( QUERY_ID FPA_ID MJD_OBS FILTER OBSCODE STAGE);
    8692
    8793# Specification of columns
    … …  
    144150        my $name = $header->{$key}->{name};
    145151        my $value = $inHeader->{$name};
     152        if (($key eq 'STAGE')&& !(defined($value))) {
     153            $value = 'DIFF';
     154        }
    146155        # get rid of quotes and whitespace
    147156        $value =~ s/\'//g;
  • branches/pap/pstamp/scripts/detectability_respond.pl

    r27643 r28003  
    4141my $EXTVER = 1.0;
    4242my $EXTNAME = 'MOPS_DETECTABILITY_RESPONSE';
    43 my ($req_id,$req_name,$product,$need_magic,$missing_tools);
    44 my ($request_file,$output,$dbname,$verbose,$save_temps);
     43my ($req_id,$req_name,$product,$need_magic,$missing_tools,$project);
     44my ($request_file,$output,$workdir,$dbname,$dbserver,$verbose,$save_temps);
    4545GetOptions(
    46     'input=s'          =>     \$request_file,
     46    'input=s'         =>      \$request_file,
    4747    'output=s'        =>      \$output,
     48    'workdir=s'       =>      \$workdir,
    4849    'dbname=s'        =>      \$dbname,
     50    'dbserver=s'      =>      \$dbserver,
    4951    'verbose'         =>      \$verbose,
    5052    'save-temps'      =>      \$save_temps,
    … …  
    5557           -exitval => 3,
    5658    ) unless
    57     defined $request_file and defined $output and defined $dbname;
     59    defined $request_file and defined $output and defined $workdir and defined $dbname;
    5860
    5961my $detect_query_read = can_run('detect_query_read') or (warn "Can't find detect_query_read" and $missing_tools = 1);
    … …  
    7173
    7274my $ipprc = PS::IPP::Config->new();
    73 #my $tmp_dir = "/data/${host}.0/tmp/";
     75
     76if (!$dbserver) {
     77    $dbserver = metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
     78}
     79# This is hardcoded in for the moment.
     80$project = resolve_project($ipprc,"gpc1",$dbname,$dbserver);
     81my $imagedb = $project->{dbname};
     82if (!$imagedb) {
     83    carp("failed to find imagedb for project: $project");
     84}
    7485
    7586#
    7687# Parse input request file using detect_query_read (as it's already written).
    7788#
    78 
    7989my $dqr_command = "$detect_query_read --input $request_file";
    8090my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    8191    run(command => $dqr_command, verbose => $verbose);
    8292unless ($success) {
    83     my_die("Unable to perform $dqr_command error code: $error_code",-1,-1,-1,-1,-1,-1);
     93    # This is a problem, because I'm not sure how we handle a failure to read something.
     94    # We need to return a $PSTAMP_INVALID_REQUEST, I think, but if we can't read it,
     95    # we can't send that response back.
     96    die("Unable to perform $dqr_command error code: $error_code");
    8497}
    8598my %query = ();
    … …  
    119132my %image_list_hash;
    120133for (my $i = 1; $i < $Nrows; $i++) {
    121 #    print "$i $Nrows $query{CONTENT}{RA1_DEG}[$i] $query{CONTENT}{DEC1_DEG}[$i]\n";
    122 
     134    # This could use the fact that locate_images now accepts position arrays, but
     135    # I'll save that for after I get the majority of things working.
    123136    my $image_set_tmp  = find_image_set($query{HEADER}{FPA_ID}[0],$query{HEADER}{STAGE}[0],
    124137                                        $query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],
    … …  
    126139                                        $query{CONTENT}{ROWNUM}[$i],$verbose);
    127140    unless (%$image_set_tmp) {
    128         my_die("No images were returned.",$query{HEADER}{QUERY_ID}[0],$query{HEADER}{FPA_ID}[0],
    129                $query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],$query{HEADER}{OBSCODE}[0],
    130                $query{HEADER}{STAGE}[0]);
    131     }
    132     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";
    133     # This appends, assuming that if we get an image, we also get the identical psf/mask/weight/etc.
     141        # No images were returned, so create a dummy entry that
     142        $image_list_hash{'no_image'}{IMAGE}    = 'no_image';
     143        $image_list_hash{'no_image'}{PSF}      = 'no_psf';
     144        $image_list_hash{'no_image'}{MASK}     = 'no_mask';
     145        $image_list_hash{'no_image'}{WEIGHT}   = 'no_weight';
     146        $image_list_hash{'no_image'}{CATALOG}  = 'no_catalog';
     147        $image_list_hash{'no_image'}{CLASS_ID} = 'no_class';
     148        $image_list_hash{'no_image'}{ERROR}    = $PSTAMP_NO_IMAGE_MATCH;
     149        push @{ $image_list_hash{'no_image'}{SKY_COORDINATES} }, "$query{CONTENT}{RA1_DEG}[$i] $query{CONTENT}{DEC1_DEG}[$i]";
     150        push @{ $image_list_hash{'no_image'}{ROWNUM} }, $query{CONTENT}{ROWNUM}[$i];
     151        next;
     152    }
     153#     print "=== $image_set_tmp->{IMAGE}\n    $image_set_tmp->{PSF}\n";
     154#     print "    $image_set_tmp->{MASK}\n    $image_set_tmp->{WEIGHT}\n";
     155#     print "    $image_set_tmp->{SKY_COORDINATES}\n    $image_set_tmp->{ROWNUM}\n";
     156
     157    # This indexes the results for identical images into the same hash.
    134158    $image_list_hash{$image_set_tmp->{IMAGE}}{IMAGE}    = $image_set_tmp->{IMAGE};
    135159    $image_list_hash{$image_set_tmp->{IMAGE}}{PSF}      = $image_set_tmp->{PSF};
    … …  
    138162    $image_list_hash{$image_set_tmp->{IMAGE}}{CATALOG}  = $image_set_tmp->{CATALOG};
    139163    $image_list_hash{$image_set_tmp->{IMAGE}}{CLASS_ID} = $image_set_tmp->{CLASS_ID};
     164    $image_list_hash{$image_set_tmp->{IMAGE}}{ERROR}    = $image_set_tmp->{ERROR};
    140165    push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{SKY_COORDINATES} }, $image_set_tmp->{SKY_COORDINATES};
    141166    push @{ $image_list_hash{$image_set_tmp->{IMAGE}}{ROWNUM} }, $image_set_tmp->{ROWNUM};
    142167}
     168
    143169my $i = 0;
    144 
    145170foreach my $k (keys %image_list_hash) {
     171    # If we errored out on finding an image, we need to not try to run psphot here.
     172    if ($image_list_hash{$k}{ERROR} != 0) {
     173        next;
     174    }
    146175    # Write coordinates of the requested targets to a file.
    147     my ($coordfile,$coordname) = tempfile("/tmp/detect.coords.$i.XXXX",
     176    my ($coordfile,$coordname) = tempfile("${workdir}/detect.coords.$i.XXXX",
    148177                                            UNLINK => !$save_temps);
    149     my ($targetfile,$targetname) = tempfile("/tmp/detect.targets.$i.XXXX",
     178    my ($targetfile,$targetname) = tempfile("${workdir}/detect.targets.$i.XXXX",
    150179                                            UNLINK => !$save_temps);
    151180
    … …  
    153182        print $coordfile "$image_list_hash{$k}{SKY_COORDINATES}[$j]\n";
    154183    }
    155 
     184#    print "$k\n";
    156185    # Convert the sky coordinates to image coordinates with ppCoord.
    157186    my $command = "ppCoord -astrom $image_list_hash{$k}{CATALOG} -radec $coordname";
    … …  
    171200    }
    172201
    173    
     202#     print "psphot $image_list_hash{$k}{PSF}\n";
    174203    # Run psphotForced on the target list.
    175     my $tmpdir  = tempdir("detect.$i.XXXX", DIR => "/tmp/", CLEANUP => !$save_temps);
     204    my $tmpdir  = tempdir("detect.$i.XXXX", DIR => "${workdir}/", CLEANUP => !$save_temps);
    176205    $image_list_hash{$k}{OUTROOT} = "$tmpdir/detectability.$query{HEADER}{STAGE}[0].$query{HEADER}{FPA_ID}[0]";
    177206   
    … …  
    185214        run(command => $psphot_cmd, verbose => $verbose);
    186215    unless ($success) {
    187         my_die("Unable to perform $psphot_cmd. Error_code: $error_code",
    188                $query{HEADER}{QUERY_ID}[0],$query{HEADER}{FPA_ID}[0],
    189                $query{HEADER}{MJD_OBS}[0],$query{HEADER}{FILTER}[0],$query{HEADER}{OBSCODE}[0],
    190                $query{HEADER}{STAGE}[0],$error_code);
     216        $image_list_hash{$k}{ERROR} = $PSTAMP_SYSTEM_ERROR;
    191217    }
    192218}
    … …  
    196222#
    197223my @rownums = ();
     224my @out_errors = ();
    198225my @psphot_Npix = ();
    199226my @psphot_Qfact= ();
    200227my @psphot_flux = ();
     228
    201229foreach my $k (keys %image_list_hash) {
    202     my $cmf = "$image_list_hash{$k}{OUTROOT}.$image_list_hash{$k}{CLASS_ID}.cmf";
    203    
    204     my ($tmp_Npix,$tmp_Qfact,$tmp_flux) = read_cmf_file($cmf,$image_list_hash{$k}{EXTENSION_BASE});
    205 
    206     push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
    207     push @psphot_Npix,    @{ $tmp_Npix };
    208     push @psphot_Qfact,   @{ $tmp_Qfact };
    209     push @psphot_flux,    @{ $tmp_flux };
     230    if ($image_list_hash{$k}{ERROR} == 0) {
     231        my $cmf = "$image_list_hash{$k}{OUTROOT}.$image_list_hash{$k}{CLASS_ID}.cmf";
     232       
     233        my ($tmp_Npix,$tmp_Qfact,$tmp_flux) = read_cmf_file($cmf,$image_list_hash{$k}{EXTENSION_BASE});
     234       
     235        push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
     236        push @out_errors,     (map { $image_list_hash{$k}{ERROR} }  @{ $image_list_hash{$k}{ROWNUM} });
     237        push @psphot_Npix,    @{ $tmp_Npix };
     238        push @psphot_Qfact,   @{ $tmp_Qfact };
     239        push @psphot_flux,    @{ $tmp_flux };
     240    }
     241    else {
     242        push @rownums,        @{ $image_list_hash{$k}{ROWNUM} };
     243        push @out_errors,     (map { $image_list_hash{$k}{ERROR} }  @{ $image_list_hash{$k}{ROWNUM} });
     244        push @psphot_Npix,    (map { 0 }  @{ $image_list_hash{$k}{ROWNUM} });
     245        push @psphot_Qfact,   (map { 0.0 }  @{ $image_list_hash{$k}{ROWNUM} });
     246        push @psphot_flux,    (map { 0.0 }  @{ $image_list_hash{$k}{ROWNUM} });
     247    }   
    210248}
    211249
    … …  
    214252                    $query{HEADER}{MJD_OBS}[0],$query{HEADER}{filter}[0],
    215253                    $query{HEADER}{obscode}[0],
    216                     \@rownums, \@psphot_Npix, \@psphot_Qfact, \@psphot_flux);
    217 
     254                    \@rownums, \@out_errors, \@psphot_Npix, \@psphot_Qfact, \@psphot_flux);
     255# print "Wrote response file $output\n";
    218256#
    219257# Add to datastore
    220258#
    221 # my $finish_command = "dquery_finish.pl --req_id $req_id --req_name $req_name --product $product";
    222 # ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    223 #     run(command => $finish_command, verbose => $verbose);
    224 # unless ($success) {
    225 #     warn ("Unable to perform $finish_command error code: $error_code");
    226 # }
    227 
     259# Files are added to the datastore by dquery_finish.pl
    228260#
    229261# Cleanup
    230262#
    231263# Since everything is written to temporary files, there should be nothing to cleanup.
     264
    232265#
    233266# Utilities
    … …  
    242275    my $index  = shift;
    243276    my $verbose = shift;
    244    
     277
     278    # This is the set of things that we need in order to run psphotForced
    245279    my $option_mask |= 1;
    246280    $option_mask |= $PSTAMP_SELECT_IMAGE;
    … …  
    252286    my $mjd_max = $mjd + 1;
    253287
     288    # Construct a row list.
     289    my @rowList;
     290    $rowList[0]->{CENTER_X} = $ra;
     291    $rowList[0]->{CENTER_Y} = $dec;
     292    $rowList[0]->{ID} = 1;
     293    $rowList[0]->{STAGE} = $stage;
     294    $rowList[0]->{COORD_MASK} = 0;
     295
     296    #    print "$stage\n";
    254297    # Call the PStamp code to find the images that contain the target on the given MJD in the specified filter.
    255     my @images = locate_images($ipprc,$dbname,"bycoord",$stage,
    256                                undef,undef,undef,$option_mask,$need_magic,
    257                                $ra,$dec,$mjd_min,$mjd_max,$filter . ".00000",undef,$verbose); 
     298    my @images = locate_images($ipprc,$imagedb,
     299                                \@rowList,
     300                               "bycoord",$stage,
     301                               undef,undef,undef,
     302                               $option_mask,$need_magic,
     303                               # $ra,$dec,
     304                               $mjd_min,$mjd_max,$filter . ".00000",undef,$verbose); 
    258305
    259306    my %image_info  = ();
    … …  
    270317            }
    271318            elsif ($stage eq 'stack') {
    272                 # Stacks hide the exposure name very well, so I'm
    273                 # choosing the stack_id as the FPA_ID to match. This
    274                 # probably needs to be approved somehow.
     319                # Stacks hide the exposure name very well, so we can only match against stage_id
    275320                if (${ $j }{stage_id} ne $FPA_ID) {
    276321                    next;
    … …  
    285330            }
    286331            # Debug prints of all the components of this image
    287             foreach my $k (keys %{ $j }) {
    288                 print "$i $j $k ${ $j }{$k}\n";
    289             }
    290            
     332#           foreach my $k (keys %{ $j }) {
     333#               if ($k eq 'row_index') {
     334#                   print "$i $j $k @{${ $j }{$k} }\n";
     335#               }
     336#               print "$i $j $k ${ $j }{$k}\n";
     337#           }
     338
     339            # Check for existance of the images. Drawn mostly from pstampparse.pl
     340            my $run_state = ${ $j }{state};
     341            my $data_state = ${ $j }{data_state};
     342            $data_state = $run_state if $stage eq 'stack';
     343            my $fault = 0;
     344            if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
     345                ($run_state eq 'drop') or
     346                ($run_state eq 'error_cleaned') or
     347                ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
     348                # image is gone and it's not coming back
     349                $fault = $PSTAMP_GONE;
     350            }
     351            elsif  (($data_state ne 'full') or ($need_magic and (${ $j }{magicked} < 0))) {
     352                if (($stage eq 'stack')||($stage eq 'diff')) {
     353                    # updating stacks and diffs isn't implemented
     354                    $fault = $PSTAMP_NOT_IMPLEMENTED;
     355                }
     356                if ($stage eq 'chip') {
     357                    my $burntool_state = ${ $j }{burntool_state};
     358                    if ($burntool_state and (abs($burntool_state) < 14)) {
     359                        $fault = $PSTAMP_NOT_AVAILABLE;
     360                    }
     361                }
     362               
     363                if ($fault == 0) {
     364                    # This bombs us out to dqueryparse, which will then flag a job for this run to be updated.
     365                    my_die_for_update($data_state,$query{HEADER}{STAGE}[0],
     366                                      ${ $j }{stage_id},${ $j }{class_id} || ${ $j }{skycell_id},
     367                                      $need_magic,$imagedb,$PSTAMP_NOT_AVAILABLE);
     368                }
     369            }
     370
    291371            # This image matches, so we want to save the information into our output structure
    292372            $image_info{ROWNUM} = $index;
    … …  
    295375            $image_info{MASK}   = ${ $j }{mask};
    296376            $image_info{WEIGHT} = ${ $j }{weight};
     377            $image_info{ERROR}  = $fault;
    297378            $image_info{SKY_COORDINATES} = "$ra $dec";
    298379            # To do sky->image coordinate transformations, we need to use the cmf/smf file. If
    … …  
    405486    my $obscode = shift;
    406487    my $rownum_ref = shift;
     488    my $out_err_ref = shift;
    407489    my $psphot_Npix_ref = shift;
    408490    my $psphot_Qfact_ref = shift;
    … …  
    413495    my $columns = [
    414496        # matching rownum from detectability original request
    415         { name => 'ROWNUM',   type => '20A', writetype => TSTRING },
     497        { name => 'ROWNUM',   type => 'V', writetype => TULONG },
     498        # any errors that occurred during processing
     499        { name => 'ERROR_CODE',   type => 'V', writetype => TULONG },
    416500        # number of pixels used in hypothetical PSF for the query detection
    417501        { name => 'DETECT_N', type => 'V',   writetype => TULONG },
    … …  
    455539    for (my $i = 0; $i < $numRows; $i++) {
    456540        push @{$colData{'ROWNUM'}},      ${ $rownum_ref }[$i];
     541        push @{$colData{'ERROR_CODE'}},  ${ $out_err_ref }[$i];
    457542        push @{$colData{'DETECT_N'}},    ${ $psphot_Npix_ref }[$i];
    458543        push @{$colData{'DETECT_F'}},    ${ $psphot_Qfact_ref }[$i];
    … …  
    529614
    530615}
     616
     617sub my_die_for_update {
     618    my $state = shift;
     619    my $stage = shift;
     620    my $stage_id = shift;
     621    my $component = shift;
     622    my $need_magic = shift;
     623    my $imagedb = shift;
     624    my $exit_code = shift;
     625
     626    print "$state $stage $stage_id $component $need_magic $imagedb\n";
     627    print STDERR "$state $stage $stage_id $component $need_magic $imagedb\n";
     628    exit($exit_code);
     629}
  • branches/pap/pstamp/scripts/dquery_finish.pl

    r27578 r28003  
    2020use PS::IPP::Config qw( :standard );
    2121
    22 my ( $req_id, $req_name, $req_file, $product, $out_dir, $dbname, $dbserver, $verbose, $save_temps );
     22my ( $req_id, $req_name, $req_file, $product, $outdir, $dbname, $dbserver, $verbose, $save_temps );
    2323
    2424GetOptions(
    … …  
    2727           'req_file=s' => \$req_file,
    2828           'product=s'  => \$product,
    29            'out_dir=s'  => \$out_dir,
     29           'outdir=s'   => \$outdir,
    3030           'dbname=s'   => \$dbname,
    3131           'dbserver=s' => \$dbserver,
    … …  
    4141$err .= "--req_name is required\n" if !$req_name;
    4242$err .= "--product is required\n" if !$product;
    43 $err .= "--out_dir is required\n" if !$out_dir;
     43$err .= "--outdir is required\n" if !$outdir;
    4444
    4545die "$err" if $err;
    … …  
    7676    die "product directory does not exist $prod_dir";
    7777}
    78 my $out_dir = "$prod_dir/$req_name";
     78my $outdir = "$prod_dir/$req_name";
    7979}
    80 if (! -e $out_dir ) {
     80if (! -e $outdir ) {
    8181    # something must have gone wrong at the parse stage
    82     print STDERR "output fileset directory $out_dir does not exist\n" if $verbose;
    83     if (! mkdir $out_dir ) {
     82    print STDERR "output fileset directory $outdir does not exist\n" if $verbose;
     83    if (! mkdir $outdir ) {
    8484        stop_request($req_id, $PS_EXIT_SYS_ERROR, $verbose);
    85         die "cannot create output directory $out_dir";
     85        die "cannot create output directory $outdir";
    8686    }
    87 } elsif (! -d $out_dir) {
     87} elsif (! -d $outdir) {
    8888    stop_request($req_id, $PS_EXIT_SYS_ERROR, $verbose);
    89     die "output fileset directory $out_dir exists but is not a directory";
     89    die "output fileset directory $outdir exists but is not a directory";
    9090}
    9191
    … …  
    118118
    119119# XXX: have the jobs produce the reglist as with postage stamp requests
    120 my ($REGLIST, $reg_list) = tempfile("$out_dir/reqlist.XXXX", UNLINK => !$save_temps);
     120my ($REGLIST, $reg_list) = tempfile("$outdir/reqlist.XXXX", UNLINK => !$save_temps);
     121
    121122foreach my $job (@jobs) {
    122123    my $job_id = $job->{job_id};
    123124    my $response_file = "response${job_id}.fits";
    124     my $response_path = "$out_dir/$response_file";
     125    my $response_path = "$outdir/$response_file";
    125126
    126127    if (-e $response_path) {
    127128        # the job generated a response file put it into the Data Store
    128129        print $REGLIST "$response_file|||table|\n";
     130
     131        # do the same if we have an error file.  Should the parse data be uploaded as well?
     132        my $err_file = "parse_error.txt";
     133        if (-e "$outdir/$err_file") {
     134            print $REGLIST "$err_file|||text|\n";
     135        }
    129136    } else  {
    130137        print STDERR "detect_query response file for job $job_id not found\n" if $verbose;
    … …  
    136143if (-s $reg_list) {
    137144    my $command = "$dsreg --add $req_name --product $product --list $reg_list";
    138     $command .= " --copy --datapath $out_dir";
     145    $command .= " --copy --datapath $outdir";
    139146    $command .= " --type MOPS_DETECTABILITY_RESPONSE";
     147    $command .= " --ps0 $req_id";
    140148    $command .= " --dbname $dbname" if $dbname;
    141149
    … …  
    158166    my $verbose = shift;
    159167   
    160     my $command = "$pstamptool -updatereq -req_id $req_id -state stop";
    161     $command   .= " -fault $fault" if $fault;
     168    my $command = "$pstamptool -updatereq -req_id $req_id -set_state stop";
     169    $command   .= " -set_fault $fault" if $fault;
    162170    $command   .= " -dbname $dbname" if $dbname;
    163171    $command   .= " -dbserver $dbserver" if $dbserver;
  • branches/pap/pstamp/scripts/dqueryparse.pl

    r27578 r28003  
    22#
    33# parse a MOPS_DETCTABILITY_QUERY table and create a results file
    4 #
    5 # Note: this file is currently only a placeholder which creates a fake response file
    6 # and adds a completed job to the database
    74#
    85
    96use strict;
    107use warnings;
    11 
     8use Carp;
    129use Getopt::Long qw( GetOptions );
    1310use Pod::Usage qw( pod2usage );
    1411use IPC::Cmd 0.36 qw( can_run run );
    1512
     13use PS::IPP::PStamp::RequestFile qw( :standard );
     14use PS::IPP::PStamp::Job qw( :standard );
    1615use PS::IPP::Config qw($PS_EXIT_SUCCESS
    1716                       $PS_EXIT_UNKNOWN_ERROR
    … …  
    2625                       );
    2726
    28 my ($req_file, $req_id, $out_dir, $product, $mode, $dbname, $dbserver, $verbose, $save_temps);
    29 
     27my ($no_update, $imagedb, $label);
     28my ($req_file, $req_id, $outdir, $product, $mode, $dbname, $dbserver, $verbose, $save_temps);
     29my ($job_id,$rownum); # stuff from the post-update world
    3030#
    3131# parse args
    … …  
    3535        'file=s'          =>      \$req_file,
    3636        'req_id=s'        =>      \$req_id,
    37         'out_dir=s'       =>      \$out_dir,
     37        'job_id=s'        =>      \$job_id,
     38        'rownum=s'        =>      \$rownum,
     39        'outdir=s'       =>      \$outdir,
     40        'label=s'         =>      \$label,
    3841        'product=s'       =>      \$product,
    3942        'mode=s'          =>      \$mode,
    … …  
    4447) or pod2usage(2);
    4548
    46 my $err = "";
    47 
    48 if (!$req_file) {
    49     $err .= "--file is required\n";
    50 }
    51 if (!$req_id) {
    52     $err .= "--req_id is required\n";
    53 }
    54 if (!$out_dir) {
    55     $err .="--out_dir is required\n";
    56 }
    57 if (!$product) {
    58     $err .="--product is required\n";
    59 }
    60 
    61 
    62 die $err if ($err);
    63 
     49die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "queue_job");
     50die "--file or --job_id is required" if !$req_file;
     51
     52if ($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}
    6457my $missing_tools;
    6558my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools =1);
    66 my $fakedresponse = can_run('fakedresponse.pl') or (warn "Can't find fakedresponse.pl" and $missing_tools =1);
     59my $detectresponse = can_run('detectability_respond.pl') or
     60    (warn "Can't find detectability_respond.pl" and $missing_tools = 1);
    6761my $fields = can_run('fields') or (warn "Can't find fields" and $missing_tools =1);
    6862
    … …  
    7771}
    7872
     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.
     81if (!$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;
     86}
     87
    7988# get the query id and check the extname and version from the header
    80 my $fields_output;
     89my $fields_output; 
    8190{
    8291    my $command = "echo $req_file | $fields -x 0 EXTNAME EXTVER QUERY_ID";
    … …  
    8493        run(command => $command, verbose => $verbose);
    8594   
    86 #   fields doesn't return zero when it succeeds
    87 #    unless ($success) {
    88 #        print STDERR @$stderr_buf;
    89 #    }
    9095    $fields_output = join "", @$stdout_buf;
    9196}
    9297my (undef, $extname, $extver, $req_name) = split " ", $fields_output;
    9398
    94 die "$req_file is missing one of EXTNAME EXTVER or QUERY_ID"
     99my_die("$req_file is missing one of EXTNAME EXTVER or QUERY_ID", $PS_EXIT_PROG_ERROR)
    95100    if !(defined($extname) and defined($extver) and defined($req_name));
    96 
    97 die "$req_file has EXTNAME $extname not MOPS_DETECTABILITY_QUERY table"
    98                 if $extname ne         "MOPS_DETECTABILITY_QUERY";
    99 die "$req_file is version $extver expecting 1" if $extver ne 1;
    100 
    101 if (0) {
    102 $out_dir .= "/$req_name";
    103 }
    104 if (! -e $out_dir ) {
    105     mkdir $out_dir or die "cannot create output directory $out_dir";
    106 } elsif (! -d $out_dir ) {
    107     die "output fileset directory $out_dir exists but is not a directory";
    108 }
    109 
    110 #
    111 # XXX Eventually we will parse the file here, to look up the list of input images to be processed
    112 # and queue a job for each image.
    113 # The request file will be one of the arguments. Each job will look at all rows and create entries
    114 # in the response file the coordinates that overlap the image.
    115 #
    116 # In the meantime we don't parse the file here, pass it to the program fakedresponse.
    117 # It creates a response file with a line for each row in the request file
    118 
    119 my $response_file = "$out_dir/response.fits";
     101my_die("$req_file has EXTNAME $extname not MOPS_DETECTABILITY_QUERY table", $PS_EXIT_PROG_ERROR)
     102    if $extname ne "MOPS_DETECTABILITY_QUERY";
     103my_die("$req_file is version $extver expecting 1", $PS_EXIT_PROG_ERROR)
     104    if $extver ne 1;
     105
     106# Set up the workdir for this query.
     107if (! -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.
     115my $response_file = "$outdir/${req_name}.dresponse.${req_id}.fits";
    120116my $fault;
     117my $data_to_update = '';
    121118{
    122     my $command = "$fakedresponse --input $req_file --output $response_file --workdir $out_dir";
     119    my $command = "$detectresponse --input $req_file --output $response_file --workdir $outdir";
    123120    $command .= " --save-temps" if $save_temps;
    124121    $command .= " --verbose" if $verbose;
    … …  
    127124        run(command => $command, verbose => $verbose);
    128125    unless ($success) {
    129         warn("Unable to perform $command error code: $error_code");
    130     }
     126        warn("Warn! Unable to perform $command error code: $error_code");
     127    }
     128    # Use the fault code to see if we can regenerate the missing data.
    131129    $fault = $error_code >> 8;
    132 }
    133 
    134 my $job_id;
     130    if ($fault == $PSTAMP_NOT_AVAILABLE) {
     131        $data_to_update = (split /\n/, (join "", @$stdout_buf))[-1];   
     132    }   
     133}
     134
    135135my $result;
    136 {
    137     my $command = "$pstamptool -addjob -req_id $req_id -outputBase $out_dir";
    138     $command .= " -job_type detect_query -state stop -fault $fault";
     136# If we returned correctly with a valid response file, get a job ID
     137# for the completed work, and move the response to a standardized name.
     138if ($fault == 0) {
     139    my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir";
     140    $command .= " -job_type detect_query -state stop -fault 0";
    139141    $command .= " -rownum 1";
    140     $command .= " -dbname $dbname" if $dbname;
    141     $command .= " -dbserver $dbserver" if $dbserver;
    142 
    143     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    144         run(command => $command, verbose => $verbose);
    145 
     142
     143    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     144        run(command => $command, verbose => $verbose);
    146145    if ($success) {
    147146        $job_id = join "", @$stdout_buf;
    148147        chomp $job_id;
    149148        if ($job_id && -e $response_file) {
    150             rename $response_file, "$out_dir/response${job_id}.fits";
     149            rename $response_file, "$outdir/response${job_id}.fits";
    151150        }
    152151        $result = 0;
    … …  
    156155    }
    157156}
    158 
    159 
     157else {
     158    # Failed to run correctly, which means that we need to queue a job and flag data for updating.
     159    # Get the dependency id for the data we're requesting be updated.
     160    my $dep_id = queue_update_run($req_id,$job_id,$outdir,$label,$data_to_update);
     161
     162    # Link this request to a job and link that job to any dependency
     163    my $command = "$pstamptool -addjob -req_id $req_id -outputBase $outdir";
     164    $command .= " -job_type detect_query -state run -fault 0";
     165    $command .= " -rownum 1";
     166    $command .= " -dep_id $dep_id" if $dep_id;
     167
     168    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     169        run(command => $command, verbose => $verbose);
     170
     171    if ($success) {
     172        $job_id = join "", @$stdout_buf;
     173        chomp $job_id;
     174        if ($job_id && -e $response_file) {
     175            # We shouldn't have a response file at this stage.
     176            rename $response_file, "$outdir/response${job_id}.fits";
     177        }
     178        $result = 0;
     179    } else {
     180        warn("Unable to perform $command error code: $error_code");
     181        $result = $error_code >> 8;
     182    }
     183}
     184
     185# This does not set the request state to stop.  That will happen with the request_finish.pl script,
     186# which will notice that we've inserted the stopped job and decide we're finished. Easy enough.
    160187{
    161     my $command = "$pstamptool -updatereq -req_id $req_id -name $req_name -outProduct $product";
    162     $command .= " -fault $result" if $result;
    163     $command .= " -dbname $dbname" if $dbname;
    164     $command .= " -dbserver $dbserver" if $dbserver;
     188    my $command = "$pstamptool -updatereq -req_id $req_id -set_name $req_name -set_outProduct $product";
     189    $command .= " -set_fault $result" if $result;
    165190
    166191    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    167192        run(command => $command, verbose => $verbose);
    168193    unless ($success) {
    169         die "$command failed";
     194        my_die("$command failed",$PS_EXIT_UNKNOWN_ERROR);
    170195    }
    171196}
    172197 
    173198exit 0;
     199
     200
     201# If we have to queue an update run, do so and create a new dependent
     202sub queue_update_run {
     203    my ($req_id, $job_id, $outdir, $label, $data_to_update) = @_;
     204
     205    my ($state, $stage, $stage_id, $component, $need_magic, $imagedb) = split /\s+/, $data_to_update;
     206   
     207    if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) {
     208        # We should have received one of these states, so if not, signal that we have a problem.
     209        my_die("$stage $stage_id is in unexpected state $state", $PS_EXIT_PROG_ERROR);
     210    }
     211    my $dep_id;
     212    my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb -component $component ";
     213    $command .= " -outdir $outdir";
     214    $command .= " -need_magic" if $need_magic;
     215
     216    my $rlabel = "dq_ud_" . $label if $label;
     217    $command .= " -rlabel $rlabel" if $rlabel;
     218
     219    if (!$no_update) {
     220        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     221            run(command => $command, verbose => $verbose);
     222        unless ($success) {
     223            my_die("$command failed", $PS_EXIT_UNKNOWN_ERROR);
     224        }
     225        my $output = join "", @$stdout_buf;
     226        chomp $output;
     227        $dep_id = $output;
     228
     229        my_die("pstamptool -getdependent returned invalid dep_id", $PS_EXIT_PROG_ERROR) if !$dep_id;
     230    }
     231    else {
     232        print STDERR "skipping $command\n";
     233        $dep_id = 42;
     234    }
     235
     236    return($dep_id);
     237}
     238       
     239   
     240
     241sub my_die {
     242    my $msg = shift;
     243    my $fault = shift;
     244
     245    carp $msg;
     246
     247    # we don't fault the request here pstamp_parser_run.pl handles that if necessary
     248    exit $fault;
     249}
  • branches/pap/pstamp/scripts/pstamp_checkdependent.pl

    r27703 r28003  
    2121use Carp;
    2222
     23# XXX: put this in a module somewhere
     24my $IPP_DIFF_MODE_WARP_WARP   = 1;
     25my $IPP_DIFF_MODE_WARP_STACK  = 2;
     26my $IPP_DIFF_MODE_STACK_WARP  = 3;
     27my $IPP_DIFF_MODE_STACK_STACK = 4;
    2328
    2429my ($dep_id, $stage, $stage_id, $component, $imagedb, $rlabel, $need_magic);
    … …  
    3035    'stage_id=i'    =>  \$stage_id,
    3136    'component=s'   =>  \$component,
    32     'imagedb=s'     =>  \$imagedb,      # dbname for images
     37    'imagedb=s'     =>  \$imagedb,      # dbname for images.
    3338    'rlabel=s'      =>  \$rlabel,
    3439    'need_magic'    =>  \$need_magic,
    … …  
    4853my $warptool = can_run('warptool') or (warn "Can't find warptool" and $missing_tools = 1);
    4954my $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1);
     55my $stacktool = can_run('stacktool') or (warn "Can't find stacktool" and $missing_tools = 1);
    5056my $magicdstool = can_run('magicdstool') or (warn "Can't find magicdstool" and $missing_tools = 1);
    5157my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools = 1);
    … …  
    5561}
    5662
     63# Append imagedb to the ippTools
    5764$chiptool    .= " -dbname $imagedb";
    5865$warptool    .= " -dbname $imagedb";
    5966$difftool    .= " -dbname $imagedb";
     67$stacktool   .= " -dbname $imagedb";
    6068$magicdstool .= " -dbname $imagedb";
    61 
    6269
    6370my $ipprc = PS::IPP::Config->new();
    … …  
    6673    $dbserver =  metadataLookupStr($ipprc->{_siteConfig}, 'PS_DBSERVER');
    6774}
    68 
    6975
    7076
    … …  
    8692} else {
    8793    if ($stage eq "chip") {
    88         $cmd = "$chiptool -processedimfile -chip_id $stage_id -class_id $component";
     94        $cmd = "$chiptool -processedimfile -allfiles -chip_id $stage_id -class_id $component";
    8995    } elsif ($stage eq "warp") {
    9096        $cmd = "$warptool -warped -warp_id $stage_id -skycell_id $component";
    … …  
    96102}
    97103
    98 my $components = runToolAndParse($cmd, $verbose);
    99 
    100 my $n = scalar @$components;
    101 my_die("Unexpected number of components found $n", $PS_EXIT_PROG_ERROR) if ($n != 1);
     104my $it = runToolAndParseExpectOne($cmd, $verbose);
     105
     106my_die("no components found", $PS_EXIT_PROG_ERROR) if ( !$it);
    102107
    103108# Got "it"
    104 my $it = $components->[0];
    105 
     109
     110my $magic_ok = 0;
     111if ($stage eq 'diff') {
     112    if ($it->{diff_mode} == $IPP_DIFF_MODE_STACK_STACK) {
     113        # stack stack diffs don't need magic, but since the warps need to have the chips destreaked
     114        # in order to be processed se set need_magic in the database for all runs
     115        # Now the diffs themselves don't need to be destreaked so
     116        $magic_ok = 1;
     117    }
     118}
    106119my $status = 0;
    107120if (($it->{state} eq 'full') or ($it->{state} eq 'update') and ($whole_run or ($it->{data_state} eq 'full'))
    108         and (!$need_magic or $it->{magicked} > 0)) {
    109 
    110     # This Dependency is satisfied. all done
     121        and (!$need_magic or $magic_ok or $it->{magicked} > 0)) {
     122
     123    # This Dependency is satisfied. All done!
    111124    my $command = "$pstamptool -updatedependent -set_state full -dep_id $dep_id";
    112125    $command .= " -dbname $dbname" if $dbname;
    … …  
    125138        ($whole_run or ($it->{data_state} eq 'cleaned'))) {
    126139
     140    # Update has not been queued for this component yet. 
     141
    127142    # XXX: if $whole_run this is going to repeatedly call -setimfiletoupdate. This will be a no-op
    128143    # but is wasteful.
    … …  
    130145    # need to queue the updates
    131146    if ($stage eq 'chip') {
    132         # queue_update_chip takes an array so that queue_update_warp can pass a set of
    133         # chips to it
     147        # queue_update_chip takes an array so that queue_update_warp can pass it set of chips
    134148        my $chips = [$it];
    135149        $status = queue_update_chip($it->{chip_id}, $whole_run, $chips, $rlabel, $need_magic);
    … …  
    142156    }
    143157} else {
     158    # update for this component has been queued by hasn't completed yet or the state is an error state
     159    # XXX: in this state we aren't checking the dependents anymore. If something goes wrong this
     160    # will never complete. Consider calling the 'queue_update' functions again just to check. They are relatively cheap
     161
     162
    144163    print "${stage}Run $stage_id state is $it->{state} $component data_state is $it->{data_state}\n";
    145164
    146165    # detect states that cannot be updated and update the job state
    147     # XXX: we should be more assertive here and check for the specific states where we can continue
     166    # XXX: Perhaps I should be more assertive here and check for the specific states that we know
     167    # that we can continue.
     168
    148169    my $state = $it->{state};
    149170    my $job_fault = 0;
    150     if (($state =~ /scrub/) or ($state =~ /purge/)) {
     171
     172    # temporary hack to deal with data with old burntool tables. This check is now done by pstampparse.pl
     173    # so runs in this state should not get queued
     174    if ($stage eq 'chip') {
     175        my $burntool_state = $it->{burntool_state};
     176        if ($burntool_state and (abs($burntool_state) < 14)) {
     177            print STDERR "chip $it->{chip_id} $it->{class_id} has burntool_state $burntool_state. Not avaiable.\n";
     178            $job_fault = $PSTAMP_NOT_AVAILABLE;
     179        }
     180    }
     181    if ($state eq 'error_cleaned') {
     182        $job_fault = $PSTAMP_NOT_AVAILABLE;
     183    } elsif (($state =~ /scrub/) or ($state =~ /purge/)) {
    151184        # jobs must have changed state since depenency was made
    152185        print STDERR "Dependency cannot be satisfied\n";
    … …  
    156189        my_die ("Unexpected state for ${stage}Run $stage_id $state", $PS_EXIT_PROG_ERROR);
    157190    }
     191    if (!$job_fault and ($stage eq 'chip')) {
     192        # chip processing is done, start destreaking.
     193        $job_fault = queue_update_magicDSRun($stage, $stage_id, $rlabel, $need_magic, $it->{raw_magicked}, $it->{dsRun_state});
     194    }
    158195    if ($job_fault) {
    159196        faultJobs($state, $stage, $stage_id, $job_fault);
    … …  
    171208    my $need_magic = shift;
    172209
     210
    173211    my $dsRun_state;
    174212    my $raw_all_magicked = 1; # this gets cleared if any of the inputs aren't destreaked
    … …  
    178216            $raw_all_magicked &= ($chip->{raw_magicked} > 0);
    179217
    180             if ($chip->{data_state} ne 'update') {
     218            if ($chip->{state} =~ /error/) {
     219                faultJobs('stop', undef, undef, $PSTAMP_GONE);
     220            } elsif (($chip->{data_state} ne 'update') and ($chip->{data_state} ne 'full')) {
    181221                my $command = "$chiptool -setimfiletoupdate -chip_id $chip_id -class_id $chip->{class_id}";
    182222                $command .= " -set_label $rlabel" if $rlabel;
    … …  
    213253    }
    214254
     255    my $status = queue_update_magicDSRun('chip', $chip_id, $rlabel, $need_magic, $raw_all_magicked, $dsRun_state);
     256
     257    return $status;
     258}
     259
     260sub queue_update_warp {
     261    # check status of input chips. If state is not updatable set error code for job
     262
     263    # if chipProcessedImfile.state is cleaned call queue_update_chip
     264
     265    # need to code warptool -setskyfiletoupdate
     266    my $metadata = shift;
     267    my $whole_run = shift;  # if true queue entire run for update
     268    my $rlabel = shift;     # if defined a new label for the chipRun
     269    my $need_magic = shift;
     270
     271    my $raw_all_magicked = 1; # this gets cleared if any of the inputs aren't destreaked
     272
     273    my $warp_id = $metadata->{warp_id};
     274    my $state = $metadata->{state};
     275    if ($state =~ /error/) {
     276        print STDERR "warpRun $warp_id has state $state faulting jobs\n";
     277        faultJobs('stop', undef, undef, $PSTAMP_GONE);
     278        exit 0;
     279    }
     280
     281    if (!$whole_run) {
     282        my $skycell = $metadata;
     283        my $skycell_id = $skycell->{skycell_id};
     284
     285        my $command = "$warptool -scmap -warp_id $warp_id -skycell_id $skycell_id";
     286        my $data = runToolAndParse($command, $verbose);
     287        my_die("failed to find warpSkyCelllMap for warpRun $warp_id skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR)
     288            if !$data or scalar @$data == 0;
     289
     290        my $chips_ready = 1;
     291        my @chipsToUpdate;
     292        my $chip_id;
     293        foreach my $chip (@$data) {
     294            $chip_id = $chip->{chip_id};
     295            if (($chip->{data_state} ne 'full') or ($need_magic and ($chip->{magicked} <= 0))) {
     296                $chips_ready = 0;
     297                push @chipsToUpdate, $chip;
     298            } else {
     299                # this chip is good to go
     300            }
     301        }
     302
     303        if ($chips_ready) {
     304            # the reason we defer setting the warp to update is so that we can handle error conditions at previous
     305            # stages more easily.
     306            my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id -skycell_id $skycell->{skycell_id}";
     307            $command .= " -set_label $rlabel" if $rlabel;
     308
     309            if (!$no_update) {
     310                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     311                            run(command => $command, verbose => $verbose);
     312                unless ($success) {
     313                    my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
     314                }
     315            } else {
     316                print "skipping $command\n";
     317            }
     318        } elsif (scalar @chipsToUpdate > 0) {
     319            return queue_update_chip($chip_id, 0, \@chipsToUpdate, $rlabel, $need_magic);
     320        }
     321    } else {
     322        my $warpRun = $metadata;
     323        my $command = "$chiptool -listrun -chip_id $warpRun->{chip_id}";
     324        my $data = runToolAndParse($command, $verbose);
     325        my_die("failed to find chipRun $warpRun->{chip_id} for warpRun $warp_id", $PS_EXIT_UNKNOWN_ERROR)
     326            if !$data or scalar @$data != 1;
     327
     328        my $chipRun = $data->[0];
     329
     330        my $chipRunState = $chipRun->{state};
     331        if (($chipRunState =~ /purge/) or ($chipRunState =~ /scrub/)) {
     332            print STDERR "warpRun $warp_id depends on chipRun $chipRun->{chip_id} which is in state $chipRunState\n";
     333            faultJobs('stop', 'warp', $warp_id, $PSTAMP_GONE);
     334            return 0;
     335        }
     336        my $warpRunState = $warpRun->{state};
     337        if (($chipRunState eq 'full') and (! $need_magic or ($chipRun->{magicked} > 0)) and ($warpRunState eq 'cleaned')) {
     338            # The inputs and outputs are ready. Queue the warpRun for update.
     339
     340            # providing no -skycell_id arguments changes all skyfiles with data_state = 'cleaned' to 'update'
     341            my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id";
     342            $command .= " -set_label $rlabel" if $rlabel;
     343
     344            if (!$no_update) {
     345                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     346                            run(command => $command, verbose => $verbose);
     347                unless ($success) {
     348                    my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
     349                }
     350            } else {
     351                print "skipping $command\n";
     352            }
     353        } elsif ($chipRunState eq 'cleaned' or
     354            (($chipRun->{state} eq 'full') and ($need_magic and ($chipRun->{magicked} < 0) and ($chipRun->{dsRun_state} ne 'new')))) {
     355            my $data = [$chipRun];
     356            return queue_update_chip($chipRun->{chip_id}, 1, $data, $rlabel, $need_magic);
     357        }
     358    }
     359
     360    # return value may be the return status of script so zero is good
     361    return 0;
     362}
     363sub queue_update_diff {
     364    my $metadata = shift;
     365    my $whole_run = shift;  # if true queue entire run for update
     366    my $rlabel = shift;     # if defined a new label for the chipRun
     367    my $need_magic = shift;
     368
     369    my $diff_id   = $metadata->{diff_id};
     370    my $diff_mode = $metadata->{diff_mode};
     371    if (!$whole_run) {
     372        my $skycell = $metadata;
     373        my $skycell_id = $skycell->{skycell_id};
     374
     375        if ($diff_mode == $IPP_DIFF_MODE_WARP_STACK ) {
     376            # check the state of the template stack
     377            my $command = "$stacktool -sumskyfile -stack_id $skycell->{stack2}";
     378            my $stack = runToolAndParseExpectOne($command, $verbose);
     379            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack2}", $PS_EXIT_UNKNOWN_ERROR) if !$stack;
     380
     381            if ($stack->{state} ne 'full') {
     382                print STDERR "template stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
     383                # this faults all jobs depending on this dep_id
     384                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
     385                return $PSTAMP_GONE;
     386            }
     387
     388            # now check the warp
     389            $command = "$warptool -warped -warp_id $skycell->{warp1} -skycell_id $skycell_id";
     390            my $warp = runToolAndParseExpectOne($command, $verbose);
     391            my_die("failed to find warpSkyfile for warpRun $skycell->{warp1} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp;
     392
     393            if ($warp->{data_state} ne 'full') {
     394                return queue_update_warp($warp, 0, $rlabel, $need_magic);
     395            }
     396            # warps are ready fall through and queue the diff update
     397        } elsif ($diff_mode eq $IPP_DIFF_MODE_WARP_WARP) {
     398            my $command = "$warptool -warped -warp_id $skycell->{warp1} -skycell_id $skycell_id";
     399            my $warp1 = runToolAndParseExpectOne($command, $verbose);
     400            my_die("failed to find warpSkyfile for warpRun $skycell->{warp1} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp1;
     401
     402            my $warps_ready = 1;
     403            my $status = 0;
     404            if ($warp1->{data_state} ne 'full') {
     405                $warps_ready = 0;
     406                $status = queue_update_warp($warp1, 0, $rlabel, $need_magic);
     407                if ($status) {
     408                    return $status;
     409                }
     410            }
     411            $command = "$warptool -warped -warp_id $skycell->{warp2} -skycell_id $skycell_id";
     412            my $warp2 = runToolAndParseExpectOne($command, $verbose);
     413            my_die("failed to find warpSkyfile for warpRun $skycell->{warp2} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp2;
     414
     415            if ($warp2->{data_state} ne 'full') {
     416                $warps_ready = 0;
     417                $status = queue_update_warp($warp2, 0, $rlabel, $need_magic);
     418            }
     419
     420            if (!$warps_ready) {
     421                # don't queue the diff update yet
     422                return $status;
     423            }
     424
     425        } elsif ($diff_mode == $IPP_DIFF_MODE_STACK_STACK ) {
     426            # check the state of the input stack
     427            my $command = "$stacktool -sumskyfile -stack_id $skycell->{stack2}";
     428            my $stack1 = runToolAndParseExpectOne($command, $verbose);
     429            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack2}", $PS_EXIT_UNKNOWN_ERROR) if !$stack1;
     430
     431            if ($stack1->{state} ne 'full') {
     432                print STDERR "input stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
     433                # this faults all jobs depending on this dep_id
     434                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
     435                return $PSTAMP_GONE;
     436            }
     437            # check the state of the template stack
     438            $command = "$stacktool -sumskyfile -stack_id $skycell->{stack2}";
     439            my $stack2 = runToolAndParseExpectOne($command, $verbose);
     440            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack2}", $PS_EXIT_UNKNOWN_ERROR) if !$stack2;
     441
     442            if ($stack2->{state} ne 'full') {
     443                print STDERR "template stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
     444                # this faults all jobs depending on this dep_id
     445                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
     446                return $PSTAMP_GONE;
     447            }
     448
     449            # inputs are ready fall through and queue the diff update
     450        } elsif ($diff_mode == $IPP_DIFF_MODE_STACK_WARP ) {
     451            # check the state of the input stack
     452            my $command = "$stacktool -sumskyfile -stack_id $skycell->{stack1}";
     453            my $stack = runToolAndParseExpectOne($command, $verbose);
     454            my_die("failed to find stackSumSkyfile for stack_id $skycell->{stack1}", $PS_EXIT_UNKNOWN_ERROR) if !$stack;
     455
     456            if ($stack->{state} ne 'full') {
     457                print STDERR "input stack for diffRun $diff_id $skycell_id is not in full state faulting jobs\n";
     458                # this faults all jobs depending on this dep_id
     459                faultJobs('stop', 'diff', $diff_id, $PSTAMP_GONE);
     460                return $PSTAMP_GONE;
     461            }
     462
     463            # now check the template warp
     464            $command = "$warptool -warped -warp_id $skycell->{warp2} -skycell_id $skycell_id";
     465            my $warp = runToolAndParseExpectOne($command, $verbose);
     466            my_die("failed to find warpSkyfile for warpRun $skycell->{warp2} skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR) if !$warp;
     467
     468            if ($warp->{data_state} ne 'full') {
     469                return queue_update_warp($warp, 0, $rlabel, $need_magic);
     470            }
     471            # warps are ready fall through and queue the diff update
     472        } else {
     473            my_die("unexpected diff_mode found: $diff_mode", $PS_EXIT_PROG_ERROR);
     474        }
     475
     476        my $command = "$difftool -setskyfiletoupdate -diff_id $diff_id -skycell_id $skycell_id";
     477        $command .= " -set_label $rlabel" if $rlabel;
     478
     479        if (!$no_update) {
     480            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     481                        run(command => $command, verbose => $verbose);
     482            unless ($success) {
     483                my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
     484            }
     485        } else {
     486            print "skipping $command\n";
     487        }
     488    } else {
     489        # XXX todo whole_run
     490        return $PS_EXIT_PROG_ERROR;
     491    }
     492
     493    # return value is a unix style exit status so zero is good
     494    return 0;
     495}
     496
     497
     498# run a command that produces metadata output and parse the results into an array of objects
     499sub runToolAndParse {
     500    my $command = shift;
     501    my $verbose = shift;
     502
     503    my ($program) = split " ", $command;
     504    $program = basename($program);
     505
     506    print "Running $command\n" if !$verbose;
     507    my $start_tool = DateTime->now->mjd;
     508    # run the command and parse the output
     509    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     510                run(command => $command, verbose => $verbose);
     511    unless ($success) {
     512        print STDERR @$stderr_buf if !$verbose;
     513        return undef;
     514    }
     515
     516    my $now = DateTime->now->mjd;
     517    my $dtime_tool = (DateTime->now->mjd - $start_tool) * 86400.;
     518    print "Time to run $program: $dtime_tool\n";
     519
     520    my $buf = join "", @$stdout_buf;
     521    if (!$buf) {
     522        return undef;
     523    }
     524
     525    my $start_parse = DateTime->now->mjd;
     526
     527    my $mdcParser = PS::IPP::Metadata::Config->new;
     528    my $results = parse_md_fast($mdcParser, $buf)
     529        or my_die ("Unable to parse metadata config doc", $PS_EXIT_UNKNOWN_ERROR);
     530
     531    my $dtime_parse = (DateTime->now->mjd - $start_parse) * 86400.;
     532    print "Time to parse results from $program: $dtime_parse\n";
     533
     534    return $results;
     535}
     536
     537# run an command returning metadata where we expect 1 entry
     538sub runToolAndParseExpectOne {
     539    my $command = shift;
     540    my $verbose = shift;
     541
     542    my $data = runToolAndParse($command, $verbose);
     543
     544    if (!$data) {
     545        return undef;
     546    }
     547
     548    my $n = scalar @$data;
     549    if ($n > 1) {
     550        my_die("Unexpected number of components $n returned by $command", $PS_EXIT_PROG_ERROR);
     551    }
     552
     553    return $data->[0];
     554}
     555
     556# splits meta data config input stream into single units to work around the pathalogically
     557# slow parser. This is similar to and adapted from code in various ippScripts.
     558sub parse_md_fast {
     559    my $mdcParser = shift;
     560    my $input = shift;
     561    my $output = ();
     562
     563    my @whole = split /\n/, $input;
     564    my @single = ();
     565
     566    my $n;
     567    while ( ($n = @whole) > 0) {
     568        my $value = shift @whole;
     569        push @single, $value;
     570        if ($value =~ /^\s*END\s*$/) {
     571            push @single, "\n";
     572
     573            my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or
     574                print STDERR "Unable to parse metdata config doc" and return undef;
     575            push @$output, $list->[0];
     576
     577            @single = ();
     578        }
     579    }
     580    return $output;
     581}
     582
     583sub faultJobs {
     584    my ($state, $stage, $stage_id, $job_fault) = @_;
     585
     586    my $command = "$pstamptool -updatejob -set_state stop -set_fault $job_fault -dep_id $dep_id";
     587    $command .= " -dbname $dbname" if $dbname;
     588    $command .= " -dbserver $dbserver" if $dbserver;
     589    if (!$no_update) {
     590        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     591                    run(command => $command, verbose => $verbose);
     592        unless ($success) {
     593            my_die("failed to set pstampJob.fault for dep_id: $dep_id",
     594                $PS_EXIT_UNKNOWN_ERROR);
     595        }
     596    } else {
     597        print "skipping $command\n";
     598    }
     599}
     600
     601sub queue_update_magicDSRun {
     602    my $stage = shift;
     603    my $stage_id = shift;
     604    my $rlabel  = shift;
     605    my $need_magic = shift;
     606    my $input_magicked = shift;
     607    my $dsRun_state = shift;
     608
     609    # XXX: this code assumes that destreaking is handled at the chip stage
     610    my_die ("queue_update_magicDSRun only works for stage chip", $PS_EXIT_PROG_ERROR) if $stage ne 'chip';
     611
    215612    # if called from queue_update_warp dsRun_state is unknown. Go find it.
    216613    if (!$dsRun_state) {
    217         my $command = "$chiptool -listrun -chip_id $chip_id";
     614        my $command = "$chiptool -listrun -chip_id $stage_id";
    218615        my $data = runToolAndParse($command, $verbose);
    219616        my $chipRun = $data->[0];
    … …  
    222619
    223620    # if the input file is already magicked no need to queue destreaking for this chipRun
    224     if ($need_magic and !$raw_all_magicked) {
     621    if ($need_magic and !$input_magicked) {
    225622        if ($dsRun_state eq 'cleaned') {
    226623            my $command = "$magicdstool -updaterun -set_state new -stage $stage -stage_id $stage_id";
    … …  
    236633                print "skipping $command\n";
    237634            }
     635        } elsif ($dsRun_state eq 'failed_revert') {
     636            print "magicDSRun.state = $dsRun_state for chipRun $stage_id is in state failed_revert cannot update";
     637            faultJobs('stop', undef, undef, $PSTAMP_NOT_AVAILABLE);
    238638        } else {
    239639            print "magicDSRun.state = $dsRun_state for chipRun $stage_id";
    … …  
    242642        }
    243643    }
    244 
    245     # return value may be the return status of script so zero is good
    246644    return 0;
    247645}
    248646
    249 sub queue_update_warp {
    250     # check status of input chips. If state is not updatable set error code for job
    251 
    252     # if chipProcessedImfile.state is cleaned call queue_update_chip
    253 
    254     # need to code warptool -setskyfiletoupdate
    255     my $metadata = shift;
    256     my $whole_run = shift;  # if true queue entire run for update
    257     my $rlabel = shift;     # if defined a new label for the chipRun
    258     my $need_magic = shift;
    259 
    260     my $raw_all_magicked = 1; # this gets cleared if any of the inputs aren't destreaked
    261 
    262     my $warp_id = $metadata->{warp_id};
    263     if (!$whole_run) {
    264         my $skycell = $metadata;
    265         my $skycell_id = $skycell->{skycell_id};
    266 
    267         my $command = "$warptool -scmap -warp_id $warp_id -skycell_id $skycell_id";
    268         my $data = runToolAndParse($command, $verbose);
    269         my_die("failed to find warpSkyCelllMap for warpRun $warp_id skycell_id $skycell_id", $PS_EXIT_UNKNOWN_ERROR)
    270             if !$data or scalar @$data == 0;
    271 
    272         my $good_to_go = 1;
    273         my @chipsToUpdate;
    274         my $chip_id;
    275         foreach my $chip (@$data) {
    276             $chip_id = $chip->{chip_id};
    277             if (($chip->{data_state} ne 'full') or ($need_magic and ($chip->{magicked} <= 0))) {
    278                 $good_to_go = 0;
    279                 push @chipsToUpdate, $chip;
    280             } else {
    281                 # this chip is good to go
    282             }
    283         }
    284 
    285         if ($good_to_go) {
    286             my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id -skycell_id $skycell->{skycell_id}";
    287             $command .= " -set_label $rlabel" if $rlabel;
    288 
    289             if (!$no_update) {
    290                 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    291                             run(command => $command, verbose => $verbose);
    292                 unless ($success) {
    293                     my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
    294                 }
    295             } else {
    296                 print "skipping $command\n";
    297             }
    298         } elsif (scalar @chipsToUpdate > 0) {
    299             return queue_update_chip($chip_id, 0, \@chipsToUpdate, $rlabel, $need_magic);
    300         }
    301     } else {
    302         my $warpRun = $metadata;
    303         my $command = "$chiptool -listrun -chip_id $warpRun->{chip_id}";
    304         my $data = runToolAndParse($command, $verbose);
    305         my_die("failed to find chipRun $warpRun->{chip_id} for warpRun $warp_id", $PS_EXIT_UNKNOWN_ERROR)
    306             if !$data or scalar @$data != 1;
    307 
    308         my $chipRun = $data->[0];
    309 
    310         my $chipRunState = $chipRun->{state};
    311         if (($chipRunState =~ /purge/) or ($chipRunState =~ /scrub/)) {
    312             print STDERR "warpRun $warp_id depends on chipRun $chipRun->{chip_id} which is in state $chipRunState\n";
    313             faultJobs('stop', 'warp', $warp_id, $PSTAMP_GONE);
    314             return 0;
    315         }
    316         my $warpRunState = $warpRun->{state};
    317         if (($chipRunState eq 'full') and (! $need_magic or ($chipRun->{magicked} > 0)) and ($warpRunState eq 'cleaned')) {
    318             # The inputs and outputs are ready. Queue the warpRun for update.
    319 
    320             # providing no -skycell_id arguments changes all skyfiles with data_state = 'cleaned' to 'update'
    321             my $command = "$warptool -setskyfiletoupdate -warp_id $warp_id";
    322             $command .= " -set_label $rlabel" if $rlabel;
    323 
    324             if (!$no_update) {
    325                 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    326                             run(command => $command, verbose => $verbose);
    327                 unless ($success) {
    328                     my_die("failed to queue ${stage}Run $stage_id $component for update", $PS_EXIT_UNKNOWN_ERROR);
    329                 }
    330             } else {
    331                 print "skipping $command\n";
    332             }
    333         } elsif ($chipRunState eq 'cleaned' or
    334             (($chipRun->{state} eq 'full') and ($need_magic and ($chipRun->{magicked} < 0) and ($chipRun->{dsRun_state} ne 'new')))) {
    335             my $data = [$chipRun];
    336             return queue_update_chip($chipRun->{chip_id}, 1, $data, $rlabel, $need_magic);
    337         }
    338     }
    339 
    340     # return value may be the return status of script so zero is good
    341     return 0;
    342 }
    343 sub queue_update_diff {
    344     return 0;
    345 }
    346 
    347 
    348 # run a command that produces metadata output and parse the results into an array of objects
    349 sub runToolAndParse {
    350     my $command = shift;
    351     my $verbose = shift;
    352 
    353     my ($program) = split " ", $command;
    354     $program = basename($program);
    355 
    356     print "Running $command\n" if !$verbose;
    357     my $start_tool = DateTime->now->mjd;
    358     # run the command and parse the output
    359     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    360                 run(command => $command, verbose => $verbose);
    361     unless ($success) {
    362         print STDERR @$stderr_buf if !$verbose;
    363         return undef;
    364     }
    365 
    366     my $now = DateTime->now->mjd;
    367     my $dtime_tool = (DateTime->now->mjd - $start_tool) * 86400.;
    368     print "Time to run $program: $dtime_tool\n";
    369 
    370     my $buf = join "", @$stdout_buf;
    371     if (!$buf) {
    372         return undef;
    373     }
    374 
    375     my $start_parse = DateTime->now->mjd;
    376 
    377     my $mdcParser = PS::IPP::Metadata::Config->new;
    378     my $results = parse_md_fast($mdcParser, $buf)
    379         or my_die ("Unable to parse metadata config doc", $PS_EXIT_UNKNOWN_ERROR);
    380 
    381     my $dtime_parse = (DateTime->now->mjd - $start_parse) * 86400.;
    382     print "Time to parse results from $program: $dtime_parse\n";
    383 
    384     return $results;
    385 }
    386 
    387 # splits meta data config input stream into single units to work around the pathalogically
    388 # slow parser. This is similar to and adapted from code in various ippScripts.
    389 sub parse_md_fast {
    390     my $mdcParser = shift;
    391     my $input = shift;
    392     my $output = ();
    393 
    394     my @whole = split /\n/, $input;
    395     my @single = ();
    396 
    397     my $n;
    398     while ( ($n = @whole) > 0) {
    399         my $value = shift @whole;
    400         push @single, $value;
    401         if ($value =~ /^\s*END\s*$/) {
    402             push @single, "\n";
    403 
    404             my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or
    405                 print STDERR "Unable to parse metdata config doc" and return undef;
    406             push @$output, $list->[0];
    407 
    408             @single = ();
    409         }
    410     }
    411     return $output;
    412 }
    413 sub faultJobs {
    414     my ($state, $stage, $stage_id, $job_fault) = @_;
    415 
    416     my $command = "$pstamptool -updatejob -state stop -fault $job_fault -dep_id $dep_id";
     647sub my_die
     648{
     649    my $msg = shift;
     650    my $fault = shift;
     651    carp $msg;
     652
     653    my $command = "$pstamptool -updatedependent -set_fault $fault -dep_id $dep_id";
    417654    $command .= " -dbname $dbname" if $dbname;
    418655    $command .= " -dbserver $dbserver" if $dbserver;
    … …  
    421658                    run(command => $command, verbose => $verbose);
    422659        unless ($success) {
    423             my_die("failed to set pstamJob.fault for dep_id: $dep_id",
    424                 $PS_EXIT_UNKNOWN_ERROR);
     660            carp "$cmd failed";
    425661        }
    426662    } else {
    427663        print "skipping $command\n";
    428664    }
    429 }
    430 
    431 sub my_die
    432 {
    433     my $msg = shift;
    434     my $fault = shift;
    435 
    436     carp $msg;
    437 
    438     return $fault;
    439 }
     665
     666    exit $fault;
     667}
  • branches/pap/pstamp/scripts/pstamp_dorequest.pl

    r19221 r28003  
    106106{
    107107    ## TODO: what about request status
    108     my $command = "$pstamptool -updatereq -req_id $request_id -state stop";
     108    my $command = "$pstamptool -updatereq -req_id $request_id -set_state stop";
    109109    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    110110        run(command => $command, verbose => $verbosity);
  • branches/pap/pstamp/scripts/pstamp_finish.pl

    r27670 r28003  
    2525use PS::IPP::PStamp::Job qw( :standard );
    2626
    27 my ( $req_id, $req_name, $req_file, $out_dir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output);
     27my %imagedb_cache;
     28
     29my ( $req_id, $req_name, $req_file, $outdir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output);
    2830
    2931# the char to the right of the bar may be used as a single - alias for the longer name
    … …  
    3436           'req_file=s'     => \$req_file,
    3537           'product=s'      => \$product,
    36            'out_dir=s'      => \$out_dir,
     38           'outdir=s'       => \$outdir,
    3739           'dbname=s'       => \$dbname,
    3840           'dbserver=s'     => \$dbserver,
    … …  
    4446pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
    4547
    46 die "usage: --req_id id --req_name name --req_file file --product product --out_dir output_directory [--dbname dbname --verbose]\n"
    47     if !$req_id or !$req_name or !$req_file or !$product or !$out_dir;
     48die "usage: --req_id id --req_name name --req_file file --product product --outdir output_directory [--dbname dbname --verbose]\n"
     49    if !$req_id or !$req_name or !$req_file or !$product or !$outdir;
     50
     51die "outdir is NULL\n" if $outdir eq "NULL";
    4852
    4953my $ipprc = PS::IPP::Config->new(); # IPP Configuration
    5054if ($redirect_output) {
    51     my $logDest = "$out_dir/psfinish.$req_id.log";
     55    # XXX: what happens here if the directory does not exist? We check below
     56    my $logDest = "$outdir/psfinish.$req_id.log";
    5257    $ipprc->redirect_output($logDest);
    5358}
    … …  
    7075
    7176if ($product eq "NULL") {
     77    # nothing more to do
    7278    stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
    7379}
    74 
    75 my $outputDataStoreRoot = metadataLookupStr($ipprc->{_siteConfig}, 'DATA_STORE_ROOT');
    76 exit ($PS_EXIT_CONFIG_ERROR) unless defined $outputDataStoreRoot; # lookup failure outputs a message
    7780
    7881my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
    … …  
    8285    my $fileset = $req_name;
    8386
    84     print STDERR "product: $product  REQ_NAME: $req_name $out_dir\n" if $verbose;
    85 
    86     if (!-e $out_dir) {
     87    print STDERR "product: $product  REQ_NAME: $req_name $outdir\n" if $verbose;
     88
     89    if (!-e $outdir) {
    8790        # something must have gone wrong parsing the request
    88         print STDERR  "output directory $out_dir does not exist\n";
    89 
    90         if (!mkdir $out_dir) {
    91             print STDERR "cannot create output directory $out_dir";
     91        print STDERR  "output directory $outdir does not exist\n";
     92
     93        if (!mkdir $outdir) {
     94            print STDERR "cannot create output directory $outdir";
    9295            stop_request_and_exit($req_id, $PS_EXIT_UNKNOWN_ERROR);
    9396        }
    9497
    9598
    96     } elsif (! -d $out_dir ) {
     99    } elsif (! -d $outdir ) {
    97100        # XXX TODO: fault the request so we pstamp_finish doesn't keep trying to process the
    98101        # request
    99         print STDERR "output directory $out_dir exists but is not a directory";
     102        print STDERR "output directory $outdir exists but is not a directory";
    100103        stop_request_and_exit($req_id, $PS_EXIT_UNKNOWN_ERROR);
    101104    }
    … …  
    116119    }
    117120
    118     # at this point we need to find out what kind of request type it is and
    119     # split the processing depending on the request type
    120     # the only processing required for a detectabilty query is to build the output fileset.
    121 
    122     # the following is for a postage stamp request
    123 
    124     my ($rlf, $reglist_name) = tempfile ("$out_dir/reglist.XXXX", UNLINK => !$save_temps);
     121    # start building the list of files to be placed in the output fileset
     122    my ($rlf, $reglist_name) = tempfile ("$outdir/reglist.XXXX", UNLINK => !$save_temps);
     123
     124    # results file
    125125    print $rlf "results.fits|||table|\n";
    126     print $rlf "results.mdc|||txt|\n";
     126    # human readable representation of the results file
     127    print $rlf "results.mdc|||text|\n";
    127128
    128129    my $err_file = "parse_error.txt";
    129     if (-e "$out_dir/$err_file" ) {
     130    if (-e "$outdir/$err_file" ) {
    130131        print $rlf "$err_file|||text|\n";
    131132    }
    132133
    133     my ($tdf, $table_def_name) = tempfile ("$out_dir/tabledef.XXXX", UNLINK => !$save_temps);
    134 
     134    # The results table definition file
     135    my ($tdf, $table_def_name) = tempfile ("$outdir/tabledef.XXXX", UNLINK => !$save_temps);
    135136
    136137    # data for the header
    137138    print $tdf "$req_name|$req_id|\n";
     139
     140    # get the list of jobs generated for this request
    138141    my @jobs;
    139142    {
    … …  
    151154                print STDERR "Request $req_id produced no jobs.\n"
    152155            }
    153             # This should not happen. A fake job should be queued
     156            # This should not happen. A fake job should have been entered
    154157            stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
    155158        } else {
     159if (0) {
    156160            my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
    157161
    158162            my $jobs = parse_md_list($metadata);
     163}
     164            my $jobs = parse_md_fast($mdcParser, $output);
    159165
    160166            @jobs = @$jobs;
    … …  
    163169
    164170    my $exp_info;
    165     my $last_exp_id = -1;
    166171    foreach my $job (@jobs) {
    167172        my $job_id = $job->{job_id};
    … …  
    172177
    173178        if (($fault eq $PSTAMP_DUP_REQUEST) and ($req_name eq "NULL")) {
    174             # this request had a duplicate request name. We can't put the results
    175             # on the data store since the product name is already used
    176             # maybe we could be more clever about this and choose a fileset name
    177             stop_request_and_exit($req_id, $fault);
     179            # this request had a duplicate request name yet the parser didn't give
     180            # it an "ERROR style name.
     181            stop_request_and_exit($req_id, $PS_EXIT_PROG_ERROR);
    178182        }
    179183        my ($row, $req_info, $project) = get_request_info($rows, $rownum);
    … …  
    188192        }
    189193
    190         if ($exp_id ne $last_exp_id) {
     194        my $job_params = get_job_parameters($job);
     195        my $stage = "";
     196        if ($job_params) {
     197            $stage = $job_params->{stage};
     198        }
     199
     200        if ($stage ne 'stack') {
    191201            # get the metadata for the exposure (if any i.e. stack)
    192202            # returns an appropriate string if !$exp_id
    193             $exp_info = get_exposure_info($image_db, $exp_id);
    194             $last_exp_id = $exp_id;
     203            $exp_info = get_exposure_info($job_params, $image_db, $exp_id);
     204        } else {
     205            my $filter = $job_params->{filter};
     206            $filter = "0" if !$filter;
     207            $exp_info = "0|0|0|$filter|0|0";
    195208        }
    196209
    197210        if (($job_type eq "stamp") || ($job_type eq "get_image") || ($job_type eq "none")) {
    198             my $jreglist = "$out_dir/reglist$job_id";
     211            my $jreglist = "$outdir/reglist$job_id";
    199212            if (open JRL, "<$jreglist") {;
    200213                # process the reglist file to get the list of files produced by this job
    … …  
    213226                    # If not found check the PHU. If that doesn't work just set them to zero.
    214227                    # XXX do this more cleanly
    215                     my (undef, $ra_deg, $dec_deg) = split " ", `echo $out_dir/$img_name | fields -x 0 RA_DEG DEC_DEG`;
     228                    my (undef, $ra_deg, $dec_deg) = split " ", `echo $outdir/$img_name | fields -x 0 RA_DEG DEC_DEG`;
    216229                    if (!defined $ra_deg) {
    217                         (undef, $ra_deg, $dec_deg) = split " ", `echo $out_dir/$img_name | fields RA_DEG DEC_DEG`;
     230                        (undef, $ra_deg, $dec_deg) = split " ", `echo $outdir/$img_name | fields RA_DEG DEC_DEG`;
    218231                    }
    219232                    $ra_deg = 0.0 if (!$ra_deg);
    … …  
    246259    # make the results file
    247260    {
    248         my $command = "$pstamp_results --input $table_def_name --output $out_dir/results.fits";
     261        my $command = "$pstamp_results --input $table_def_name --output $outdir/results.fits";
    249262        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    250263            run(command => $command, verbose => $verbose);
    … …  
    254267        } else {
    255268            # dump a textual representation
    256             my $command = "$pstampdump $out_dir/results.fits > $out_dir/results.mdc";
     269            my $command = "$pstampdump $outdir/results.fits > $outdir/results.mdc";
    257270            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    258271                run(command => $command, verbose => $verbose);
    … …  
    266279        # register the fileset
    267280        my $command = "$dsreg --list $reglist_name --add $fileset --product $product --type PSRESULTS";
    268         $command .= " --link --datapath $out_dir --ps0 $req_id";
    269         $command .= " --dbname $dbname" if $dbname;
     281        $command .= " --link --datapath $outdir --ps0 $req_id";
     282# XXX: let dsreg and config handle resolving dbname and dbserver
     283#        $command .= " --dbname $dbname" if $dbname;
    270284
    271285        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    … …  
    280294    # set the request's state to stop
    281295    {
    282         my $command = "$pstamptool -updatereq -req_id $req_id -state stop -fault $request_fault";
     296        my $command = "$pstamptool -updatereq -req_id $req_id -set_state stop -set_fault $request_fault";
    283297        $command   .= " -dbname $dbname" if $dbname;
    284298        $command   .= " -dbserver $dbserver" if $dbserver;
    … …  
    296310    my $fault  = shift;
    297311
    298     my $command = "$pstamptool -updatereq -req_id $req_id -state stop -fault $fault";
     312    my $command = "$pstamptool -updatereq -req_id $req_id -set_state stop -set_fault $fault";
    299313    $command   .= " -dbname $dbname" if $dbname;
    300314    $command   .= " -dbserver $dbserver" if $dbserver;
    … …  
    333347    $data_group = "null" if !$data_group;
    334348
    335     # This is ugly, error prone and hard to change.
     349    # XXX: This is ugly, error prone and hard to change.
    336350    # Create a results file module and provide a list of the names (we have the data in the columns)
    337351    my $rowinfo = "$row->{PROJECT}|$row->{JOB_TYPE}|$row->{REQ_TYPE}|$row->{IMG_TYPE}|";
    … …  
    344358}
    345359
     360sub get_job_parameters {
     361    my $job = shift;
     362    if (!$job->{outputBase}) {
     363        print "get_job_parameters: $job->{job_id} has no outputBase\n";
     364        return undef;
     365    }
     366    my $params_file = $job->{outputBase} . '.mdc';
     367    if (! -e $params_file ) {
     368        print "get_job_parameters: $job->{job_id} has no parameters file\n";
     369        return undef;
     370    }
     371    open IN, "<$params_file" or die "unable to open $params_file";
     372    my $data = join "", (<IN>);
     373    close IN;
     374    if (! $data ) {
     375        print "get_job_parameters: parameters file is empty\n";
     376        return undef;
     377    }
     378    my $metadata = $mdcParser->parse($data) or die("Unable to parse metdata config doc");
     379
     380    # no need to use parse_md_fast here
     381    my $results = parse_md_list($metadata);
     382    if (scalar @$results != 1) {
     383        print STDERR "get_job_params: failed to parse_md_list\n";
     384        return undef;
     385    }
     386    return $results->[0];
     387}
     388
    346389sub get_exposure_info {
     390    my $job_params = shift;
    347391    my $image_db= shift;
    348392    my $exp_id = shift;
    349393
    350     if (!$exp_id or !$image_db) {
    351         # no exposure id just return zeros
    352         # XXX: we could put a value in for filter, but we don't have a good place to find it
    353 
    354         #"$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
    355         return "0|0|0|0|0|0";
    356     }
    357 
    358     my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
    359     if ($missing_tools) {
    360         warn("Can't find required tools.");
    361         exit ($PS_EXIT_CONFIG_ERROR);
    362     }
    363 
    364     my $command = "$regtool -processedexp -dbname $image_db -exp_id $exp_id";
    365 
    366     # run the tool and parse the output
    367     my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    368                 run(command => $command, verbose => $verbose);
    369     unless ($success) {
    370         # not sure if we should die here
    371         die "cannot get exposure information for $exp_id from image database $image_db";
    372     }
    373     my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
    374 
    375     my $output = join "", @$stdout_buf;
    376     if (!$output) {
    377         print STDERR "no output returned from $command\n" if $verbose;
    378         return undef;
    379     }
    380     my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
    381 
    382     my $exposures = parse_md_list($metadata);
    383     my $numExp = @$exposures;
    384 
    385     die "unexpected number of exposures $numExp found for exp_id: $exp_id in DB: $image_db" if $numExp != 1;
     394    my ($dateobs, $ra, $decl, $filter, $exp_time, $exp_name);
     395
     396    $dateobs  = $job_params->{dateobs};
     397    $ra       = $job_params->{ra};
     398    $decl     = $job_params->{decl};
     399    $filter   = $job_params->{filter};
     400    $exp_time = $job_params->{exp_time};
     401    $exp_name = $job_params->{exp_name};
     402
     403    unless (defined $dateobs and defined $ra and defined $decl and defined $filter and defined $exp_time and defined $exp_name) {
     404        # job params don't have all of the values that we need (most likely this is a diff stage job)
     405        # go look up the exposure if we have one
     406        if (!$exp_id or !$image_db) {
     407            # no exposure id just return zeros
     408            # XXX: we could put a value in for filter, but we don't have a good place to find it
     409
     410            #"$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
     411            return "0|0|0|0|0|0";
     412        }
     413
     414        my $exp;
     415        # get cache of exposures for this image_db
     416        my $exp_cache = $imagedb_cache{$image_db};
     417        if (defined $exp_cache) {
     418            $exp = $exp_cache->{$exp_id};
     419        }
     420
     421        unless (defined $exp) {
     422
     423            my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1);
     424            if ($missing_tools) {
     425                warn("Can't find required tools.");
     426                exit ($PS_EXIT_CONFIG_ERROR);
     427            }
     428
     429            my $command = "$regtool -processedexp -dbname $image_db -exp_id $exp_id";
     430
     431            # run the tool and parse the output
     432            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     433                        run(command => $command, verbose => $verbose);
     434            unless ($success) {
     435                # not sure if we should die here
     436                die "cannot get exposure information for $exp_id from image database $image_db";
     437            }
     438            my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
     439
     440            my $output = join "", @$stdout_buf;
     441            if (!$output) {
     442                print STDERR "no output returned from $command\n" if $verbose;
     443                return undef;
     444            }
     445if (0) {
     446            my $metadata = $mdcParser->parse($output) or die("Unable to parse metdata config doc");
     447
     448            my $exposures = parse_md_list($metadata);
     449}
     450            my $exposures = parse_md_fast($mdcParser, $output);
     451            my $numExp = @$exposures;
     452
     453            die "unexpected number of exposures $numExp found for exp_id: $exp_id in DB: $image_db" if $numExp != 1;
     454
     455            $exp = $exposures->[0];
     456
     457            unless (defined $exp_cache) {
     458                my %new_exp_cache;
     459                $exp_cache = \%new_exp_cache;
     460                $imagedb_cache{$image_db} = $exp_cache;
     461            }
     462            $exp_cache->{$exp_id} = $exp;
     463        } else {
     464            print "found $exp_id in cache\n";
     465        }
     466       
     467        #my $info = "$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
     468        $dateobs  = $exp->{dateobs};
     469        $ra       = $exp->{ra};
     470        $decl     = $exp->{decl};
     471        $filter   = $exp->{filter};
     472        $exp_time = $exp->{exp_time};
     473        $exp_name = $exp->{exp_name};
     474    }
     475
     476    die "failed to find exp_info for $exp_id" unless (defined $dateobs and defined $ra and defined $decl and defined $filter and defined $exp_time and defined $exp_name);
    386477   
    387     my $exp = $exposures->[0];
    388 
    389     #my $info = "$mjd_obs|$ra_obs|$dec_obs|$filter|$exp_time|$fpa_id";
    390 
    391478    use constant RADIANS_TO_DEGREES => 90. / atan2(1, 0);
    392     my $ra_deg   = $exp->{ra} * RADIANS_TO_DEGREES;
    393     my $decl_deg = $exp->{decl} * RADIANS_TO_DEGREES;
    394     my $mjd_obs = dateobs_to_mjd($exp->{dateobs});
    395 
    396     my $info = "$mjd_obs|$ra_deg|$decl_deg|$exp->{filter}|$exp->{exp_time}|$exp->{exp_name}";
     479    my $ra_deg   = $ra * RADIANS_TO_DEGREES;
     480    my $decl_deg = $decl * RADIANS_TO_DEGREES;
     481    my $mjd_obs = dateobs_to_mjd($dateobs);
     482
     483    my $info = "$mjd_obs|$ra_deg|$decl_deg|$filter|$exp_time|$exp_name";
    397484           
    398485    return $info;
  • branches/pap/pstamp/scripts/pstamp_get_image_job.pl

    r26215 r28003  
    8787}
    8888
    89 my $out_dir = dirname($output_base);
     89my $outdir = dirname($output_base);
    9090my $prefix = basename($output_base) . "_";
    9191my $results_file = $output_base . ".bundle_results";
    … …  
    102102    my $command = "$dist_bundle --camera $camera --stage $stage --stage_id $stage_id";
    103103    $command .= " --component $component";
    104     $command .= " --path_base $path_base --outdir $out_dir --results_file $results_file";
     104    $command .= " --path_base $path_base --outdir $outdir --results_file $results_file";
    105105    $command .= " --prefix $prefix";
    106106    $command .= " --magicked" if $magicked;
    … …  
    139139}
    140140
    141 my $reglist = "$out_dir/reglist$job_id";
     141my $reglist = "$outdir/reglist$job_id";
    142142if (! open(REGLIST, ">$reglist") ) {
    143143    my_die("failed to open registration list: $reglist", $PS_EXIT_UNKNOWN_ERROR);
  • branches/pap/pstamp/scripts/pstamp_job_run.pl

    r27577 r28003  
    7474my $ppstamp    = can_run('ppstamp') or (warn "Can't find ppstamp" and $missing_tools = 1);
    7575my $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);
     76my $dqueryparse = can_run('dqueryparse.pl') or (warn "Can't find dqueryparse.pl" and $missing_tools = 1);
    7677
    7778if ($missing_tools) {
    … …  
    8384my $jobStatus;
    8485if ($jobType eq "stamp") {
    85     my $argslist = "$outputBase.args";
    86     open ARGSLIST, "<$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
    87     my $argString = <ARGSLIST>;
    88     close ARGSLIST;
    89     chomp $argString;
     86    my $params = read_params_file($outputBase);
     87
     88    my $argString;
     89    $argString = $params->{job_args};
    9090
    9191    # XXX: should we do any other sanity checking?
    92     my_die("arglist file $argslist is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
     92    my_die("argument list is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
     93
     94    # XXX: remove -astrom from argString and add it here
     95
     96    $argString .= " -file $params->{image}";
     97    $argString .= " -mask $params->{mask}";
     98    if ($options & $PSTAMP_SELECT_VARIANCE) {
     99        $argString .= " -variance $params->{weight}";
     100    }
    93101
    94102    my $command = "$ppstamp $outputBase $argString";
    … …  
    119127        my %extensions = ( $PSTAMP_SELECT_IMAGE  => "fits",
    120128                           $PSTAMP_SELECT_MASK   => "mk.fits",
    121                            $PSTAMP_SELECT_WEIGHT => "wt.fits");
    122 
    123         my $output_mask = $options & ($PSTAMP_SELECT_IMAGE | $PSTAMP_SELECT_MASK | $PSTAMP_SELECT_WEIGHT);
     129                           $PSTAMP_SELECT_VARIANCE => "wt.fits");
     130
     131        my $output_mask = $options & ($PSTAMP_SELECT_IMAGE | $PSTAMP_SELECT_MASK | $PSTAMP_SELECT_VARIANCE);
    124132
    125133        foreach my $key (keys (%extensions)) {
    … …  
    139147        }
    140148
    141         get_other_outputs($F, $outputBase, $options);
     149        get_other_outputs($F, $outputBase, $options, $params);
    142150
    143151        close $F;
    … …  
    165173    }
    166174} elsif ($jobType eq "detect_query") {
    167     my_die("detect_query jobs not supported yet", $job_id,$PS_EXIT_CONFIG_ERROR);
     175    # detect_query jobs are basically holders to note that we need a file updated before we can continue.
     176    # Load the argument list that dqueryparse should have created the first time it ran, so we know how to
     177    # run it again the same way.
     178    my $argslist = "$outputBase/parse.args";
     179    open ARGSLIST, "<$argslist" or my_die("failed to open argslist file $argslist", $job_id, $PS_EXIT_UNKNOWN_ERROR);
     180    my $argString = <ARGSLIST>;
     181    close ARGSLIST;
     182    chomp $argString;
     183
     184    # XXX: should we do any other sanity checking?
     185    my_die("arglist file $argslist is empty", $job_id, $PS_EXIT_DATA_ERROR) if !$argString;
     186
     187    my $command = "$dqueryparse --job_id $job_id $argString";
     188    $command .= " --dbname $dbname" if $dbname;
     189    $command .= " --dbserver $dbserver" if $dbserver;
     190    $command .= " --verbose" if $verbose;
     191    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     192        run(command => $command, verbose => $verbose);
     193
     194    # Although dqueryparse can potentially force more updates (and more jobs), it should still return success.
     195    if ($success) {
     196        $jobStatus = $PS_EXIT_SUCCESS;
     197    } else {
     198        $jobStatus = $error_code >> 8;
     199        my_die("dqueryparse.pl failed with error code: $jobStatus", $job_id, $jobStatus);
     200    }
    168201} else {
    169202    my_die("unknown jobType $jobType found", $job_id, $PS_EXIT_PROG_ERROR);
    … …  
    172205# mark the job stopped in the database
    173206{
    174     my $command = "$pstamptool -updatejob -job_id $job_id -state stop";
    175     $command .= " -fault $jobStatus" if $jobStatus;
     207    my $command = "$pstamptool -updatejob -job_id $job_id -set_state stop";
     208    $command .= " -set_fault $jobStatus" if $jobStatus;
    176209    $command .= " -dbname $dbname" if $dbname;
    177210    $command .= " -dbserver $dbserver" if $dbserver;
    … …  
    212245    my $output_base = shift;
    213246    my $options = shift;
     247    my $params = shift;
    214248
    215249    if ($options & ( $PSTAMP_SELECT_CMF | $PSTAMP_SELECT_PSF | $PSTAMP_SELECT_BACKMDL)) {
    216         my $comp = read_params_file($output_base);
    217 
    218         my $stage = $comp->{stage};
     250        if (!$params) {
     251            $params = read_params_file($output_base);
     252        }
     253
     254        my $stage = $params->{stage};
    219255
    220256        # raw files don't have any other data products
    … …  
    225261        # detected in pstampparse so that the user can be notified with
    226262        # a message in parse_error.txt ("warp do not have a background model")
    227         my $cmf_file = $comp->{cmf} if ($options & $PSTAMP_SELECT_CMF);
    228         my $psf_file = $comp->{psf} if ($options & $PSTAMP_SELECT_PSF);
    229         my $backmdl_file = $comp->{backmdl} if ($options & $PSTAMP_SELECT_BACKMDL);
    230         my $pattern_file = $comp->{pattern} if ($options & $PSTAMP_SELECT_BACKMDL);
     263        my $cmf_file = $params->{cmf} if ($options & $PSTAMP_SELECT_CMF);
     264        my $psf_file = $params->{psf} if ($options & $PSTAMP_SELECT_PSF);
     265        my $backmdl_file = $params->{backmdl} if ($options & $PSTAMP_SELECT_BACKMDL);
     266        my $pattern_file = $params->{pattern} if ($options & $PSTAMP_SELECT_BACKMDL);
    231267
    232268        my $outdir = dirname($output_base);
    … …  
    250286            copy_and_register_file($f, $backmdl_file, $outdir, $prefix);
    251287        }
    252         if (0) {
     288       if (0) {
    253289        # don't enable this yet
    254290        if ($pattern_file) {
    … …  
    256292            copy_and_register_file($f, $pattern_file, $outdir, $prefix);
    257293        }
    258         }
     294       }
    259295    }
    260296}
    … …  
    317353        my $command = "$pstamptool -updatejob";
    318354        $command .= " -job_id $job_id";
    319         $command .= " -fault $exit_code";
     355        $command .= " -set_fault $exit_code";
    320356        # XXX: fix pstamptool to not require -state when -fault with nonzero value is provided
    321         $command .= " -state run";
     357        $command .= " -set_state run";
    322358        $command .= " -dbname $dbname" if defined $dbname;
    323359        $command .= " -dbserver $dbserver" if defined $dbserver;
  • branches/pap/pstamp/scripts/pstamp_parser_run.pl

    r26151 r28003  
    2828my $redirect_output;
    2929my $product;
     30my $outdir;
     31my $label;
    3032my $verbose;
    3133my $dbname;
    … …  
    3638    'uri=s'             =>  \$uri,
    3739    'product=s'         =>  \$product,
     40    'outdir=s'          =>  \$outdir,
     41    'label=s'           =>  \$label,
    3842    'redirect-output'   =>  \$redirect_output,
    3943    'verbose'           =>  \$verbose,
    … …  
    7983}
    8084
    81 # workdir is where all of the files generated for this request are placed
    82 # NOTE: this location needs to be kept in sync with the web interface ( request.php )
    83 my $datestr = strftime "%Y%m%d", gmtime;
    84 my $datedir = "$pstamp_workdir/$datestr";
    85 if (! -e $datedir ) {
    86     mkdir $datedir or my_die( "failed to create working directory $datedir for request id $req_id", $req_id,
     85if (!$outdir or ($outdir eq "NULL")) {
     86    # outdir is where all of the files generated for this request are placed
     87    # NOTE: this location needs to be kept in sync with the web interface ( request.php )
     88    my $datestr = strftime "%Y%m%d", gmtime;
     89    my $datedir = "$pstamp_workdir/$datestr";
     90    if (! -e $datedir ) {
     91        mkdir $datedir or my_die( "failed to create working directory $datedir for request id $req_id", $req_id,
     92            $PS_EXIT_CONFIG_ERROR);
     93    }
     94
     95    $outdir = "$datedir/$req_id";
     96}
     97
     98if (! -e $outdir ) {
     99    mkdir $outdir or my_die("failed to create working directory $outdir for request id $req_id", $req_id,
    87100        $PS_EXIT_CONFIG_ERROR);
    88101}
    89 
    90 my $workdir = "$datedir/$req_id";
    91 if (! -e $workdir ) {
    92     mkdir $workdir or my_die("failed to create working directory $workdir for request id $req_id", $req_id,
    93         $PS_EXIT_CONFIG_ERROR);
    94 }
     102   
    95103
    96104if ($redirect_output) {
    97     my $logDest = "$workdir/psparse.$req_id.log";
     105    my $logDest = "$outdir/psparse.$req_id.log";
    98106    $ipprc->redirect_output($logDest);
    99107}
    … …  
    106114
    107115my $fn = basename($uri);
    108 my $new_uri = "$workdir/$fn";
     116my $new_uri = "$outdir/$fn";
    109117if ($uri =~ /^http:/) {
    110118    # if the uri is an http uri download the file
    … …  
    116124    }
    117125} elsif ($uri ne $new_uri) {
    118     # put a link to the file into the workdir
     126    # copy the request file into outdir
    119127    if (-e $new_uri) {
     128        # file exists already delete it incase the previous copy is bogus
    120129        unlink $new_uri or my_die("failed to unlink $new_uri", $req_id, $PS_EXIT_UNKNOWN_ERROR);
    121130    }
    122131    if (! copy $uri, $new_uri) {
    123         my_die ("failed to copy request file $uri to workdir $workdir", $req_id, $PS_EXIT_UNKNOWN_ERROR);
     132        my_die ("failed to copy request file $uri to workdir $outdir", $req_id, $PS_EXIT_UNKNOWN_ERROR);
    124133    }
    125134}
    … …  
    146155        if ($request_type eq "PS1_PS_REQUEST") {
    147156            $reqType = 'pstamp';
    148             $parse_cmd = $pstampparse;
     157            $parse_cmd = "$pstampparse";
     158            $parse_cmd .= " --label $label" if $label;
    149159        } elsif ($request_type eq "MOPS_DETECTABILITY_QUERY") {
    150160            $reqType = 'dquery';
    151             $parse_cmd = $dqueryparse;
     161            $parse_cmd = "$dqueryparse";
     162            $parse_cmd .= " --label $label" if $label;
    152163        } else {
    153164            print STDERR "Unknown request type $request_type found in $uri";
    … …  
    169180    # that they sent us a request file that we don't understand
    170181
    171     my $command = "$pstamptool -updatereq -req_id $req_id -state run";
    172     $command   .= " -reqType unknown";
    173     $command   .= " -fault $PS_EXIT_DATA_ERROR";
     182    my $command = "$pstamptool -updatereq -req_id $req_id -set_state run";
     183    $command   .= " -set_reqType unknown";
     184    $command   .= " -set_fault $PS_EXIT_DATA_ERROR";
    174185    $command   .= " -dbname $dbname" if $dbname;
    175186    $command   .= " -dbserver $dbserver" if $dbserver;
    … …  
    182193}
    183194
    184 $parse_cmd .= " --mode queue_job --req_id $req_id --product $product --out_dir $workdir --file $uri";
     195$parse_cmd .= " --mode queue_job --req_id $req_id --product $product --outdir $outdir --file $uri";
    185196$parse_cmd .= " --dbname $dbname" if $dbname;
    186197$parse_cmd .= " --dbserver $dbserver" if $dbserver;
    … …  
    190201my $fault;
    191202{
    192     my $error_file_name = "$workdir/parse_error.txt";
     203    my $error_file_name = "$outdir/parse_error.txt";
    193204    # get rid of any error file from previous attempt to parse this request
    194205    unlink $error_file_name if (-e $error_file_name);
    … …  
    215226    unless ($success) {
    216227        $fault = $error_code >> 8;
    217         $newState = "stop";
     228#        $newState = "stop";
    218229    }
    219230}
    … …  
    223234#
    224235{
    225     my $command = "$pstamptool -updatereq -req_id $req_id -state $newState";
    226     $command   .= " -reqType $reqType" if $reqType;
    227     $command   .= " -uri $new_uri" if $new_uri;
    228     $command   .= " -fault $fault" if $fault;
     236    my $command = "$pstamptool -updatereq -req_id $req_id -set_state $newState";
     237    $command   .= " -set_outdir $outdir";
     238    $command   .= " -set_reqType $reqType" if $reqType;
     239    $command   .= " -set_uri $new_uri" if $new_uri;
     240    $command   .= " -set_fault $fault" if $fault;
    229241    $command   .= " -dbname $dbname" if $dbname;
    230242    $command   .= " -dbserver $dbserver" if $dbserver;
    … …  
    265277    carp($msg);
    266278
    267     my $command = "$pstamptool -updatereq -req_id $req_id  -fault $fault";
     279    my $command = "$pstamptool -updatereq -req_id $req_id  -set_fault $fault";
    268280    $command   .= " -dbname $dbname" if $dbname;
    269281    $command   .= " -dbserver $dbserver" if $dbserver;
  • branches/pap/pstamp/scripts/pstamp_request_file

    r26289 r28003  
    187187        for (my $i = 0; $i < scalar @colNames; $i++) {
    188188            my $writeType = $colWriteType[$i];
    189             $outFits->write_col( $writeType, $i + 1, 1, 1, $numRows, $colData->[$i], $status );
     189            my $data = $colData->[$i];
     190            if ($writeType == TULONG) {
     191                die "invalid integer data found in column $i\n" unless validIntegers($data);
     192            } elsif ($writeType == TDOUBLE) {
     193                die "invalid numeric data found in column $i\n" unless validNumbers($data);
     194            }
     195            $outFits->write_col( $writeType, $i + 1, 1, 1, $numRows, $data, $status );
    190196            check_fitsio( $status );
    191197        }
    … …  
    312318}
    313319
     320sub checkValid {
     321    my $aref = shift;
     322    my $float = shift;
     323
     324    return 0 if !defined $aref;
     325
     326    my $valid = 0;
     327    my $row = 0;
     328    foreach my $val (@$aref) {
     329        $row++;
     330        if ($float) {
     331            if (!($val =~  /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)) {
     332                $valid = 0;
     333                print STDERR "Error on row $row: '$val' is not a valid number\n";
     334                last;
     335            }
     336        } else {
     337            if ($val =~ /\D/) {
     338                $valid = 0;
     339                print STDERR "Error on row $row: '$val' is not a valid integer\n";
     340                last;
     341            }
     342        }
     343        $valid = 1;
     344    }
     345
     346    return $valid;
     347}
     348sub validIntegers {
     349    return checkValid(@_, 0);
     350}
     351
     352sub validNumbers
     353{
     354    return checkValid(@_, 1);
     355}
     356
     357
    314358sub printhelp
    315359{
  • branches/pap/pstamp/scripts/pstampparse.pl

    r27524 r28003  
    1717use Carp;
    1818use POSIX;
     19use Time::HiRes qw(gettimeofday);
    1920
    2021my $verbose;
    … …  
    2425my $request_file_name;
    2526my $mode = "list_uri";
    26 my $out_dir;
     27my $outdir;
    2728my $product;
     29my $label;
    2830my $save_temps;
    2931my $no_update;
    … …  
    3234    'file=s'    =>  \$request_file_name,
    3335    'req_id=s'  =>  \$req_id,
    34     'out_dir=s' =>  \$out_dir,
     36    'outdir=s'  =>  \$outdir,
    3537    'product=s' =>  \$product,
     38    'label=s'   =>  \$label,
    3639    'mode=s'    =>  \$mode,
    3740    'dbname=s'  =>  \$dbname,
    … …  
    4245);
    4346
    44 die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "list_job") or ($mode eq "queue_job");
     47die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "queue_job");
    4548die "--file is required"     if !defined($request_file_name);
    4649
    4750if ($mode ne "list_uri") {
    4851    die "req_id is required"   if !$req_id;
    49     die "out_dir is required"  if !$out_dir;
     52    die "outdir is required"  if !$outdir;
    5053    die "product is required"  if !$product;
    5154}
    … …  
    6467my $pstamptool  = can_run('pstamptool')  or (warn "Can't find pstamptool"  and $missing_tools = 1);
    6568my $pstampdump  = can_run('pstampdump') or (warn "Can't find pstampdump" and $missing_tools = 1);
    66 my $dvoImagesAtCoords  = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" and $missing_tools = 1);
    6769my $fields  = can_run('fields') or (warn "Can't find fields" and $missing_tools = 1);
    6870
    … …  
    127129    # update the database with the request name. This will be used as the
    128130    # the output data store's product name
    129     my $command = "$pstamptool -updatereq -req_id $req_id  -name $req_name";
    130     $command .= " -outProduct $product";
     131    my $command = "$pstamptool -updatereq -req_id $req_id  -set_name $req_name";
     132    $command .= " -set_outProduct $product";
    131133    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    132134        run(command => $command, verbose => $verbose);
    … …  
    145147my $rows;
    146148{
     149    my $start_request_file = gettimeofday();
    147150    my $command = "$pstampdump $request_file_name";
    148151    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    … …  
    152155    }
    153156    if (@$stdout_buf) {
    154         my $table =  $mdcParser->parse(join "", @$stdout_buf) or
    155             my_die("Unable to parse metdata config doc", $PS_EXIT_UNKNOWN_ERROR);
    156         $rows = parse_md_list($table);
    157     }
    158 
    159 }
    160 
     157        $rows = parse_md_fast($mdcParser, join "", @$stdout_buf);
     158    }
     159    my $dtime_request_file = gettimeofday() - $start_request_file;
     160    print "Time to read and parse request file: $dtime_request_file\n";
     161
     162}
     163
     164#
     165# Loop over rows in the request file collecting consecutive rows that have the "same images of interest"
     166# in the sense that their selection parameters will yield the same "Runs".
     167# Process the groups of rows together to reduce lookup time and to potentially make multiple
     168# stamps from the same ppstamp process.
     169#
    161170my @rowList;
    162171my $num_jobs = 0;
    … …  
    165174my $need_magic;
    166175foreach my $row (@$rows) {
    167     # XXX: TODO: sanity check all parameters
    168 
    169     # If we encounter an error for a particular row add a job with the proper fault code.
    170     # If we encounter an error in this loop we shouldn't really just die.
    171     # We only do that now in the case of I/O or DB errors or the like.
    172 
    173     my $rownum   = $row->{ROWNUM};
    174     my $job_type = $row->{JOB_TYPE};
    175    
    176     # parameters that select the images of interest
    177     my $project  = $row->{PROJECT};
    178 
    179     # note: resolve_project avoids running pstamptool every time by remembering the
    180     # last project resolved
    181     my $proj_hash = resolve_project($ipprc, $project, $dbname, $dbserver);
    182     if (!$proj_hash) {
    183         print STDERR "project $project not found\n"  if $verbose;
    184         insertFakeJobForRow($row, 1, $PSTAMP_UNKNOWN_PRODUCT);
     176    # santiy check the paramaters
     177    if (!checkRow($row)) {
     178        # when it enconters an error checkRow adds a fake job with an appropriate error code to the database
    185179        $num_jobs++;
    186180        next;
    187181    }
     182    # initialize counter for "job number"
     183    $row->{job_num} = 0;
     184    $row->{error_code} = 0;
     185
     186    if (scalar @rowList == 0) {
     187        push @rowList, $row;
     188        next;
     189    }
     190
     191    my $firstRow = $rowList[0];
     192    if (same_images_of_interest($firstRow, $row)) {
     193        # add this row to the list and move on
     194        push @rowList, $row;
     195        next;
     196    }
     197
     198    # the images of interest for this new row doesn't match the list.
     199    # process the list ...
     200    $num_jobs += processRows(\@rowList);
     201
     202    # and reset the list to contain just the new row
     203    @rowList = ($row);
     204}
     205
     206# out of rows process the list
     207if (scalar @rowList > 0) {
     208    $num_jobs += processRows(\@rowList);
     209}
     210
     211if (($mode eq "queue_job") and ($num_jobs eq 0)) {
     212    print STDERR "no jobs created for $req_name\n" if $verbose;
     213    insertFakeJobForRow(undef, 0, $PSTAMP_INVALID_REQUEST);
     214}
     215
     216exit 0;
     217
     218sub checkRow {
     219       
     220    my $row = shift;
     221
     222    # If we encounter an error for a particular row add a job with the proper fault code.
     223
     224    my $rownum   = $row->{ROWNUM};
     225    if (!validID($rownum)) {
     226        print STDERR "$rownum is not a valid ROWNUM\n";
     227        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     228        return 0;
     229    }
     230    my $job_type = $row->{JOB_TYPE};
     231    if (($job_type ne "stamp") and ($job_type ne "get_image")) {
     232        print STDERR "$job_type is not a valid JOB_TYPE\n";
     233        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     234        return 0;
     235    }
     236   
    188237    my $req_type = $row->{REQ_TYPE};
    189     $stage       = $row->{IMG_TYPE};
    190     my $id      = $row->{ID};
     238    if (($req_type ne "byid") and ($req_type ne "bycoord") and ($req_type ne "byexp") and
     239        ($req_type ne "byskycell") and ($req_type ne "bydiff")) {
     240        print STDERR "$req_type is not a valid REQ_TYPE\n";
     241        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     242        return 0;
     243    }
     244    if ($job_type eq 'get_image') {
     245        unless ($req_type eq 'byid' or $req_type eq 'byexp') {
     246            print STDERR "REQ_TYPE must be 'byid' or 'byexp' for JOB_TYPE 'get_image'\n";
     247            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     248            return 0;
     249        }
     250    }
     251
     252
    191253    my $component = $row->{COMPONENT};
    192     my $tess_id = $row->{TESS_ID};
     254    if (!defined $component or (lc($component) eq "null") or (lc($component) eq "all")) {
     255        if ($job_type eq 'get_image') {
     256            $row->{COMPONENT} = 'all';
     257        } else {
     258            $row->{COMPONENT} = $component = "";
     259        }
     260    }
     261    $row->{TESS_ID} = "" if !defined $row->{TESS_ID};
    193262
    194263    my $filter  = $row->{REQFILT};
    … …  
    196265        if (length($filter) == 1) {
    197266            # allow single character filter cuts to work
    198             $filter .= '%';
     267            $row->{REQFILT} .= '%';
    199268        }
    200269    }
    201270    my $mjd_min = $row->{MJD_MIN};
     271    if (defined($mjd_min) and !validNumber($mjd_min)) {
     272        print STDERR "$mjd_min is not a valid MJD_MIN\n";
     273        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     274        return 0;
     275    }
    202276    my $mjd_max = $row->{MJD_MAX};
     277    if (defined($mjd_max) and !validNumber($mjd_max)) {
     278        print STDERR "$mjd_max is not a valid MJD_MAX\n";
     279        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     280        return 0;
     281    }
    203282    my $data_group = $row->{DATA_GROUP};
    204283    if (!defined $data_group) {
    … …  
    209288    }
    210289       
    211     my $x       = $row->{CENTER_X};
    212     my $y       = $row->{CENTER_Y};
    213 
    214     # XXX things don't work if bit zero of option mask is not set;
     290    # req_finish doesn't work if bit zero of option mask is not set;
    215291    $row->{OPTION_MASK} |= 1;
     292
    216293    my $option_mask= $row->{OPTION_MASK};
    217294    my $inverse = ($option_mask & $PSTAMP_SELECT_INVERSE) ? 1 : 0;
    … …  
    222299    my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
    223300
    224     my $search_component = (!defined($component) or ($component eq "null")) ? "" : $component;
    225    
    226     if (!$skycenter and !$search_component) {
    227         print STDERR "COMPONENT must be specified for pixel coordinate ROI center\n" if $verbose;
     301    if (!$skycenter and !$component) {
     302        print STDERR "COMPONENT must be specified for pixel coordinate ROI center\n";
    228303        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    229         $num_jobs++;
    230         next;
    231     }
    232 
    233     # user requested us to search all components. Set to ""
    234     $search_component = "" if $search_component eq "all";
    235 
     304        return 0;
     305    }
     306
     307    my $stage = $row->{IMG_TYPE};
    236308    if (!check_image_type($stage)) {
    237         print STDERR "invalid IMG_TYPE for row $rownum\n" if $verbose;
     309        print STDERR "invalid IMG_TYPE for row $rownum\n";
    238310        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    239         $num_jobs++;
    240         next;
     311        return 0;
    241312    }
    242313
    243314    if ((($job_type eq "stamp") or ($req_type eq "bycoord")) and ! validROI($row)) {
    244         print STDERR "invalid ROI for row $rownum\n" if $verbose;
     315        print STDERR "invalid ROI for row $rownum\n";
    245316        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    246         $num_jobs++;
    247         next;
     317        return 0;
    248318    }
    249319
    250320    if (($req_type eq "byexp") and ($stage eq "stack")) {
    251         print STDERR "byexp not implemented for stack stage. row: $rownum\n" if $verbose;
     321        print STDERR "byexp not implemented for stack stage. row: $rownum\n";
    252322        insertFakeJobForRow($row, 1, $PSTAMP_NOT_IMPLEMENTED);
    253         $num_jobs++;
    254         next;
    255     }
    256 
    257    
     323        return 0;
     324    }
     325
    258326    # $mode list_uri is a debugging mode (it may used by the http interface)
    259327    # if this happens just croak
    260     my_die("job_type is list_uri but mode is $mode", $PS_EXIT_PROG_ERROR) if ($job_type eq "list_uri") and ($mode ne "list_uri");
    261 
     328   # my_die("job_type is list_uri but mode is $mode", $PS_EXIT_PROG_ERROR) if ($job_type eq "list_uri") and ($mode ne "list_uri");
     329
     330
     331    if ($req_type eq "bycoord") {
     332        if (!$skycenter) {
     333            print STDERR "center must be specified in sky coordintes for bycoord";
     334            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     335            return 0;
     336        }
     337    }
     338
     339    if (($req_type eq "byid") or ($req_type eq "bydiff")) {
     340        if (!validID($row->{ID})) {
     341            print STDERR "ID must be a positive integer for req_type $req_type\n";
     342            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     343            return 0
     344        }
     345    }
     346
     347    return 1;
     348}
     349
     350sub processRows {
     351    my $rowList = shift;
     352    my $num_jobs = 0;
     353
     354    # all rows in the list are compatible
     355    my $row = $rowList->[0];
     356
     357    my $project  = $row->{PROJECT};
     358
     359    # note: resolve_project avoids running pstamptool every time by remembering the
     360    # last project resolved
     361    my $proj_hash = resolve_project($ipprc, $project, $dbname, $dbserver);
     362    if (!$proj_hash) {
     363        print STDERR "project $project not found\n" ;
     364        foreach $row (@$rowList) {
     365            insertFakeJobForRow($row, 1, $PSTAMP_UNKNOWN_PRODUCT);
     366            $num_jobs++;
     367        }
     368        return $num_jobs;
     369    }
     370    my $req_type  = $row->{REQ_TYPE};
     371    $stage        = $row->{IMG_TYPE};
     372    my $id        = $row->{ID};
     373    my $component = $row->{COMPONENT};
     374    my $tess_id   = $row->{TESS_ID};
     375
     376    my $filter    = $row->{REQFILT};
     377    my $mjd_min   = $row->{MJD_MIN};
     378    my $mjd_max   = $row->{MJD_MAX};
     379    my $data_group = $row->{DATA_GROUP};
     380
     381    my $rownum     = $row->{ROWNUM};
     382    my $job_type   = $row->{JOB_TYPE};
     383    my $option_mask= $row->{OPTION_MASK};
     384   
    262385    my $image_db   = $proj_hash->{dbname};
    263386    my $camera     = $proj_hash->{camera};
    264     $need_magic = $proj_hash->{need_magic};
     387    $need_magic    = $proj_hash->{need_magic};
    265388
    266389    # Temporary hack so that MOPS can get at non-magicked data
    267 #    if ($product and ($product eq "mops-pstamp-results")) {
    268 #        $need_magic = 0;
    269 #    }
    270 
    271     # For "stamp" and "list_uri" jobs collect rows with the same images of interest in a list so that they
    272     # can be looked up together.
    273     if (@rowList) {
    274         my $firstRow = $rowList[0];
    275         if (($firstRow->{JOB_TYPE} ne "get_image") and same_images_of_interest($firstRow, $row)) {
    276 
    277             # add this row to the list and move on
    278             push @rowList, $row;
    279 
    280             next;
    281 
    282         } else {
    283             # this row has different selectors
    284             # queue the jobs for the ones we've collected
    285             $num_jobs += queueJobs($mode, \@rowList, $imageList);
    286             @rowList = ();
    287         }
    288     }
    289 
    290     # look up images for the current row
    291     if ($req_type eq "bycoord") {
    292         if (!$skycenter) {
    293             print STDERR "center must be specified in sky coordintes for bycoord" if $verbose;
    294             insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    295             $num_jobs++;
    296             next;
    297         }
    298     }
    299     if (($req_type eq "byid") or ($req_type eq "bydiff")) {
    300         if (!validID($id)) {
    301             print STDERR "ID must be a positive integer for req_type $req_type\n" if $verbose;
    302             insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    303             $num_jobs++;
    304             next;
    305         }
    306     }
     390    my $allow_mops_unmagicked = 1;
     391    if ($allow_mops_unmagicked) {
     392        if ($product and (($product eq "mops-pstamp-results") or
     393                          ($product eq "mops-pstamp-results2"))) {
     394            $need_magic = 0;
     395        }
     396    }
     397
     398    $need_magic = 0 if $stage eq 'stack';
     399   
     400    my $numRows = scalar @$rowList;
     401
     402    print "Collected $numRows rows beginning with row $rownum. $req_type $stage $id $tess_id $component\n";
     403   
    307404    # Call PS::IPP::PStamp::Job locate_images subroutine to get the images for this
    308405    # request specification. An array reference is returned.
    309     $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $tess_id, $search_component,
    310                 $option_mask, $need_magic, $x, $y, $mjd_min, $mjd_max, $filter, $data_group, $verbose);
    311 
    312     if (!$imageList or !@$imageList) {
    313         print STDERR "no matching images found for row $rownum\n" if $verbose;
    314         # note in this case queueJobs inserts the fake job for these rows
    315     }
     406    my $start_locate = gettimeofday();
     407
     408    # XXX: perhaps we should get rid of most of this argument list.
     409    # Now that we are passing down compatible rows all of the
     410    # information required is contained there
     411
     412    $imageList = locate_images($ipprc, $image_db, \@rowList, $req_type, $stage, $id, $tess_id, $component,
     413                $option_mask, $need_magic, $mjd_min, $mjd_max, $filter, $data_group, $verbose);
     414
     415    my $dtime_locate = gettimeofday() - $start_locate;
     416    print "Time to locate_images for row $rownum $dtime_locate\n";
     417
     418    # handle this XXX: what did I mean by this comment
    316419    $row->{need_magic} = $need_magic;
    317     push @rowList, $row;
    318 }
    319 
    320 if (@rowList) {
     420
    321421    $num_jobs += queueJobs($mode, \@rowList, $imageList);
    322 }
    323 
    324 if (($mode eq "queue_job") and ($num_jobs eq 0)) {
    325     print STDERR "no jobs created for $req_name\n" if $verbose;
    326     insertFakeJobForRow(undef, 0, $PSTAMP_INVALID_REQUEST);
    327 }
    328 
    329 # PAU
    330 
    331 exit 0;
    332 
    333 
    334 sub queueJobsForRow
     422
     423    # if a row slipped through with no jobs add one
     424    foreach my $row (@rowList) {
     425        if ($row->{job_num} == 0) {
     426            print "row $row->{ROWNUM} produced no jobs\n";
     427            print STDERR "row $row->{ROWNUM} produced no jobs\n";
     428            my $error_code = $row->{error_code};
     429            $error_code =  $PSTAMP_NO_IMAGE_MATCH if !$error_code;
     430            insertFakeJobForRow($row, ++$row->{job_num}, $error_code);
     431        }
     432    }
     433
     434    return $num_jobs;
     435}
     436
     437sub queueJobForImage
    335438{
    336439    my $row = shift;
    337440    my $stage = shift;
    338     my $imageList = shift;
    339     my $have_skycells = shift;
     441    my $image = shift;
    340442    my $need_magic = shift;
    341443    my $mode = shift;
    342444
    343     my $num_jobs = 0;
    344445    my $rownum = $row->{ROWNUM};
    345446    my $option_mask = $row->{OPTION_MASK};
    … …  
    365466    }
    366467
     468    my $component = $image->{component};
     469
     470    my $job_num = ++($row->{job_num});
     471
     472    my $imagefile = $image->{image};
     473    if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
     474        # XXX: should we add a faulted job so the client can know what happened if no images come back?
     475        # The test for destreaked is made in locate_images now so this code never runs. This leads to no feedback
     476        # to users, but speeds up processing significantly
     477        print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
     478
     479        # for now assume yes.
     480
     481        insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
     482        return 1;
     483    } elsif ($stage eq "stack") {
     484        # unconvolved stack images weren't available prior to some point in time.
     485        # XXX: handle this more correctly by examining the stack run's config dump file.
     486        # It looks like # the feature was turned on sometime around November 11, 2009. stackRun 30067 is the lowest
     487        # one that I found with an unconvolved image.
     488        my $MIN_GPC1_STACK_ID_WITH_UNCONVOLVED_IMAGES = 30067;
     489        if ($row->{unconvolved} and ($row->{PROJECT} eq 'gpc1') and
     490            ($image->{stack_id} < $MIN_GPC1_STACK_ID_WITH_UNCONVOLVED_IMAGES)) {
     491            print STDERR "Unconvolved stack image is not available for stackRun.stack_id: $image->{stack_id}\n";
     492            insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_AVAILABLE);
     493            return 1;
     494        }
     495    }
     496    my $exp_id = $image->{exp_id};
     497           
     498    my $args = $roi_string ? $roi_string : "";
     499    if ($stage eq "raw" or $stage eq "chip") {
     500        $args .= " -class_id $component" if $component;
     501    }
     502
     503    # add astrometry file for raw and chip images if one is available
     504    if (($stage eq "chip") || ($stage eq "raw")) {
     505        $args .= " -astrom $image->{astrom}" if $image->{astrom};
     506    }
     507
     508    $image->{job_args} = $args;
     509
     510    my $base = basename($image->{image});
     511    if (! $base =~ /.fits$/ ) {
     512        my_die("unexpected image file name found $image->{image}", $PS_EXIT_PROG_ERROR);
     513    }
     514    $base =~ s/.fits$//;
     515           
     516    my $output_base = "$outdir/${rownum}_${job_num}_${base}";
     517    write_params($output_base, $image);
     518
     519    my $newState = "run";
     520    my $fault = 0;
     521    my $dep_id;
     522
     523    # XXX: this code is repeated in queueGetImageJobs we should encapsulate it in a subroutine and share it
     524    if ($stage ne 'raw') {
     525        # updates for stack stage not supported yet
     526        my $allow_wait_for_update = ($stage ne 'stack');
     527        my $run_state = $image->{state};
     528        my $data_state = $image->{data_state};
     529        $data_state = $run_state if $stage eq 'stack';
     530        if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
     531            ($run_state eq 'drop') or
     532            ($run_state eq 'error_cleaned') or ($data_state eq 'error_cleaned') or
     533            ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
     534            # image is gone and it's not coming back
     535            $newState = 'stop';
     536            $fault = $PSTAMP_GONE;
     537        } elsif (($data_state ne 'full') or ($need_magic and ($image->{magicked} < 0))) {
     538            if ($stage eq 'chip') {
     539                my $burntool_state = $image->{burntool_state};
     540                if ($burntool_state and (abs($burntool_state) < 14)) {
     541                    $newState = 'stop';
     542                    $fault = $PSTAMP_NOT_AVAILABLE;
     543                }
     544            }
     545            if (!$allow_wait_for_update) {
     546                print STDERR "wait for update not supported for stage $stage yet\n";
     547                $newState = 'stop';
     548                $fault = $PSTAMP_NOT_AVAILABLE;
     549            }
     550            if (!$fault) {
     551                # wait for update unless the customer asks us not to
     552                if (($option_mask & $PSTAMP_NO_WAIT_FOR_UPDATE)) {
     553                    $newState = 'stop';
     554                    $fault = $PSTAMP_NOT_AVAILABLE;
     555                } elsif (!$image->{magicked}) {
     556                    $newState = 'stop';
     557                    $fault = $PSTAMP_NOT_DESTREAKED;
     558                } else {
     559                    # cause the image to be re-made
     560                    # set up to queue an update run
     561                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{imagedb},
     562                        $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic);
     563                }
     564            }
     565        }
     566    }
     567
     568    my $command = "$pstamptool -addjob  -req_id $req_id -job_type $row->{JOB_TYPE}"
     569                    . " -outputBase $output_base -rownum $rownum -state $newState -options $option_mask";
     570    $command .= " -fault $fault" if $fault;
     571    $command .= " -exp_id $exp_id" if $exp_id;
     572    $command .= " -dep_id $dep_id" if $dep_id;
     573
     574    if (!$no_update) {
     575        # mode eq "queue_job"
     576        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     577            run(command => $command, verbose => $verbose);
     578        unless ($success) {
     579            print STDERR @$stderr_buf;
     580            # XXX TODO: now what? Should we mark the error state for the request?
     581            # should we keep going for other uris? If so how do we report that some
     582            # of the work that the request wanted isn't going to get done
     583            my_die("failed to queue job for request $req_id", $PS_EXIT_UNKNOWN_ERROR);
     584        }
     585    } else {
     586        print "skipping command: $command\n";
     587    }
     588
     589    return 1;
     590}
     591
     592# queue jobs for a collection of request specifications that have the same Images of Interest
     593sub queueJobs
     594{
     595    my $mode = shift;
     596    my $rowList = shift;
     597    my $imageList = shift;
     598
     599    my $firstRow = $rowList[0];
     600    my $stage    = $firstRow->{IMG_TYPE};
     601    my $job_type = $firstRow->{JOB_TYPE};
     602    my $need_magic = $firstRow->{need_magic};
     603
     604    my $num_jobs = 0;
     605
     606    if ($mode eq "list_uri") {
     607        foreach my $image (@$imageList) {
     608            print "$image->{image}\n";
     609        }
     610    } elsif ($job_type eq "get_image") {
     611        my $n = scalar @$rowList;
     612
     613        my_die( "error: unexpected number of rows for get_image request: $n", $PS_EXIT_PROG_ERROR) if $n != 1;
     614
     615        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
     616
     617    } else {
     618        if (!$imageList or (scalar @$imageList eq 0)) {
     619            # We didn't find any images for this set of rows. Insert a fake job to carry
     620            # the status back to the requestor.
     621            foreach my $row (@$rowList) {
     622                my $error_code = $row->{error_code};
     623                $error_code = $PSTAMP_NO_IMAGE_MATCH if !$error_code;
     624                insertFakeJobForRow($row, ++$row->{job_num}, $error_code);
     625                $num_jobs++;
     626            }
     627            return $num_jobs;
     628        }
     629
     630        foreach my $image (@$imageList) {
     631            # get the array of row indices that touch this image
     632            my $row_index = $image->{row_index};
     633            if (!$row_index or scalar @$row_index == 0) {
     634                # XXX should this happen? Why did something get returned.
     635                print "image ${stage}_id: $image->{stage_id} component: $image->{component} matched no rows\n";
     636                next;
     637            }
     638            # XXX: TODO: eventually we may change ppstamp to be able to make multiple stamps per invocation
     639
     640            foreach my $i (@$row_index) {
     641                my $row = $rowList->[$i];
     642
     643                $num_jobs += queueJobForImage($row, $stage, $image, $need_magic, $mode);
     644            }
     645        }
     646    }
     647
     648    return $num_jobs;
     649}
     650
     651sub queueGetImageJobs
     652{
     653    my $row = shift;
     654    my $imageList = shift;
     655    my $stage = shift;
     656    my $need_magic = shift;
     657    my $mode = shift;
     658
     659    my $num_jobs = 0;
     660    my $rownum = $row->{ROWNUM};
     661    my $option_mask = $row->{OPTION_MASK};
     662
     663    # For dist_bundle we need
     664    #  --camera from $image
     665    #  --stage
     666    #  --stage_id from $image
     667    #  --component from $image
     668    #  --path_base
     669    #  --outdir global to this script
     670
    367671    # loop over images
    368     my $job_num = 0;
    369672    foreach my $image (@$imageList) {
    370         my $component;
    371         if ($have_skycells) {
    372             $component = $image->{skycell_id};
    373         } else {
    374             $component = $image->{class_id};
    375         }
    376 
    377         # skip this component if it is not in the list for this row
    378         next if ! $components->{$component};
    379 
    380         $job_num++;
     673        my $stage_id = $image->{stage_id};
     674        my $component = $image->{component};
     675
     676        # skip faulted components for now. Should we even be here?
     677        if ($image->{fault} > 0) {
     678            printf STDERR "skipping faulted component for $stage $stage_id $component\n" if $verbose;
     679            next;
     680        }
     681
     682        my $job_num = ++($row->{job_num});
    381683
    382684        my $imagefile = $image->{image};
    383685        if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
    384             # XXX: should we add a faulted job so the client can know what happened if no images come back?
    385             # The test for destreaked is made in locate_images now so this code never runs. This leads to no feedback
    386             # to users, but speeds up processing significantly
     686            # we only get here if req_type is (byid or byexp). For other types the test for magicked is performed
     687            # in locate_images because it's much more efficient to do the test in the database.
     688            # For these two modes we fall through to here in order to give feedback to the requestor as
     689            # to why the request failed to queue jobs.
    387690            print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
    388 
    389             # for now assume yes.
    390 
    391691            insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
    392692            $num_jobs++;
    … …  
    396696        my $exp_id = $image->{exp_id};
    397697           
    398         my $args = $roi_string ? $roi_string : "";
    399         if ($stage eq "raw" or $stage eq "chip") {
    400             $args .= " -class_id $component" if $component;
    401         }
    402 
    403         # add astrometry file for raw and chip images if one is available
    404         if (($stage eq "chip") || ($stage eq "raw")) {
    405             $args .= " -astrom $image->{astrom}" if $image->{astrom};
    406         }
    407 
    408         $image->{job_args} = $args;
    409 
    410         # XXX: we can get rid of the following everything that we need is
    411         # in the params file
    412 
    413         $args .= " -file $imagefile";
    414 
    415         if (($option_mask & $PSTAMP_SELECT_MASK) &&  $image->{mask} ) {
    416             $args .= " -mask $image->{mask}";
    417         }
    418         if (($option_mask & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {
    419             $args .= " -variance $image->{weight}";
    420         }
    421 
    422         my $base = basename($image->{image});
    423         if (! $base =~ /.fits$/ ) {
    424             my_die("unexpected image file name found $image->{image}", $PS_EXIT_PROG_ERROR);
    425         }
    426         $base =~ s/.fits$//;
    427            
    428         # XXX: TODO use filerule for this. I don't have a camera defined here
    429         if (($stage eq 'chip') and ($image->{camera} eq 'GPC1')) {
    430             $base = "${base}.${component}";
    431         }
    432 
    433         my $output_base = "$out_dir/${rownum}_${job_num}_${base}";
    434         my $argslist = "${output_base}.args";
    435 
    436         # copy the argument list to a file
    437         open ARGSLIST, ">$argslist" or my_die("failed to open $argslist", $PS_EXIT_UNKNOWN_ERROR);
    438         print ARGSLIST "$args\n";
    439         close ARGSLIST or my_die("failed to close $argslist", $PS_EXIT_UNKNOWN_ERROR);
     698        my $output_base = "$outdir/${rownum}_${job_num}";
    440699
    441700        write_params($output_base, $image);
    … …  
    454713                $newState = 'stop';
    455714                $fault = $PSTAMP_GONE;
    456             } elsif (($data_state ne 'full') or ($run_state ne 'full' )) {
    457                 # don't wait for update unless the caller asks us to
    458                 if (!($option_mask & $PSTAMP_WAIT_FOR_UPDATE)) {
     715            } elsif (($data_state ne 'full') or ($need_magic and ($image->{magicked} < 0))) {
     716                # wait for update unless the customer asks us to not to
     717                if ($option_mask & $PSTAMP_NO_WAIT_FOR_UPDATE) {
    459718                    $newState = 'stop';
    460719                    $fault = $PSTAMP_NOT_AVAILABLE;
    … …  
    462721                    # cause the image to be re-made
    463722                    # set up to queue an update run
    464                     queue_update_run(\$newState, \$fault, \$dep_id, $image->{image_db},
    465                         $run_state, $stage, $image->{stage_id}, $need_magic);
     723                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{imagedb},
     724                        $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic);
    466725                }
    467726            }
    … …  
    475734        $command .= " -dep_id $dep_id" if $dep_id;
    476735
    477         if ($mode eq "list_job") {
    478             # this is a debugging mode, just print the pstamptool that would have run
    479             # this is sort of like the mode -noupdate that some other tools support
    480             print "$command\n";
    481         } elsif (!$no_update) {
    482             # mode eq "queue_job"
    483             my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    484                 run(command => $command, verbose => $verbose);
    485             unless ($success) {
    486                 print STDERR @$stderr_buf;
    487                 # XXX TODO: now what? Should we mark the error state for the request?
    488                 # should we keep going for other uris? If so how do we report that some
    489                 # of the work that the request wanted isn't going to get done
    490                 my_die("failed to queue job for request $req_id", $PS_EXIT_UNKNOWN_ERROR);
    491             }
    492         } else {
    493             print "skipping command: $command\n";
    494         }
    495     }
    496     if ( $num_jobs == 0 ) {
    497         print STDERR "no jobs for row $rownum\n" if $verbose;
    498         insertFakeJobForRow($row, 1, $PSTAMP_NO_OVERLAP);
    499         $num_jobs = 1;
    500     }
    501     return $num_jobs;
    502 }
    503 
    504 # queue jobs for a collection of request specifications that have the same Images of Interest
    505 sub queueJobs
    506 {
    507     my $mode = shift;
    508     my $rowList = shift;
    509     my $imageList = shift;
    510 
    511     my $firstRow = $rowList[0];
    512     my $stage    = $firstRow->{IMG_TYPE};
    513     my $job_type = $firstRow->{JOB_TYPE};
    514     my $need_magic = $firstRow->{need_magic};
    515 
    516     my $num_jobs = 0;
    517 
    518     if ($mode eq "list_uri") {
    519         foreach my $image (@$imageList) {
    520             print "$image->{image}\n";
    521         }
    522     } elsif ($job_type eq "get_image") {
    523         my $n = scalar @$rowList;
    524 
    525         my_die( "error: unexpected number of rows for get_image request: $n", $PS_EXIT_PROG_ERROR) if $n != 1;
    526 
    527         $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
    528 
    529     } else {
    530         if (!$imageList or (scalar @$imageList eq 0)) {
    531             # we didn't find any images for this set of rows. Insert a fake job to carry
    532             # the status back to the requestor
    533             foreach my $row (@$rowList) {
    534                 insertFakeJobForRow($row, 1, $PSTAMP_NO_IMAGE_MATCH);
    535                 $num_jobs++;
    536             }
    537             return $num_jobs;
    538         }
    539 
    540         my $have_skycells;
    541         if (($stage eq "raw") or ($stage eq "chip")) {
    542             $have_skycells = 0;
    543         } else {
    544             $have_skycells = 1;
    545         }
    546        
    547         my $thisRun;
    548 
    549         my $npoints = 0;
    550         my ($pointsList, $pointsListName);
    551         if (scalar @$imageList > 1) {
    552             ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps);
    553             foreach my $row (@$rowList) {
    554                 $row->{components} = {};
    555                 if ($row->{skycenter}) {
    556                     print $pointsList "$row->{ROWNUM} $row->{CENTER_X} $row->{CENTER_Y}\n";
    557                     $npoints++;
    558                 } else {
    559                     # this row's center is in pixel coordinates add all images to the component list for this row
    560                     foreach my $i (@$imageList) {
    561                         my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id};
    562                         my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR)
    563                                 if !$component;
    564                         $row->{components}->{$component} = 1;
    565                     }
    566                 }
    567             }
    568             close $pointsList;
    569         } else {
    570             # only one image. Avoid the expense of dvoImagesAtCoords.
    571             # queue the job and let ppstamp figure out if the center is valid for the image
    572             # the resulting result code will be the same.
    573             foreach my $row (@$rowList) {
    574                 $row->{components} = {};
    575                 my $i = $imageList->[0];
    576                 my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id};
    577                 my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR) if !$component;
    578                 $row->{components}->{$component} = 1;
    579             }
    580         }
    581 
    582         my $tess_dir_abs;
    583         my $last_tess_id = "";
    584         while ($thisRun = getOneRun($stage, $imageList)) {
    585             if ($npoints) {
    586                 my_die( "pointsListName is not defined", $PS_EXIT_PROG_ERROR) if !$pointsListName;
    587                 # we collected a set of sky coordinates above.
    588                 # filter the images so that only those that contain the centers of the ROIs are processed
    589                 my $command = "$dvoImagesAtCoords -coords $pointsListName";
    590                 if ($have_skycells) {
    591                     my $tess_id = $thisRun->[0]->{tess_id};
    592                     if ($tess_id ne $last_tess_id) {
    593                         $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id );
    594                         $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs );
    595                         $last_tess_id = $tess_id;
    596                     }
    597                     $command .= " -D CATDIR $tess_dir_abs";
    598                 } else {
    599                     my $astrom = $thisRun->[0]->{astrom};
    600                     my_die( "no astrometry file found", $PS_EXIT_UNKNOWN_ERROR) if !$astrom;
    601                     my $astrom_resolved = $ipprc->file_resolve($astrom);
    602                     $command .= " -astrom $astrom_resolved";
    603                 }
    604                 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    605                     run(command => $command, verbose => $verbose);
    606                 unless ($success) {
    607                     # don't fail if the program exited normally and exit status was PSTAMP_NO_OVERLAP
    608                     # That just means that the coordinate didn't match any image/skycell
    609                     if (!WIFEXITED($error_code) || (WEXITSTATUS($error_code) ne $PSTAMP_NO_OVERLAP)) {
    610                         print STDERR @$stderr_buf;
    611                         my $rc = WIFEXITED($error_code) ? WEXITSTATUS($error_code) : $PS_EXIT_SYS_ERROR;
    612                         my_die( "dvoImagesAtCoords failed: $rc", $rc);
    613                     }
    614                 }
    615                 # now we have a list of row numbers and components
    616                 # eventually we might want to multiple stamp requests for the same image
    617                 # into the same ppstamp job but not yet. For now we will queue a new
    618                 my @lines = split "\n", join "", @$stdout_buf;
    619                 foreach my $line (@lines) {
    620                     # parse the line, ignoring the ra and dec
    621                     my ($rownum, undef, undef, $component) = split " ", $line;
    622 
    623                     # I guess since we need this function we should be using a hash for rowList
    624                     my $row = findRow($rownum, $rowList);
    625                     $row->{components}->{$component} = 1;
    626                 }
    627             }
    628            
    629             foreach my $row (@$rowList) {
    630                 $num_jobs += queueJobsForRow($row, $stage, $thisRun, $have_skycells, $need_magic, $mode);
    631             }
    632         }
    633     }
    634     return $num_jobs;
    635 }
    636 
    637 #        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
    638 sub queueGetImageJobs
    639 {
    640     my $row = shift;
    641     my $imageList = shift;
    642     my $stage = shift;
    643     my $need_magic = shift;
    644     my $mode = shift;
    645 
    646     my $num_jobs = 0;
    647     my $rownum = $row->{ROWNUM};
    648     my $option_mask = $row->{OPTION_MASK};
    649 
    650     # For dist_bundle we need
    651     #  --camera from $image
    652     #  --stage
    653     #  --stage_id from $image
    654     #  --component from $image
    655     #  --path_base
    656     #  --outdir global to this script
    657 
    658     # loop over images
    659     my $job_num = 0;
    660     foreach my $image (@$imageList) {
    661         my $stage_id = $image->{stage_id};
    662         my $component = $image->{component};
    663 
    664         # skip faulted components for now. Should we even be here?
    665         if ($image->{fault} > 0) {
    666             printf STDERR "skipping faulted component for $stage $stage_id $component\n" if $verbose;
    667             next;
    668         }
    669 
    670         $job_num++;
    671 
    672         my $imagefile = $image->{image};
    673         if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
    674             # we only get here if req_type is (byid or byexp). For other types the test for magicked is performed
    675             # in locate_images because it's much more efficient to do the test in the database.
    676             # For these two modes we fall through to here in order to give feedback to the requestor as
    677             # to why the request failed to queue jobs.
    678             print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
    679             insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
    680             $num_jobs++;
    681 
    682             next;
    683         }
    684         my $exp_id = $image->{exp_id};
    685            
    686         my $output_base = "$out_dir/${rownum}_${job_num}";
    687 
    688         write_params($output_base, $image);
    689 
    690         my $newState = "run";
    691         my $fault = 0;
    692         my $dep_id;
    693 
    694         if ($stage ne 'raw') {
    695             my $run_state = $image->{state};
    696             my $data_state = $image->{data_state};
    697             $data_state = $run_state if $stage eq "stack";
    698             if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
    699                 ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
    700                 # image is gone and it's not coming back
    701                 $newState = 'stop';
    702                 $fault = $PSTAMP_GONE;
    703             } elsif (($data_state ne 'full') or ($run_state ne 'full' )) {
    704                 # don't wait for update unless the caller asks us to
    705                 if (!($option_mask & $PSTAMP_WAIT_FOR_UPDATE)) {
    706                     $newState = 'stop';
    707                     $fault = $PSTAMP_NOT_AVAILABLE;
    708                 } else {
    709                     # cause the image to be re-made
    710                     # set up to queue an update run
    711                     queue_update_run(\$newState, \$fault, \$dep_id, $image->{image_db},
    712                         $run_state, $stage, $image->{stage_id}, $need_magic);
    713                 }
    714             }
    715         }
    716 
    717         $num_jobs++;
    718         my $command = "$pstamptool -addjob  -req_id $req_id -job_type $row->{JOB_TYPE}"
    719                         . " -outputBase $output_base -rownum $rownum -state $newState -options $option_mask";
    720         $command .= " -fault $fault" if $fault;
    721         $command .= " -exp_id $exp_id" if $exp_id;
    722         $command .= " -dep_id $dep_id" if $dep_id;
    723 
    724         if ($mode eq "list_job") {
    725             # this is a debugging mode, just print the pstamptool that would have run
    726             # this is sort of like the mode -noupdate that some other tools support
    727             print "$command\n";
    728         } elsif (!$no_update) {
     736        if (!$no_update) {
    729737            # mode eq "queue_job"
    730738            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    … …  
    776784                        . " -rownum $rownum -state stop -fault $fault";
    777785
    778     if ($mode eq "list_job") {
    779         # this is a debugging mode, just print the pstamptool that would have run
    780         # this is sort of like the mode -noupdate that some other tools support
    781         print "$command\n";
    782     } elsif (!$no_update) {
     786    if (!$no_update) {
    783787        # mode eq "queue_job"
    784788        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    … …  
    796800}
    797801
    798 sub get_run_id
    799 {
    800     my $stage = shift;
    801     my $image = shift;
    802 
    803     if ($stage eq "raw") {
    804         return $image->{exp_id};
    805     } elsif ($stage eq "chip") {
    806         return $image->{chip_id};
    807     } elsif ($stage eq "warp") {
    808         return $image->{warp_id};
    809     } elsif ($stage eq "stack") {
    810         return $image->{stack_id};
    811     } elsif ($stage eq "diff") {
    812         return $image->{diff_id};
    813     } else {
    814         my_die("unenexpected stage: $stage found", $PS_EXIT_PROG_ERROR);
    815     }
    816 }
    817 
    818 # extract components from the imageList that have the same run id and return the list
    819 sub getOneRun {
    820     my $stage = shift;
    821     my $imageList = shift;
    822 
    823     # return if array is empty
    824     return undef if ! @$imageList;
    825 
    826     my $last_run_id = 0;
    827     my @runList;
    828     while ($imageList->[0]) {
    829         my $run_id = get_run_id($stage, $imageList->[0]);
    830 
    831         last if ($last_run_id and ($run_id ne $last_run_id));
    832 
    833         my $image = shift @$imageList;
    834         $image->{stage} = $stage;
    835         push @runList, $image;
    836         $last_run_id = $run_id;
    837     }
    838     return \@runList;
    839 }
    840 
    841802sub same_images_of_interest {
    842803    my $r1 = shift;
    843804    my $r2 = shift;
    844805
    845     return 0 if (($r1->{REQ_TYPE} eq "bycoord") or ($r2->{REQ_TYPE} eq "bycoord"));
    846     return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
    847     return 0 if ($r1->{JOB_TYPE} ne $r2->{JOB_TYPE});
     806    return 0 if (($r1->{REQ_TYPE} eq "bycoord")   or ($r2->{REQ_TYPE} eq "bycoord"));
     807    return 0 if (($r1->{JOB_TYPE} eq "get_image") or ($r2->{JOB_TYPE} eq "get_image"));
    848808    return 0 if ($r1->{REQ_TYPE} ne $r2->{REQ_TYPE});
    849809    return 0 if ($r1->{IMG_TYPE} ne $r2->{IMG_TYPE});
    850810    return 0 if ($r1->{ID}       ne $r2->{ID});
    851811    return 0 if ($r1->{TESS_ID}  ne $r2->{TESS_ID});
     812    return 0 if ($r1->{COMPONENT}  ne $r2->{COMPONENT});
    852813    return 0 if ($r1->{REQFILT}  ne $r2->{REQFILT});
    853814    return 0 if ($r1->{DATA_GROUP}    ne $r2->{DATA_GROUP});
    854815    return 0 if ($r1->{MJD_MIN}  ne $r2->{MJD_MAX});
    855816    return 0 if ($r1->{MJD_MAX}  ne $r2->{MJD_MAX});
     817    return 0 if ($r1->{OPTION_MASK}  ne $r2->{OPTION_MASK});
     818    return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
    856819    return 0 if ($r1->{inverse}  ne $r2->{inverse});
    857820    return 0 if ($r1->{unconvolved}  ne $r2->{unconvolved});
    858 
    859     if (defined($r1->{COMPONENT})) {
    860         return 0 if !defined $r2->{COMPONENT} or ($r1->{COMPONENT} ne $r2->{COMPONENT});
    861     } elsif (defined($r2->{COMPONENT})) {
    862         # if first row has no component all of the images will be retrieved, so
    863         # the fact that this row has a component is ok. Fall through to return 1
    864         # XXX Nope this doesn't work. It is consistent with the other logic in some way
    865         # that i haven't fully thought through
    866         return 0;
    867     }
     821    # don't combine requests in pixel coordinates
     822    return 0 if (($r1->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS) || ($r2->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS));
    868823
    869824    return 1;
    … …  
    911866sub queue_update_run
    912867{
    913     my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $need_magic) = @_;
     868    my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $component, $need_magic) = @_;
     869
     870    # XXX: The update process for warp and subsequent stages requires
     871    # destreaking to run because the -pending queries require it when magicked > 0
     872    # queries.
     873    # The case of stack-stack diffs is taken care of in pstamp_checkdependent
     874    $need_magic = 1 if $imagedb eq 'gpc1';
    914875
    915876    if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) {
    … …  
    918879
    919880    my $dep_id;
    920     my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb";
    921     $command .= " -no_magic" if !$need_magic;
     881    my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb -component $component -outdir $outdir";
     882    $command .= " -need_magic" if $need_magic;
     883
     884    # compute rlabel for the run.
     885    # XXX: This bit of policy shouldn't be buried so deeply in the code
     886    # For now use one that implies 'postage stamp server' 'update' 'request_label"
     887    my $rlabel = "ps_ud_" . $label if $label;
     888    $command .= " -rlabel $rlabel" if $rlabel;
     889
    922890    if (!$no_update) {
    923891        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    … …  
    929897        chomp $output;
    930898        $dep_id = $output;
     899        #
     900        # XXX: need to fault the request or something
    931901        my_die("pstamptool -getdependent returned invalid dep_id", $PS_EXIT_PROG_ERROR) if !$dep_id;
    932902    } else {
    … …  
    936906   
    937907    $$r_dep_id = $dep_id;
    938     $r_fault = 0;
    939     $r_jobState = 'blocked';
     908    $$r_fault = 0;
     909    $$r_jobState = 'run';
    940910}
    941911
    … …  
    990960    # we don't fault the request here pstamp_parser_run.pl handles that if necessary
    991961
    992     return $fault;
    993 }
     962    exit $fault;
     963}
  • branches/pap/pstamp/scripts/request_finish.pl

    r24831 r28003  
    2121use PS::IPP::Config qw( :standard );
    2222
    23 my ( $req_id, $req_name, $req_file, $req_type, $out_dir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output );
     23my ( $req_id, $req_name, $req_file, $req_type, $outdir, $product, $dbname, $dbserver, $verbose, $save_temps, $redirect_output );
    2424
    2525GetOptions(
    … …  
    2828           'req_file=s' => \$req_file,
    2929           'req_type=s' => \$req_type,
    30            'out_dir=s'  => \$out_dir,
     30           'outdir=s'  => \$outdir,
    3131           'product=s'  => \$product,
    3232           'dbname=s'   => \$dbname,
    … …  
    4646$err .= "--req_name is required\n" if !$req_name;
    4747$err .= "--product is required\n" if !$product;
    48 # $err .= "--out_dir is required\n" if !$out_dir;
     48# $err .= "--outdir is required\n" if !$outdir;
    4949
    5050die "$err" if $err;
    5151
    5252
    53 if (!$out_dir) {
    54     $out_dir = dirname($req_file);
     53if (!$outdir) {
     54    $outdir = dirname($req_file);
    5555}
    5656
    5757if ($redirect_output) {
    58     my $logDest = "$out_dir/reqfinish.$req_id.log";
     58    my $logDest = "$outdir/reqfinish.$req_id.log";
    5959    my $ipprc = PS::IPP::Config->new();
    6060    $ipprc->redirect_output($logDest);
    … …  
    7979}
    8080if ($finish_cmd) {
    81     my $command = $finish_cmd . " --req_id $req_id --req_name $req_name --req_file $req_file --product $product --out_dir $out_dir";
     81    my $command = $finish_cmd . " --req_id $req_id --req_name $req_name --req_file $req_file --product $product --outdir $outdir";
    8282    $command   .= " --dbname $dbname" if $dbname;
    8383    $command   .= " --dbserver $dbserver" if $dbserver;
  • branches/pap/pstamp/src/ppstampMakeStamp.c

    r27461 r28003  
    3636    double d_before = check->sky->d;
    3737    psLogMsg("ppstampMakeStamp", 2, "Before fit  Center Pixel RA: %f   DEC: %f (degrees)\n",
    38              r_before * PS_DEG_RAD, d_before * PS_DEG_RAD);
     38             r_before * PS_DEG_RAD, d_before * PS_DEG_RAD);
    3939
    4040    if (outFPA->toSky->type != PS_PROJ_TAN) {
    41         // we need to make astrometry terms for the output which are centered on the output chip center,
    42         // but we keep the original plate scale
    43         psFree(outFPA->toSky);
    44         outFPA->toSky = psProjectionAlloc (r_before, d_before, inFPA->toSky->Xs, inFPA->toSky->Ys, PS_PROJ_TAN);
    45 
    46         if (!pmAstromLinearizeToSky(inFPA, inChip, outFPA, outChip, roi)) {
     41        // we need to make astrometry terms for the output which are centered on the output chip center,
     42        // but we keep the original plate scale
     43        psFree(outFPA->toSky);
     44        outFPA->toSky = psProjectionAlloc (r_before, d_before, inFPA->toSky->Xs, inFPA->toSky->Ys, PS_PROJ_TAN);
     45
     46        if (!pmAstromLinearizeToSky(inFPA, inChip, outFPA, outChip, roi)) {
    4747            psFree(check);
    4848            psError(PS_ERR_UNKNOWN, false, "Failed to linearize astrometry\n");
    … …  
    5656
    5757        psLogMsg("ppstampMakeStamp", 2, "After fit:  Center Pixel RA: %f   DEC: %f (degrees)\n",
    58                 r_after * PS_DEG_RAD, d_after * PS_DEG_RAD);
    59         psLogMsg("ppstampMakeStamp", 2, "Error in fit to astrometry %.2f    %.2f (arcseconds)\n", 
    60                 (r_after - r_before) *  PS_DEG_RAD * 3600, (d_after - d_before) * PS_DEG_RAD * 3600);
     58                r_after * PS_DEG_RAD, d_after * PS_DEG_RAD);
     59        psLogMsg("ppstampMakeStamp", 2, "Error in fit to astrometry %.2f    %.2f (arcseconds)\n",
     60                (r_after - r_before) *  PS_DEG_RAD * 3600, (d_after - d_before) * PS_DEG_RAD * 3600);
    6161
    6262        // XXX: should we fail if the fit is bad ??
    … …  
    238238        return PS_EXIT_DATA_ERROR;
    239239    }
    240     char *fpaName = psMetadataLookupStr(NULL, input->fpa->concepts, "FPA.OBS"); // Name of FPA
    241240    pmFPAview *outview = pmFPAviewAlloc(0);
    242     pmFPAAddSourceFromView(output->fpa, fpaName, outview, output->format);
     241    pmFPAAddSourceFromView(output->fpa, outview, output->format);
    243242
    244243    outview->chip = 0;
  • branches/pap/pstamp/src/ppstampMosaic.c

    r18712 r28003  
    2424    pmChip  *inChip = pmFPAviewThisChip(view, input->fpa);
    2525    if (!mChip->hdu && !mChip->parent->hdu) {
    26         const char *name = psMetadataLookupStr(&status, input->fpa->concepts, "FPA.OBS"); // Name of FPA
    27         pmFPAAddSourceFromView(mosaic->fpa, name, mosaicView, mosaic->format);
     26        pmFPAAddSourceFromView(mosaic->fpa, mosaicView, mosaic->format);
    2827    }
    2928    psFree(mosaicView);
  • branches/pap/pstamp/test/detect_query_create

    r18738 r28003  
    1616     $output,                   # Name of output table
    1717     $query_id,
     18     $nostage,
    1819     );
    1920
    … …  
    2223           'output|o=s'   => \$output,
    2324           'query_id|q=s'  => \$query_id,
     25           'nostage'      => \$nostage,
    2426) or pod2usage( 2 );
    2527
    … …  
    6163        }
    6264];
     65unless(defined($nostage)) {
     66    push @{ $header },        { name =>  'STAGE',
     67                                writetype => TSTRING,
     68                                comment => 'processing stage to examine',
     69                                value => undef
     70    };
     71}
    6372
    6473# Specification of columns to write
Note: See TracChangeset for help on using the changeset viewer.