IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:41:49 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/tap_branches
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/tap_branches

  • branches/tap_branches/pstamp/scripts/pstampparse.pl

    r25808 r27838  
    1717use Carp;
    1818use POSIX;
     19use DateTime;
    1920
    2021my $verbose;
     
    2627my $out_dir;
    2728my $product;
     29my $label;
    2830my $save_temps;
    2931my $no_update;
     
    3436    'out_dir=s' =>  \$out_dir,
    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
     
    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
     
    98100
    99101# make sure the file contains what we are expecting
    100 
    101 # we shouldn't get here if this is the case so just die. No need to notify the client
     102# This program shouldn't have been run if the request file is bogus.
     103# No need to notify the client
    102104my_die("$request_file_name is not a PS1_PS_REQEST", $PS_EXIT_PROG_ERROR) if $extname ne "PS1_PS_REQUEST";
    103105my_die("REQ_NAME not found in $request_file_name", $PS_EXIT_PROG_ERROR)  if (!$req_name);
     
    151153        print STDERR @$stderr_buf;
    152154    }
    153     my $table =  $mdcParser->parse(join "", @$stdout_buf) or
    154         my_die("Unable to parse metdata config doc", $PS_EXIT_UNKNOWN_ERROR);
    155 
    156     $rows = parse_md_list($table);
    157 }
    158 
     155    if (@$stdout_buf) {
     156        my $table =  $mdcParser->parse(join "", @$stdout_buf) or
     157            my_die("Unable to parse metdata config doc", $PS_EXIT_UNKNOWN_ERROR);
     158        $rows = parse_md_list($table);
     159    }
     160
     161}
     162
     163#
     164# Loop over rows in the request file collecting consecutive rows that have the "same images of interest"
     165# in the sense that their selection parameters will yield the same "Runs".
     166# Process the groups of rows together to reduce lookup time and to potentially make multiple
     167# stamps from the same ppstamp process.
     168#
    159169my @rowList;
    160170my $num_jobs = 0;
     
    163173my $need_magic;
    164174foreach my $row (@$rows) {
    165     # XXX: TODO: sanity check all parameters
    166 
    167     # XXX: TODO: We shouldn't really just die in this loop.
    168     # If we encounter an error for a particular row
    169     # add a job with the proper fault code. If there is a db or config error we should probably just
    170     # trash the request.
     175    # santiy check the paramaters
     176    if (!checkRow($row)) {
     177        # when it enconters an error checkRow adds a fake job with an appropriate error code to the database
     178        $num_jobs++;
     179        next;
     180    }
     181    # initialize counter for "job number"
     182    $row->{job_num} = 0;
     183    $row->{error_code} = 0;
     184
     185    if (scalar @rowList == 0) {
     186        push @rowList, $row;
     187        next;
     188    }
     189
     190    my $firstRow = $rowList[0];
     191    if (same_images_of_interest($firstRow, $row)) {
     192        # add this row to the list and move on
     193        push @rowList, $row;
     194        next;
     195    }
     196
     197    # the images of interest for this new row doesn't match the list.
     198    # process the list ...
     199    $num_jobs += processRows(\@rowList);
     200
     201    # and reset the list to contain just the new row
     202    @rowList = ($row);
     203}
     204
     205# out of rows process the list
     206if (scalar @rowList > 0) {
     207    $num_jobs += processRows(\@rowList);
     208}
     209
     210if (($mode eq "queue_job") and ($num_jobs eq 0)) {
     211    print STDERR "no jobs created for $req_name\n" if $verbose;
     212    insertFakeJobForRow(undef, 0, $PSTAMP_INVALID_REQUEST);
     213}
     214
     215exit 0;
     216
     217sub checkRow {
     218       
     219    my $row = shift;
     220
     221    # If we encounter an error for a particular row add a job with the proper fault code.
    171222
    172223    my $rownum   = $row->{ROWNUM};
     224    if (!validID($rownum)) {
     225        print STDERR "$rownum is not a valid ROWNUM\n"  if $verbose;
     226        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     227        return 0;
     228    }
    173229    my $job_type = $row->{JOB_TYPE};
     230    if (($job_type ne "stamp") and ($job_type ne "get_image")) {
     231        print STDERR "$job_type is not a valid JOB_TYPE\n"  if $verbose;
     232        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     233        return 0;
     234    }
    174235   
    175     # parameters that select the images of interest
     236    my $req_type = $row->{REQ_TYPE};
     237    if (($req_type ne "byid") and ($req_type ne "bycoord") and ($req_type ne "byexp") and
     238        ($req_type ne "byskycell") and ($req_type ne "bydiff")) {
     239        print STDERR "$req_type is not a valid REQ_TYPE\n"  if $verbose;
     240        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     241        return 0;
     242    }
     243
     244
     245    my $component = $row->{COMPONENT};
     246    if (!defined $component or (lc($component) eq "null") or (lc($component) eq "all")) {
     247        $row->{COMPONENT} = $component = "";
     248    }
     249    $row->{TESS_ID} = "" if !defined $row->{TESS_ID};
     250
     251    my $filter  = $row->{REQFILT};
     252    if ($filter) {
     253        if (length($filter) == 1) {
     254            # allow single character filter cuts to work
     255            $row->{REQFILT} .= '%';
     256        }
     257    }
     258    my $mjd_min = $row->{MJD_MIN};
     259    if (defined($mjd_min) and !validNumber($mjd_min)) {
     260        print STDERR "$mjd_min is not a valid MJD_MIN\n"  if $verbose;
     261        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     262        return 0;
     263    }
     264    my $mjd_max = $row->{MJD_MAX};
     265    if (defined($mjd_max) and !validNumber($mjd_max)) {
     266        print STDERR "$mjd_max is not a valid MJD_MAX\n"  if $verbose;
     267        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     268        return 0;
     269    }
     270    my $data_group = $row->{DATA_GROUP};
     271    if (!defined $data_group) {
     272        # backwards compatability hook
     273        $data_group = $row->{LABEL};
     274        $data_group = "null" if !defined $data_group;
     275        $row->{DATA_GROUP} = $data_group;
     276    }
     277       
     278    # req_finish doesn't work if bit zero of option mask is not set;
     279    $row->{OPTION_MASK} |= 1;
     280
     281    my $option_mask= $row->{OPTION_MASK};
     282    my $inverse = ($option_mask & $PSTAMP_SELECT_INVERSE) ? 1 : 0;
     283    $row->{inverse} = $inverse;
     284    my $unconvolved = ($option_mask & $PSTAMP_SELECT_UNCONV) ? 1 : 0;
     285    $row->{unconvolved} = $unconvolved;
     286
     287    my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
     288
     289    if (!$skycenter and !$component) {
     290        print STDERR "COMPONENT must be specified for pixel coordinate ROI center\n" if $verbose;
     291        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     292        return 0;
     293    }
     294
     295    my $stage = $row->{IMG_TYPE};
     296    if (!check_image_type($stage)) {
     297        print STDERR "invalid IMG_TYPE for row $rownum\n" if $verbose;
     298        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     299        return 0;
     300    }
     301
     302    if ((($job_type eq "stamp") or ($req_type eq "bycoord")) and ! validROI($row)) {
     303        print STDERR "invalid ROI for row $rownum\n" if $verbose;
     304        insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     305        return 0;
     306    }
     307
     308    if (($req_type eq "byexp") and ($stage eq "stack")) {
     309        print STDERR "byexp not implemented for stack stage. row: $rownum\n" if $verbose;
     310        insertFakeJobForRow($row, 1, $PSTAMP_NOT_IMPLEMENTED);
     311        return 0;
     312    }
     313
     314    # $mode list_uri is a debugging mode (it may used by the http interface)
     315    # if this happens just croak
     316   # 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");
     317
     318
     319    if ($req_type eq "bycoord") {
     320        if (!$skycenter) {
     321            print STDERR "center must be specified in sky coordintes for bycoord" if $verbose;
     322            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     323            return 0;
     324        }
     325    }
     326
     327    if (($req_type eq "byid") or ($req_type eq "bydiff")) {
     328        if (!validID($row->{ID})) {
     329            print STDERR "ID must be a positive integer for req_type $req_type\n" if $verbose;
     330            insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
     331            return 0
     332        }
     333    }
     334
     335    return 1;
     336}
     337
     338sub processRows {
     339    my $rowList = shift;
     340    my $num_jobs = 0;
     341
     342    # all rows in the list are compatible
     343    my $row = $rowList->[0];
     344
    176345    my $project  = $row->{PROJECT};
    177346
     
    181350    if (!$proj_hash) {
    182351        print STDERR "project $project not found\n"  if $verbose;
    183         insertFakeJobForRow($row, 1, $PSTAMP_UNKNOWN_PRODUCT);
    184         $num_jobs++;
    185         next;
    186     }
    187     my $req_type = $row->{REQ_TYPE};
    188     $stage       = $row->{IMG_TYPE};
    189     my $id      = $row->{ID};
     352        foreach $row (@$rowList) {
     353            insertFakeJobForRow($row, 1, $PSTAMP_UNKNOWN_PRODUCT);
     354            $num_jobs++;
     355        }
     356        return $num_jobs;
     357    }
     358    my $req_type  = $row->{REQ_TYPE};
     359    $stage        = $row->{IMG_TYPE};
     360    my $id        = $row->{ID};
    190361    my $component = $row->{COMPONENT};
    191     my $tess_id = $row->{TESS_ID};
    192 
    193     my $filter  = $row->{REQFILT};
    194     my $mjd_min = $row->{MJD_MIN};
    195     my $mjd_max = $row->{MJD_MAX};
    196     my $label   = $row->{LABEL};
    197     my $x       = $row->{CENTER_X};
    198     my $y       = $row->{CENTER_Y};
    199 
     362    my $tess_id   = $row->{TESS_ID};
     363
     364    my $filter    = $row->{REQFILT};
     365    my $mjd_min   = $row->{MJD_MIN};
     366    my $mjd_max   = $row->{MJD_MAX};
     367    my $data_group = $row->{DATA_GROUP};
     368
     369    my $rownum     = $row->{ROWNUM};
     370    my $job_type   = $row->{JOB_TYPE};
    200371    my $option_mask= $row->{OPTION_MASK};
    201     my $inverse = ($option_mask & $PSTAMP_SELECT_INVERSE) ? 1 : 0;
    202     $row->{inverse} = $inverse;
    203 
    204     my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
    205 
    206     my $search_component = (!defined($component) or ($component eq "null")) ? "" : $component;
    207372   
    208     if (!$skycenter and !$search_component) {
    209         print STDERR "COMPONENT must be specified for pixel coordinate ROI center\n" if $verbose;
    210         insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    211         $num_jobs++;
    212         next;
    213     }
    214 
    215     $search_component = "" if $search_component eq "all";
    216 
    217     if ((($job_type eq "stamp") or ($req_type eq "bycoord")) and ! validROI($row)) {
    218         print STDERR "invalid ROI for row $rownum\n" if $verbose;
    219         insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    220         $num_jobs++;
    221         next;
    222     }
    223 
    224    
    225     # $mode list_uri is a debugging mode (it may used by the http interface)
    226     # if this happens just croak
    227     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");
    228 
    229373    my $image_db   = $proj_hash->{dbname};
    230374    my $camera     = $proj_hash->{camera};
    231     $need_magic = $proj_hash->{need_magic};
     375    $need_magic    = $proj_hash->{need_magic};
    232376
    233377    # Temporary hack so that MOPS can get at non-magicked data
    234     if ($product and ($product eq "mops-pstamp-results")) {
    235         $need_magic = 0;
    236     }
    237 
    238     # collect rows with the same images of interest in a list so that they
    239     # can be looked up together
    240     if (@rowList) {
    241         my $firstRow = $rowList[0];
    242         # note order of these parameters matters
    243         if (same_images_of_interest($firstRow, $row)) {
    244 
    245             # add this row to the list and move on
    246             push @rowList, $row;
    247 
    248             next;
    249 
    250         } else {
    251             # this row has different selectors
    252             # queue the jobs for the ones we've collected
    253             $num_jobs += queueJobs($mode, \@rowList, $imageList);
    254             @rowList = ();
    255         }
    256     }
    257 
    258     # look up images for the current row
    259     if ($req_type eq "bycoord") {
    260         if (!$skycenter) {
    261             print STDERR "center must be specified in sky coordintes for bycoord" if $verbose;
    262             insertFakeJobForRow($row, 1, $PSTAMP_INVALID_REQUEST);
    263             $num_jobs++;
    264             next;
    265         }
    266         if ($stage eq "stack") {
    267             print STDERR "lookup bycoord is not yet implemented for stage stack" if $verbose;
    268             insertFakeJobForRow($row, 1, $PSTAMP_NOT_IMPLEMENTED);
    269             $num_jobs++;
    270             next;
    271         }
    272     }
     378    my $allow_mops_unmagicked = 1;
     379    if ($allow_mops_unmagicked) {
     380        if ($product and (($product eq "mops-pstamp-results") or
     381                          ($product eq "mops-pstamp-results2"))) {
     382            $need_magic = 0;
     383        }
     384    }
     385   
     386    my $numRows = scalar @$rowList;
     387
     388#    $tess_id = "" if !defined $tess_id;
     389#    $component = "" if !defined $component;
     390
     391    print "Collected $numRows rows beginning with row $rownum. $req_type $stage $id $tess_id $component\n";
     392   
    273393    # Call PS::IPP::PStamp::Job locate_images subroutine to get the images for this
    274394    # request specification. An array reference is returned.
    275     $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $tess_id, $search_component,
    276                 $inverse, $need_magic, $x, $y, $mjd_min, $mjd_max, $filter, $label, $verbose);
     395    my $start_locate = DateTime->now->mjd;
     396
     397    # XXX: perhaps we should get rid of most of this argument list.
     398    # Now that we are passing down compatible rows all of the
     399    # information required is contained there
     400
     401    $imageList = locate_images($ipprc, $image_db, \@rowList, $req_type, $stage, $id, $tess_id, $component,
     402                $option_mask, $need_magic, $mjd_min, $mjd_max, $filter, $data_group, $verbose);
     403
     404    # XXX: why use mjd? It doesn't have great precision.
     405    my $dtime_locate = (DateTime->now->mjd - $start_locate) * 86400.;
     406    print "Time to locate_images for row $rownum $dtime_locate\n";
    277407
    278408    if (!$imageList or !@$imageList) {
     
    280410        # note in this case queueJobs inserts the fake job for these rows
    281411    }
     412    # handle this
    282413    $row->{need_magic} = $need_magic;
    283     push @rowList, $row;
    284 }
    285 
    286 if (@rowList) {
     414
    287415    $num_jobs += queueJobs($mode, \@rowList, $imageList);
    288 }
    289 
    290 if (($mode eq "queue_jobs") and ($num_jobs eq 0)) {
    291     print STDERR "no jobs created for $req_name\n" if $verbose;
    292     insertFakeJobForRow(undef, 0, $PSTAMP_UNKNOWN_ERROR);
    293 }
    294 
    295 # PAU
    296 
    297 exit 0;
    298 
    299 
    300 sub queueJobsForRow
     416
     417    # if a row slipped through with no jobs add one
     418    foreach my $row (@rowList) {
     419        if ($row->{job_num} == 0) {
     420            print "row $row->{ROWNUM} produced no jobs\n";
     421            print STDERR "row $row->{ROWNUM} produced no jobs\n";
     422            my $error_code = $row->{error_code};
     423            $error_code =  $PSTAMP_NO_IMAGE_MATCH if !$error_code;
     424            insertFakeJobForRow($row, ++$row->{job_num}, $error_code);
     425        }
     426    }
     427
     428    return $num_jobs;
     429}
     430
     431sub queueJobForImage
    301432{
    302433    my $row = shift;
    303434    my $stage = shift;
    304     my $imageList = shift;
    305     my $have_skycells = shift;
     435    my $image = shift;
    306436    my $need_magic = shift;
    307 
    308     my $num_jobs = 0;
     437    my $mode = shift;
     438
    309439    my $rownum = $row->{ROWNUM};
    310440    my $option_mask = $row->{OPTION_MASK};
     
    313443    my $roi_string;
    314444
    315     # note values were insured to be numbers in validROI()
     445    # note values were checked by the function validROI()
    316446    my $x = $row->{CENTER_X};
    317447    my $y = $row->{CENTER_Y};
     
    319449    my $h = $row->{HEIGHT};
    320450    my $coord_mask = $row->{COORD_MASK};
    321     if ($x && ($x ne "null") && $y && ($y ne "null") && $w && ($w ne "null") && $h && ($h ne "null")) {
    322         if ($coord_mask & $PSTAMP_CENTER_IN_PIXELS) {
    323             $roi_string = "-pixcenter $x $y";
    324         } else {
    325             $roi_string = "-skycenter $x $y";
    326         }
    327         if ($coord_mask & $PSTAMP_RANGE_IN_PIXELS) {
    328             $roi_string .= " -pixrange $w $h";
    329         } else {
    330             $roi_string .= " -arcrange $w $h";
    331         }
    332     }
     451    if ($coord_mask & $PSTAMP_CENTER_IN_PIXELS) {
     452        $roi_string = "-pixcenter $x $y";
     453    } else {
     454        $roi_string = "-skycenter $x $y";
     455    }
     456    if ($coord_mask & $PSTAMP_RANGE_IN_PIXELS) {
     457        $roi_string .= " -pixrange $w $h";
     458    } else {
     459        $roi_string .= " -arcrange $w $h";
     460    }
     461
     462    my $component = $image->{component};
     463
     464    my $job_num = ++($row->{job_num});
     465
     466    my $imagefile = $image->{image};
     467    if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
     468        # XXX: should we add a faulted job so the client can know what happened if no images come back?
     469        # The test for destreaked is made in locate_images now so this code never runs. This leads to no feedback
     470        # to users, but speeds up processing significantly
     471        print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
     472
     473        # for now assume yes.
     474
     475        insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
     476        return 1;
     477    } elsif ($stage eq "stack") {
     478        # unconvolved stack images weren't available prior to some point in time.
     479        # XXX: handle this more correctly by examining the stack run's config dump file.
     480        # It looks like # the feature was turned on sometime around November 11, 2009. stackRun 30067 is the lowest
     481        # one that I found with an unconvolved image.
     482        my $MIN_GPC1_STACK_ID_WITH_UNCONVOLVED_IMAGES = 30067;
     483        if ($row->{unconvolved} and ($row->{PROJECT} eq 'gpc1') and
     484            ($image->{stack_id} < $MIN_GPC1_STACK_ID_WITH_UNCONVOLVED_IMAGES)) {
     485            print STDERR "Unconvolved stack image is not available for stackRun.stack_id: $image->{stack_id}\n";
     486            insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_AVAILABLE);
     487            return 1;
     488        }
     489    }
     490    my $exp_id = $image->{exp_id};
     491           
     492    my $args = $roi_string ? $roi_string : "";
     493    if ($stage eq "raw" or $stage eq "chip") {
     494        $args .= " -class_id $component" if $component;
     495    }
     496
     497    # add astrometry file for raw and chip images if one is available
     498    if (($stage eq "chip") || ($stage eq "raw")) {
     499        $args .= " -astrom $image->{astrom}" if $image->{astrom};
     500    }
     501
     502    $image->{job_args} = $args;
     503
     504    # XXX: we can get rid of the following everything that we need is
     505    # in the params file
     506
     507    $args .= " -file $imagefile";
     508
     509    if (($option_mask & $PSTAMP_SELECT_MASK) &&  $image->{mask} ) {
     510        $args .= " -mask $image->{mask}";
     511    }
     512    if (($option_mask & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {
     513        $args .= " -variance $image->{weight}";
     514    }
     515
     516    my $base = basename($image->{image});
     517    if (! $base =~ /.fits$/ ) {
     518        my_die("unexpected image file name found $image->{image}", $PS_EXIT_PROG_ERROR);
     519    }
     520    $base =~ s/.fits$//;
     521           
     522    my $output_base = "$out_dir/${rownum}_${job_num}_${base}";
     523    my $argslist = "${output_base}.args";
     524
     525    # copy the argument list to a file
     526    open ARGSLIST, ">$argslist" or my_die("failed to open $argslist", $PS_EXIT_UNKNOWN_ERROR);
     527    print ARGSLIST "$args\n";
     528    close ARGSLIST or my_die("failed to close $argslist", $PS_EXIT_UNKNOWN_ERROR);
     529
     530    write_params($output_base, $image);
     531
     532    my $newState = "run";
     533    my $fault = 0;
     534    my $dep_id;
     535
     536    # XXX: this code is repeated in queueGetImageJobs we should encapsulate it in a subroutine and share it
     537    if ($stage ne 'raw') {
     538        # updates for stack stage not supported yet
     539        my $allow_wait_for_update = ($stage ne 'stack');
     540        my $run_state = $image->{state};
     541        my $data_state = $image->{data_state};
     542        $data_state = $run_state if $stage eq 'stack';
     543        if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or
     544            ($run_state eq 'drop') or
     545            ($run_state eq 'error_cleaned') or ($data_state eq 'error_cleaned') or
     546            ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) {
     547            # image is gone and it's not coming back
     548            $newState = 'stop';
     549            $fault = $PSTAMP_GONE;
     550        } elsif (($data_state ne 'full') or ($need_magic and ($image->{magicked} < 0))) {
     551            if ($stage eq 'chip') {
     552                my $burntool_state = $image->{burntool_state};
     553                if ($burntool_state and (abs($burntool_state) < 14)) {
     554                    $newState = 'stop';
     555                    $fault = $PSTAMP_NOT_AVAILABLE;
     556                }
     557            }
     558            if (!$allow_wait_for_update) {
     559                print STDERR "wait for update not supported for stage $stage yet\n";
     560                $newState = 'stop';
     561                $fault = $PSTAMP_NOT_AVAILABLE;
     562            }
     563            if (!$fault) {
     564                # wait for update unless the customer asks us not to
     565                if (($option_mask & $PSTAMP_NO_WAIT_FOR_UPDATE)) {
     566                    $newState = 'stop';
     567                    $fault = $PSTAMP_NOT_AVAILABLE;
     568                } elsif (!$image->{magicked}) {
     569                    $newState = 'stop';
     570                    $fault = $PSTAMP_NOT_DESTREAKED;
     571                } else {
     572                    # cause the image to be re-made
     573                    # set up to queue an update run
     574                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{imagedb},
     575                        $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic);
     576                }
     577            }
     578        }
     579    }
     580
     581    my $command = "$pstamptool -addjob  -req_id $req_id -job_type $row->{JOB_TYPE}"
     582                    . " -outputBase $output_base -rownum $rownum -state $newState -options $option_mask";
     583    $command .= " -fault $fault" if $fault;
     584    $command .= " -exp_id $exp_id" if $exp_id;
     585    $command .= " -dep_id $dep_id" if $dep_id;
     586
     587    if (!$no_update) {
     588        # mode eq "queue_job"
     589        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     590            run(command => $command, verbose => $verbose);
     591        unless ($success) {
     592            print STDERR @$stderr_buf;
     593            # XXX TODO: now what? Should we mark the error state for the request?
     594            # should we keep going for other uris? If so how do we report that some
     595            # of the work that the request wanted isn't going to get done
     596            my_die("failed to queue job for request $req_id", $PS_EXIT_UNKNOWN_ERROR);
     597        }
     598    } else {
     599        print "skipping command: $command\n";
     600    }
     601
     602    return 1;
     603}
     604
     605# queue jobs for a collection of request specifications that have the same Images of Interest
     606sub queueJobs
     607{
     608    my $mode = shift;
     609    my $rowList = shift;
     610    my $imageList = shift;
     611
     612    my $firstRow = $rowList[0];
     613    my $stage    = $firstRow->{IMG_TYPE};
     614    my $job_type = $firstRow->{JOB_TYPE};
     615    my $need_magic = $firstRow->{need_magic};
     616
     617    my $num_jobs = 0;
     618
     619    if ($mode eq "list_uri") {
     620        foreach my $image (@$imageList) {
     621            print "$image->{image}\n";
     622        }
     623    } elsif ($job_type eq "get_image") {
     624        my $n = scalar @$rowList;
     625
     626        my_die( "error: unexpected number of rows for get_image request: $n", $PS_EXIT_PROG_ERROR) if $n != 1;
     627
     628        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
     629
     630    } else {
     631        if (!$imageList or (scalar @$imageList eq 0)) {
     632            # We didn't find any images for this set of rows. Insert a fake job to carry
     633            # the status back to the requestor.
     634            foreach my $row (@$rowList) {
     635                my $error_code = $row->{error_code};
     636                $error_code = $PSTAMP_NO_IMAGE_MATCH if !$error_code;
     637                insertFakeJobForRow($row, ++$row->{job_num}, $error_code);
     638                $num_jobs++;
     639            }
     640            return $num_jobs;
     641        }
     642
     643        foreach my $image (@$imageList) {
     644            # get the array of row indices that touch this image
     645            my $row_index = $image->{row_index};
     646            if (!$row_index or scalar @$row_index == 0) {
     647                # XXX should this happen? Why did something get returned.
     648                print "image ${stage}_id: $image->{stage_id} component: $image->{component} matched no rows\n";
     649                next;
     650            }
     651            # XXX: TODO: eventually we may change ppstamp to be able to make multiple stamps per invocation
     652
     653            foreach my $i (@$row_index) {
     654                my $row = $rowList->[$i];
     655
     656                $num_jobs += queueJobForImage($row, $stage, $image, $need_magic, $mode);
     657            }
     658        }
     659    }
     660
     661    return $num_jobs;
     662}
     663
     664#        $num_jobs = queueGetImageJobs($firstRow, $imageList, $stage, $need_magic, $mode);
     665sub queueGetImageJobs
     666{
     667    my $row = shift;
     668    my $imageList = shift;
     669    my $stage = shift;
     670    my $need_magic = shift;
     671    my $mode = shift;
     672
     673    my $num_jobs = 0;
     674    my $rownum = $row->{ROWNUM};
     675    my $option_mask = $row->{OPTION_MASK};
     676
     677    # For dist_bundle we need
     678    #  --camera from $image
     679    #  --stage
     680    #  --stage_id from $image
     681    #  --component from $image
     682    #  --path_base
     683    #  --outdir global to this script
    333684
    334685    # loop over images
    335     my $job_num = 0;
    336686    foreach my $image (@$imageList) {
    337         my $component;
    338         if ($have_skycells) {
    339             $component = $image->{skycell_id};
    340         } else {
    341             $component = $image->{class_id};
    342         }
    343 
    344         # skip this component if it is not in the list for this row
    345         next if ! $components->{$component};
    346 
    347         $job_num++;
     687        my $stage_id = $image->{stage_id};
     688        my $component = $image->{component};
     689
     690        # skip faulted components for now. Should we even be here?
     691        if ($image->{fault} > 0) {
     692            printf STDERR "skipping faulted component for $stage $stage_id $component\n" if $verbose;
     693            next;
     694        }
     695
     696        my $job_num = ++($row->{job_num});
    348697
    349698        my $imagefile = $image->{image};
    350699        if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
    351             # XXX: should we add a faulted job so the client can know what happened if no images come back?
    352             # This test is made in locate_images now so this code never runs. This leads to no feedback
    353             # to users, but speeds up processing significatnly
     700            # we only get here if req_type is (byid or byexp). For other types the test for magicked is performed
     701            # in locate_images because it's much more efficient to do the test in the database.
     702            # For these two modes we fall through to here in order to give feedback to the requestor as
     703            # to why the request failed to queue jobs.
    354704            print STDERR "skipping non-magicked image $imagefile\n" if $verbose;
    355 
    356             # for now assume yes.
    357 
    358705            insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED);
    359706            $num_jobs++;
     
    363710        my $exp_id = $image->{exp_id};
    364711           
    365         my $args = $roi_string ? $roi_string : "";
    366         if ($stage eq "raw" or $stage eq "chip") {
    367             $args .= " -class_id $component" if $component;
    368         }
    369 
    370         # add astrometry file for raw and chip images if one is available
    371         if (($stage eq "chip") || ($stage eq "raw")) {
    372             $args .= " -astrom $image->{astrom}" if $image->{astrom};
    373         }
    374 
    375         $args .= " -file $imagefile";
    376 
    377         if (($option_mask & $PSTAMP_SELECT_MASK) &&  $image->{mask} ) {
    378             $args .= " -mask $image->{mask}";
    379         }
    380         if (($option_mask & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {
    381             $args .= " -variance $image->{weight}";
    382         }
    383 
    384         my $base = basename($image->{path_base});
    385         # XXX: TODO use filerule for this. I don't have a camera defined here
    386         if (($stage eq 'chip') and ($image->{camera} eq 'GPC1')) {
    387             $base = "${base}.${component}";
    388         }
    389 
    390         my $output_base = "$out_dir/${rownum}_${job_num}_${base}";
    391         my $argslist = "${output_base}.args";
    392 
    393         # copy the argument list to a file
    394         open ARGSLIST, ">$argslist" or my_die("failed to open $argslist", $PS_EXIT_UNKNOWN_ERROR);
    395         print ARGSLIST "$args\n";
    396         close ARGSLIST or my_die("failed to close $argslist", $PS_EXIT_UNKNOWN_ERROR);
     712        my $output_base = "$out_dir/${rownum}_${job_num}";
     713
     714        write_params($output_base, $image);
    397715
    398716        my $newState = "run";
     
    409727                $newState = 'stop';
    410728                $fault = $PSTAMP_GONE;
    411             } elsif (($data_state ne 'full') or ($run_state ne 'full' )) {
    412                 # don't wait for update unless the caller asks us to
    413                 if (!($option_mask & $PSTAMP_WAIT_FOR_UPDATE)) {
     729            } elsif (($data_state ne 'full') or ($need_magic and ($image->{magicked} < 0))) {
     730                # wait for update unless the customer asks us to not to
     731                if ($option_mask & $PSTAMP_NO_WAIT_FOR_UPDATE) {
    414732                    $newState = 'stop';
    415733                    $fault = $PSTAMP_NOT_AVAILABLE;
     
    418736                    # set up to queue an update run
    419737                    queue_update_run(\$newState, \$fault, \$dep_id, $image->{image_db},
    420                         $run_state, $stage, $image->{stage_id}, $need_magic, $image->{label});
     738                        $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic);
    421739                }
    422740            }
     
    430748        $command .= " -dep_id $dep_id" if $dep_id;
    431749
    432         if ($mode eq "list_job") {
    433             # this is a debugging mode, just print the pstamptool that would have run
    434             # this is sort of like the mode -noupdate that some other tools support
    435             print "$command\n";
    436         } elsif (!$no_update) {
     750        if (!$no_update) {
    437751            # mode eq "queue_job"
    438752            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     
    451765    if ( $num_jobs == 0 ) {
    452766        print STDERR "no jobs for row $rownum\n" if $verbose;
    453         insertFakeJobForRow($row, 1, $PSTAMP_NO_OVERLAP);
     767        insertFakeJobForRow($row, 1, $PSTAMP_NO_JOBS_QUEUED);
    454768        $num_jobs = 1;
    455     }
    456     return $num_jobs;
    457 }
    458 
    459 # queue jobs for a collection of request specifications that have the same Images of Interest
    460 sub queueJobs
    461 {
    462     my $mode = shift;
    463     my $rowList = shift;
    464     my $imageList = shift;
    465 
    466     my $firstRow = $rowList[0];
    467     my $stage    = $firstRow->{IMG_TYPE};
    468     my $job_type = $firstRow->{JOB_TYPE};
    469     my $need_magic = $firstRow->{need_magic};
    470 
    471     my $num_jobs = 0;
    472 
    473     if ($mode eq "list_uri") {
    474         foreach my $image (@$imageList) {
    475             print "$image->{image}\n";
    476         }
    477     } elsif ($job_type eq "get_image") {
    478         print STDERR "get_image jobs not implemented yet" if $verbose;
    479         foreach my $row (@$rowList) {
    480             insertFakeJobForRow($row, 1, $PSTAMP_NOT_IMPLEMENTED);
    481             $num_jobs++;
    482         }
    483     } else {
    484         if (!$imageList or (scalar @$imageList eq 0)) {
    485             # we didn't find any images for this set of rows. Insert a fake job to carry
    486             # the status back to the requestor
    487             foreach my $row (@$rowList) {
    488                 insertFakeJobForRow($row, 1, $PSTAMP_NO_IMAGE_MATCH);
    489                 $num_jobs++;
    490             }
    491             return $num_jobs;
    492         }
    493 
    494         my $have_skycells;
    495         if (($stage eq "raw") or ($stage eq "chip")) {
    496             $have_skycells = 0;
    497         } else {
    498             $have_skycells = 1;
    499         }
    500        
    501         my $thisRun;
    502 
    503         my $npoints = 0;
    504         my ($pointsList, $pointsListName);
    505         if (scalar @$imageList > 1) {
    506             ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps);
    507             foreach my $row (@$rowList) {
    508                 $row->{components} = {};
    509                 if ($row->{skycenter}) {
    510                     print $pointsList "$row->{ROWNUM} $row->{CENTER_X} $row->{CENTER_Y}\n";
    511                     $npoints++;
    512                 } else {
    513                     # this row's center is in pixel coordinates add all images to the component list for this row
    514                     foreach my $i (@$imageList) {
    515                         my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id};
    516                         my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR)
    517                                 if !$component;
    518                         $row->{components}->{$component} = 1;
    519                     }
    520                 }
    521             }
    522             close $pointsList;
    523         } else {
    524             # only one image. Avoid the expense of dvoImagesAtCoords.
    525             # queue the job and let ppstamp figure out if the center is valid for the image
    526             # the resulting result code will be the same.
    527             foreach my $row (@$rowList) {
    528                 $row->{components} = {};
    529                 my $i = $imageList->[0];
    530                 my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id};
    531                 my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR) if !$component;
    532                 $row->{components}->{$component} = 1;
    533             }
    534         }
    535 
    536         my $tess_dir_abs;
    537         my $last_tess_id = "";
    538         while ($thisRun = getOneRun($stage, $imageList)) {
    539             if ($npoints) {
    540                 my_die( "pointsListName is not defined", $PS_EXIT_PROG_ERROR) if !$pointsListName;
    541                 # we collected a set of sky coordinates above.
    542                 # filter the images so that only those that contain the centers of the ROIs are processed
    543                 my $command = "$dvoImagesAtCoords $pointsListName";
    544                 if ($have_skycells) {
    545                     my $tess_id = $thisRun->[0]->{tess_id};
    546                     if ($tess_id ne $last_tess_id) {
    547                         $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id );
    548                         $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs );
    549                         $last_tess_id = $tess_id;
    550                     }
    551                     $command .= " -D CATDIR $tess_dir_abs";
    552                 } else {
    553                     my $astrom = $thisRun->[0]->{astrom};
    554                     my_die( "no astrometry file found", $PS_EXIT_UNKNOWN_ERROR) if !$astrom;
    555                     my $astrom_resolved = $ipprc->file_resolve($astrom);
    556                     $command .= " -astrom $astrom_resolved";
    557                 }
    558                 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    559                     run(command => $command, verbose => $verbose);
    560                 unless ($success) {
    561                     # don't fail if the program exited normally and exit status was PSTAMP_NO_OVERLAP
    562                     # That just means that the coordinate didn't match any image/skycell
    563                     if (!WIFEXITED($error_code) || (WEXITSTATUS($error_code) ne $PSTAMP_NO_OVERLAP)) {
    564                         print STDERR @$stderr_buf;
    565                         my $rc = WIFEXITED($error_code) ? WEXITSTATUS($error_code) : $PS_EXIT_SYS_ERROR;
    566                         my_die( "dvoImagesAtCoords failed: $rc", $rc);
    567                     }
    568                 }
    569                 # now we have a list of row numbers and components
    570                 # eventually we might want to multiple stamp requests for the same image
    571                 # into the same ppstamp job but not yet. For now we will queue a new
    572                 my @lines = split "\n", join "", @$stdout_buf;
    573                 foreach my $line (@lines) {
    574                     # parse the line, ignoring the ra and dec
    575                     my ($rownum, undef, undef, $component) = split " ", $line;
    576 
    577                     # I guess since we need this function we should be using a hash for rowList
    578                     my $row = findRow($rownum, $rowList);
    579                     $row->{components}->{$component} = 1;
    580                 }
    581             }
    582            
    583             foreach my $row (@$rowList) {
    584                 $num_jobs += queueJobsForRow($row, $stage, $thisRun, $have_skycells, $need_magic);
    585             }
    586         }
    587769    }
    588770    return $num_jobs;
     
    598780        $job_type = $row->{JOB_TYPE};
    599781        $rownum = $row->{ROWNUM};
     782        $rownum = 0 if !defined $rownum;
     783        if ($job_type) {
     784            if (($job_type ne "stamp") and ($job_type ne "get_image")) {
     785                print STDERR "invalid job type: $job_type found in row $rownum\n";
     786                $job_type = "none";
     787            }
     788        } else {
     789            print STDERR "undefined job type found in row $rownum\n";
     790            $job_type = "none";
     791        }
    600792    } else {
    601793        $job_type = "none";
     
    606798                        . " -rownum $rownum -state stop -fault $fault";
    607799
    608     if ($mode eq "list_job") {
    609         # this is a debugging mode, just print the pstamptool that would have run
    610         # this is sort of like the mode -noupdate that some other tools support
    611         print "$command\n";
    612     } elsif (!$no_update) {
     800    if (!$no_update) {
    613801        # mode eq "queue_job"
    614802        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     
    626814}
    627815
    628 sub get_run_id
    629 {
    630     my $stage = shift;
    631     my $image = shift;
    632 
    633     if ($stage eq "raw") {
    634         return $image->{exp_id};
    635     } elsif ($stage eq "chip") {
    636         return $image->{chip_id};
    637     } elsif ($stage eq "warp") {
    638         return $image->{warp_id};
    639     } elsif ($stage eq "stack") {
    640         return $image->{stack_id};
    641     } elsif ($stage eq "diff") {
    642         return $image->{diff_id};
    643     } else {
    644         my_die("unenexpected stage: $stage found", $PS_EXIT_PROG_ERROR);
    645     }
    646 }
    647 
    648 # extract components from the imageList that have the same run id and return the list
    649 sub getOneRun {
    650     my $stage = shift;
    651     my $imageList = shift;
    652 
    653     # return if array is empty
    654     return undef if ! @$imageList;
    655 
    656     my $last_run_id = 0;
    657     my @runList;
    658     while ($imageList->[0]) {
    659         my $run_id = get_run_id($stage, $imageList->[0]);
    660 
    661         last if ($last_run_id and ($run_id ne $last_run_id));
    662 
    663         my $image = shift @$imageList;
    664         $image->{stage} = $stage;
    665         push @runList, $image;
    666         $last_run_id = $run_id;
    667     }
    668     return \@runList;
    669 }
    670 
    671816sub same_images_of_interest {
    672817    my $r1 = shift;
    673818    my $r2 = shift;
    674819
    675     return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
    676     return 0 if ($r1->{JOB_TYPE} ne $r2->{JOB_TYPE});
     820    return 0 if (($r1->{REQ_TYPE} eq "bycoord")   or ($r2->{REQ_TYPE} eq "bycoord"));
     821    return 0 if (($r1->{JOB_TYPE} eq "get_image") or ($r2->{JOB_TYPE} eq "get_image"));
    677822    return 0 if ($r1->{REQ_TYPE} ne $r2->{REQ_TYPE});
    678823    return 0 if ($r1->{IMG_TYPE} ne $r2->{IMG_TYPE});
    679     return 0 if ($r1->{ID} ne $r2->{ID});
    680     return 0 if ($r1->{TESS_ID} ne $r2->{TESS_ID});
    681     return 0 if ($r1->{REQFILT} ne $r2->{REQFILT});
    682     return 0 if ($r1->{LABEL} ne $r2->{LABEL});
    683     return 0 if ($r1->{MJDMIN} ne $r2->{MJDMAX});
    684     return 0 if ($r1->{MJDMAX} ne $r2->{MJDMAX});
    685     return 0 if ($r1->{inverse} ne $r2->{inverse});
    686 
    687     if (defined($r1->{COMPONENT})) {
    688         return 0 if !defined $r2->{COMPONENT} or ($r1->{COMPONENT} ne $r2->{COMPONENT});
    689     } elsif (defined($r2->{COMPONENT})) {
    690         # if first row has no component all of the images will be retrieved, so
    691         # the fact that this row has a component is ok. Fall through to return 1
    692         # XXX Nope this doesn't work. It is consistent with the other logic in some way
    693         # that i haven't fully thought through
    694         return 0;
    695     }
     824    return 0 if ($r1->{ID}       ne $r2->{ID});
     825    return 0 if ($r1->{TESS_ID}  ne $r2->{TESS_ID});
     826    return 0 if ($r1->{COMPONENT}  ne $r2->{COMPONENT});
     827    return 0 if ($r1->{REQFILT}  ne $r2->{REQFILT});
     828    return 0 if ($r1->{DATA_GROUP}    ne $r2->{DATA_GROUP});
     829    return 0 if ($r1->{MJD_MIN}  ne $r2->{MJD_MAX});
     830    return 0 if ($r1->{MJD_MAX}  ne $r2->{MJD_MAX});
     831    return 0 if ($r1->{OPTION_MASK}  ne $r2->{OPTION_MASK});
     832    return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
     833    return 0 if ($r1->{inverse}  ne $r2->{inverse});
     834    return 0 if ($r1->{unconvolved}  ne $r2->{unconvolved});
     835    # don't combine requests in pixel coordinates
     836    return 0 if (($r1->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS) || ($r2->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS));
    696837
    697838    return 1;
     
    702843    my $val = shift;
    703844
    704     return $val =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
     845    return 0 if !defined $val;
     846
     847    return ($val =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/);
     848}
     849sub validID
     850{
     851    my $val = shift;
     852
     853    return 0 if !$val;
     854
     855    return  ! ($val =~ /\D/);
    705856}
    706857
     
    729880sub queue_update_run
    730881{
    731     my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $need_magic, $label) = @_;
     882    my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $component, $need_magic) = @_;
    732883
    733884    if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) {
     
    736887
    737888    my $dep_id;
    738     my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb";
    739     $command .= " -rlabel $label" if $label;
    740     $command .= " -no_magic" if !$need_magic;
     889    my $command = "$pstamptool -getdependent -stage $stage -stage_id $stage_id -imagedb $imagedb -component $component";
     890    $command .= " -need_magic" if $need_magic;
     891
     892    # compute rlabel for the run.
     893    # XXX: This bit of policy shouldn't be buried so deeply in the code
     894    # For now use one that implies 'postage stamp server' 'update' 'request_label"
     895    my $rlabel = "ps_ud_" . $label if $label;
     896    $command .= " -rlabel $rlabel" if $rlabel;
     897
    741898    if (!$no_update) {
    742899        my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     
    748905        chomp $output;
    749906        $dep_id = $output;
     907        #
     908        # XXX: need to fault the request or something
    750909        my_die("pstamptool -getdependent returned invalid dep_id", $PS_EXIT_PROG_ERROR) if !$dep_id;
    751910    } else {
     
    755914   
    756915    $$r_dep_id = $dep_id;
    757     $r_fault = 0;
    758     $r_jobState = 'blocked';
     916    $$r_fault = 0;
     917    $$r_jobState = 'run';
     918}
     919
     920sub write_params {
     921    my $output_base = shift;
     922    my $image = shift;
     923
     924    # write the contents of this "image" as a metadata config doc
     925    # Simply treat all values as strings. This is ok since we are only going to
     926    # read it from another perl script
     927    my $mdc_file = "${output_base}.mdc";
     928    open P, ">$mdc_file" or my_die("failed to open $mdc_file", $PS_EXIT_UNKNOWN_ERROR);
     929
     930    print P "params METADATA\n";
     931
     932    foreach my $key (keys %$image) {
     933        my $value = $image->{$key};
     934        if (defined $value) {
     935            printf P "  %-20s STR     %s\n", $key, $value;
     936        } else {
     937            printf P "  %-20s STR     NULL\n", $key;
     938        }
     939    }
     940
     941    print P "END\n";
     942    close P or my_die("failed to close $mdc_file", $PS_EXIT_UNKNOWN_ERROR);
     943}
     944
     945sub check_image_type
     946{
     947    my $img_type = shift;
     948    if (!$img_type) {
     949            print STDERR "NULL IMG_TYPE supplied\n";
     950            return 0;
     951    }
     952    if (($img_type eq "raw") or ($img_type eq "chip") or ($img_type eq "warp") or
     953        ($img_type eq "stack") or ($img_type eq "diff")) {
     954        return 1;
     955    } else {
     956        print STDERR "$img_type is not a valid IMG_TYPE\n";
     957        return 0;
     958    }
    759959}
    760960
     
    768968    # we don't fault the request here pstamp_parser_run.pl handles that if necessary
    769969
    770     return $fault;
    771 }
     970    exit $fault;
     971}
Note: See TracChangeset for help on using the changeset viewer.