IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 7, 2009, 12:45:24 PM (17 years ago)
Author:
eugene
Message:

update from mainline

Location:
branches/eam_branches/20090715
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715

  • branches/eam_branches/20090715/pstamp/scripts/pstampparse.pl

    r23267 r25022  
    1313use PS::IPP::PStamp::RequestFile qw( :standard );
    1414use PS::IPP::PStamp::Job qw( :standard );
     15use File::Temp qw(tempfile);
    1516
    1617my $verbose;
    1718my $dbname;
     19my $dbserver;
    1820my $req_id;
    1921my $request_file_name;
     
    2123my $out_dir;
    2224my $product;
     25my $save_temps;
     26my $no_update;
    2327
    2428GetOptions(
     
    2933    'mode=s'    =>  \$mode,
    3034    'dbname=s'  =>  \$dbname,
     35    'dbserver=s'=>  \$dbserver,
    3136    'verbose'   =>  \$verbose,
     37    'save-temps'=>  \$save_temps,
     38    'no-update' =>  \$no_update,
    3239);
    3340
     
    5461my $pstamptool  = can_run('pstamptool')  or (warn "Can't find pstamptool"  and $missing_tools = 1);
    5562my $pstampdump  = can_run('pstampdump') or (warn "Can't find pstampdump" and $missing_tools = 1);
     63my $dvoImagesAtCoords  = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" and $missing_tools = 1);
    5664my $fields  = can_run('fields') or (warn "Can't find fields" and $missing_tools = 1);
    5765
     
    6068    exit ($PS_EXIT_CONFIG_ERROR);
    6169}
     70
     71$no_update = 1 if $mode eq "list_job";
    6272
    6373my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files
     
    8595die "wrong EXTVER $extver found in $request_file_name" if ($extver ne "1");
    8696
    87 if ($req_id) {
     97if ($req_id and !$no_update) {
    8898    my $command = "$pstamptool -updatereq -req_id $req_id  -name $req_name";
    8999    $command .= " -outProduct $product";
    90100    $command .= " -dbname $dbname" if $dbname;
     101    $command .= " -dbserver $dbserver" if $dbserver;
    91102    my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    92103        run(command => $command, verbose => $verbose);
     
    114125}
    115126
     127my @rowList;
    116128my $num_jobs = 0;
     129my $imageList;
     130my $stage;
     131my $need_magic;
    117132foreach my $row (@$rows) {
     133    # XXX: TODO: sanity check all parameters
     134
     135    # XXX: TODO: We shouldn't really just die in this loop.
     136    # If we encounter an error for a particular row
     137    # add a job with the proper fault code. If there is a db or config error we should probably just
     138    # trash the request.
     139
    118140    my $rownum   = $row->{ROWNUM};
    119141    my $job_type = $row->{JOB_TYPE};
     142   
     143    # parameters that select the images of interest
    120144    my $project  = $row->{PROJECT};
    121145    my $req_type = $row->{REQ_TYPE};
    122     my $img_type = $row->{IMG_TYPE};
     146    $stage = $row->{IMG_TYPE};
    123147    my $id       = $row->{ID};
    124     my $class_id = $row->{CLASS_ID};
     148    my $component = $row->{COMPONENT};
     149
    125150    my $filter   = $row->{REQFILT};
    126151    my $mjd_min = $row->{MJD_MIN};
    127152    my $mjd_max = $row->{MJD_MAX};
    128     my $x = $row->{CENTER_X};
    129     my $y = $row->{CENTER_Y};
    130     my $w = $row->{WIDTH};
    131     my $h = $row->{HEIGHT};
    132     my $coord_mask = $row->{COORD_MASK};
     153
    133154    my $option_mask= $row->{OPTION_MASK};
    134155
    135     $class_id = "" if ($class_id eq "null" or $class_id eq "all");
     156    die "valid region of interest is required to make postage stamps"
     157        if (($job_type eq "stamp") and ! validROI($row));
     158
     159    my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS);
     160    $component = "" if (defined($component) and ($component eq "null" or $component eq "all"));
    136161   
    137     # XXX: TODO: sanity check all parameters
    138 
    139     # XXX: TODO: We shouldn't just die in this loop.
    140     # If we encounter an error for a particular row
    141     # add a job with the proper fault code. If there is a db or config error we should probably just
    142     # trash the request.
    143162    die "job_type is list_uri but mode is $mode" if ($job_type eq "list_uri") and ($mode ne "list_uri");
    144163
    145     my $proj_hash = resolve_project($ipprc, $project, $dbname);
     164
     165    # note: resolve_project avoids running pstamptool every time by remembering the
     166    # last project resolved
     167    my $proj_hash = resolve_project($ipprc, $project, $dbname, $dbserver);
    146168    die "project $project not found\n" unless $proj_hash;
    147169
    148     my $image_db = $proj_hash->{dbname};
    149     my $camera = $proj_hash->{camera};
    150     my $need_magic = $proj_hash->{need_magic};
    151 
    152     my $roi_string;
    153     # XXX we're depending on other code to insure valid values for roi components
    154     # this is checked in and ppstamp but I should check here so that we don't get that far,
    155     # but not today
    156     if ($x && ($x ne "null") && $y && ($y ne "null") && $w && ($w ne "null") && $h && ($h ne "null")) {
    157         if ($coord_mask & $PSTAMP_CENTER_IN_PIXELS) {
    158             $roi_string = "-pixcenter $x $y";
     170    my $image_db   = $proj_hash->{dbname};
     171    my $camera     = $proj_hash->{camera};
     172    $need_magic = $proj_hash->{need_magic};
     173
     174    # collect rows with the same images of interest in a list so that they
     175    # can be processed optimially
     176    if (@rowList) {
     177        my $firstRow = $rowList[0];
     178        # XXX: the collecting might work with !$skycenter but I need to think about it
     179        if ($skycenter and same_images_of_interest($row, $firstRow)) {
     180            push @rowList, $row;
     181            # On to the next row
     182            next;
    159183        } else {
    160             $roi_string = "-skycenter $x $y";
    161         }
    162         if ($coord_mask & $PSTAMP_RANGE_IN_PIXELS) {
    163             $roi_string .= " -pixrange $w $h";
    164         } else {
    165             $roi_string .= " -arcrange $w $h";
    166         }
    167     }
    168 
    169     die "region of interest is required to make postage stamps"
    170         if (($job_type eq "stamp") && !defined($roi_string));
    171 
    172     # find the uris for this request
     184            # queue the jobs for this set of rows
     185            $num_jobs += queueJobs($mode, \@rowList, $imageList);
     186            @rowList = ();
     187        }
     188    }
    173189
    174190    if ($req_type eq "bycoord") {
    175         die "region of interest is required for request type bycoord" if !defined($roi_string) ;
    176         die "center must be specified in sky coordintes for bycoord"
    177             if ($coord_mask & $PSTAMP_CENTER_IN_PIXELS);
    178     }
    179 
    180     # Call PS::IPP::PStamp::Job's locate_images routine to get the parameters for this request specification
    181     my $images = locate_images($ipprc, $image_db, $req_type, $img_type, $id, $class_id,
    182             $x, $y, $mjd_min, $mjd_max, $filter, $verbose);
    183 
    184     if (!$images) {
     191        die "center must be specified in sky coordintes for bycoord" if ( ! $skycenter);
     192        die "lookup bycoord is not yet implemented";
     193    } else {
     194
     195        # Call PS::IPP::PStamp::Job's locate_images routine to get the parameters for this
     196        # request specification. An array reference is returned
     197        my ($x, $y);
     198        $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $component, $skycenter,
     199                $x, $y, $mjd_min, $mjd_max, $filter, $verbose);
     200    }
     201
     202    if (!$imageList or !@$imageList) {
    185203        print STDERR "no matching images found for row $rownum\n";
    186204        next;
    187205    }
    188     if ($mode eq "list_uri") {
    189         foreach my $image (@$images) {
    190             print "$image->{image}\n";
    191         }
    192     } elsif ($job_type eq "get_image") {
    193         # XXX TODO: Get rid of this block and use the same code as the stamp jobs
    194         # XXX This doesn't work to get the mask and weight images
    195         my $listfile = "$out_dir/filelist";
    196 
    197 
    198         # map our img_type to the Data Store file types.
    199         my %filelist_img_types = ( "raw" => "chip",
    200                                    "chip" => "chipproc",
    201                                    "warp" => "warp",
    202                                    "stack"=>"stack",
    203                                    "diff" => "diff");
    204 
    205         my $filelist_img_type = $filelist_img_types{$img_type};
    206 
    207         open LISTFILE, ">$listfile"
    208             or die "failed to open file list: $listfile while parsing get_image request $req_id";
    209 
    210         foreach my $image (@$images) {
    211             my $class_id = $image->{class_id} ? $image->{class_id} : "";
    212             print LISTFILE "$image->{image}|$filelist_img_type|$class_id|\n";
    213         }
    214         close LISTFILE;
    215         $num_jobs++;
    216         my $command = "$pstamptool -addjob -req_id $req_id -job_type get_image"
    217                     . " -uri $listfile -outputBase $out_dir -rownum $rownum";
    218         $command .= " -dbname $dbname" if $dbname;
    219         if ($mode eq "list_job") {
    220             print "$command\n";
    221         } else {
    222             my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    223                 run(command => $command, verbose => $verbose);
    224             unless ($success) {
    225                 print STDERR @$stderr_buf;
    226                 # XXX TODO: now what? Should we mark the error state for the request?
    227                 die "failed to queue job for request $req_id: rownum: $rownum";
    228             }
    229         }
    230     } else {
    231         # sequence number for the the job for a request spec. Not to be confused with job_id
    232         my $job_num = 0;
    233 
    234         # XXX TODO: for raw and chip level images and class_id "null" if there are multiple images
    235         # use -list instead of -file
    236         foreach my $image (@$images) {
    237             my $uri = $image->{image};
    238             my $exp_id = $image->{exp_id};
    239            
    240             my $args = $roi_string ? $roi_string : "";
    241             $args .= " -class_id $class_id" if $class_id;
    242 
    243             $job_num++;
    244 
    245             my $output_base = "$out_dir/${rownum}_${job_num}";
    246 
    247             # add astrometry file for raw and chip images if one is available
    248             if (($img_type eq "chip") || ($img_type eq "raw")) {
    249                 $args .= " -astrom $image->{astrom}" if $image->{astrom};
    250             }
    251 
    252             if (($option_mask & $PSTAMP_SELECT_MASK) &&  $image->{mask} ) {
    253                 $args .= " -mask $image->{mask}";
    254             }
    255             if (($option_mask & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {
    256                 $args .= " -weight $image->{weight}";
    257             }
    258 
    259             # XXX sounds like magic will be handled outside of the postage stamp server
    260             #if ($need_magic) {
    261             #    die "no magic mask available" if ! $image->{magic_mask};
    262             #    $args .= " -magic_mask $image->{magic_mask}"
    263             #}
    264 
    265             # XXX: TODO: here is where we need to check whether or not the source inputs still exist
    266             # and if not, queue a regeneration job and set the job state appropriately.
    267 
    268             my $state = "run";
    269 
    270             $num_jobs++;
    271             my $command = "$pstamptool -addjob -req_id $req_id -job_type $job_type"
    272                 . " -uri $uri -outputBase $output_base -args '$args' -rownum $rownum"
    273                 . " -state $state";
    274             $command .= " -exp_id $exp_id" if $exp_id;
    275             $command .= " -dbname $dbname" if $dbname;
    276 
    277             if ($mode eq "list_job") {
    278                 # this is a debugging mode, just print the pstamptool that would have run
    279                 # this is sort of like the mode -noupdate that some other tools support
    280                 print "$command\n";
    281             } else {
    282                 # mode eq "queue_job"
    283                 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
    284                     run(command => $command, verbose => $verbose);
    285                 unless ($success) {
    286                     print STDERR @$stderr_buf;
    287                     # XXX TODO: now what? Should we mark the error state for the request?
    288                     # should we keep going for other uris? If so how do we report that some
    289                     # of the work that the request wanted isn't going to get done
    290                     die "failed to queue job for request $req_id";
    291                 }
    292             }
    293         }
    294     }
     206    $row->{need_magic} = $need_magic;
     207    push @rowList, $row;
     208}
     209
     210if (@rowList) {
     211    $num_jobs += queueJobs($mode, \@rowList, $imageList);
    295212}
    296213
     
    306223    exit 0;
    307224}
     225
     226
     227sub queueJobsForRow
     228{
     229    my $row = shift;
     230    my $stage = shift;
     231    my $imageList = shift;
     232    my $have_skycells = shift;
     233    my $need_magic = shift;
     234
     235    # loop over images
     236    my $job_num = 0;
     237    foreach my $image (@$imageList) {
     238        my $component;
     239        if ($have_skycells) {
     240            $component = $image->{skycell_id};
     241        } else {
     242            $component = $image->{class_id};
     243        }
     244
     245        # skip this component if it is not in the list for this row
     246        next if !$row->{components}->{$component};
     247
     248        my $rownum = $row->{ROWNUM};
     249
     250        my $roi_string;
     251
     252        # note values were insured to be numbers in validROI()
     253        my $x = $row->{CENTER_X};
     254        my $y = $row->{CENTER_Y};
     255        my $w = $row->{WIDTH};
     256        my $h = $row->{HEIGHT};
     257        my $coord_mask = $row->{COORD_MASK};
     258        if ($x && ($x ne "null") && $y && ($y ne "null") && $w && ($w ne "null") && $h && ($h ne "null")) {
     259            if ($coord_mask & $PSTAMP_CENTER_IN_PIXELS) {
     260                $roi_string = "-pixcenter $x $y";
     261            } else {
     262                $roi_string = "-skycenter $x $y";
     263            }
     264            if ($coord_mask & $PSTAMP_RANGE_IN_PIXELS) {
     265                $roi_string .= " -pixrange $w $h";
     266            } else {
     267                $roi_string .= " -arcrange $w $h";
     268            }
     269        }
     270
     271        my $imagefile = $image->{image};
     272        if (($stage ne "stack") and ($need_magic and !$image->{magicked})) {
     273            # XXX: should we add a faulted job so the client can know what happened?
     274            print STDERR "skippping non-magicked image $imagefile\n" if $verbose;
     275            next;
     276        }
     277        my $exp_id = $image->{exp_id};
     278           
     279        my $args = $roi_string ? $roi_string : "";
     280        if ($stage eq "raw" or $stage eq "chip") {
     281            $args .= " -class_id $component" if $component;
     282        }
     283
     284        $job_num++;
     285
     286        # add astrometry file for raw and chip images if one is available
     287        if (($stage eq "chip") || ($stage eq "raw")) {
     288            $args .= " -astrom $image->{astrom}" if $image->{astrom};
     289        }
     290
     291        $args .= " -file $imagefile";
     292
     293        if (($row->{OPTION_MASK} & $PSTAMP_SELECT_MASK) &&  $image->{mask} ) {
     294            $args .= " -mask $image->{mask}";
     295        }
     296        if (($row->{OPTION_MASK} & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {
     297            $args .= " -variance $image->{weight}";
     298        }
     299
     300        my $output_base = "$out_dir/${rownum}_${job_num}";
     301        my $argslist = "${output_base}.args";
     302
     303        # copy the argument list to a file
     304        open ARGSLIST, ">$argslist" or die "failed to open $argslist";
     305        print ARGSLIST "$args\n";
     306        close ARGSLIST or die "failed to close $argslist";
     307
     308        # XXX: TODO: here is where we need to check whether or not the source inputs still exist
     309        # and if not, queue an update job and set the job state appropriately.
     310
     311        my $newState = "run";
     312
     313        $num_jobs++;
     314        my $command = "$pstamptool -addjob  -req_id $req_id -job_type $row->{JOB_TYPE}"
     315                        . " -outputBase $output_base -rownum $rownum -state $newState";
     316        $command .= " -exp_id $exp_id" if $exp_id;
     317        $command .= " -dbname $dbname" if $dbname;
     318        $command .= " -dbserver $dbserver" if $dbserver;
     319
     320        if ($mode eq "list_job") {
     321            # this is a debugging mode, just print the pstamptool that would have run
     322            # this is sort of like the mode -noupdate that some other tools support
     323            print "$command\n";
     324        } elsif (!$no_update) {
     325            # mode eq "queue_job"
     326            my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     327                run(command => $command, verbose => $verbose);
     328            unless ($success) {
     329                print STDERR @$stderr_buf;
     330                # XXX TODO: now what? Should we mark the error state for the request?
     331                # should we keep going for other uris? If so how do we report that some
     332                # of the work that the request wanted isn't going to get done
     333                die "failed to queue job for request $req_id";
     334            }
     335        } else {
     336            print "skipping command: $command\n";
     337        }
     338    }
     339    return $num_jobs;
     340}
     341
     342sub queueJobs
     343{
     344    my $mode = shift;
     345    my $rowList = shift;
     346    my $imageList = shift;
     347
     348    my $firstRow = $rowList[0];
     349    my $stage    = $firstRow->{IMG_TYPE};
     350    my $job_type = $firstRow->{JOB_TYPE};
     351    my $need_magic = $firstRow->{need_magic};
     352
     353    my $num_jobs = 0;
     354
     355    if ($mode eq "list_uri") {
     356        foreach my $image (@$imageList) {
     357            print "$image->{image}\n";
     358        }
     359    } elsif ($job_type eq "get_image") {
     360        die "get_image jobs not implemented yet";
     361    } else {
     362        my $thisRun;
     363
     364        my ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps);
     365        foreach my $row (@$rowList) {
     366            print $pointsList "$row->{ROWNUM} $row->{CENTER_X} $row->{CENTER_Y}\n";
     367            $row->{components} = {};
     368        }
     369        close $pointsList;
     370
     371        my $have_skycells;
     372        if (($stage eq "raw") or ($stage eq "chip")) {
     373            $have_skycells = 0;
     374        } else {
     375            $have_skycells = 1;
     376        }
     377       
     378        my $tess_dir_abs;
     379        my $last_tess_id = "";
     380        while ($thisRun = getOneRun($stage, $imageList)) {
     381            {
     382                my $command = "$dvoImagesAtCoords $pointsListName";
     383                if ($have_skycells) {
     384                    my $tess_id = $thisRun->[0]->{tess_id};
     385                    if ($tess_id ne $last_tess_id) {
     386                        $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id );
     387                        $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs );
     388                        $last_tess_id = $tess_id;
     389                    }
     390                    $command .= " -D CATDIR $tess_dir_abs";
     391                } else {
     392                    my $astrom = $thisRun->[0]->{astrom};
     393                    die "no astrometry file found" if !$astrom;
     394                    my $astrom_resolved = $ipprc->file_resolve($astrom);
     395                    $command .= " -astrom $astrom_resolved";
     396                }
     397                my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
     398                    run(command => $command, verbose => $verbose);
     399                unless ($success) {
     400                    print STDERR @$stderr_buf;
     401                    my $rc = $error_code >> 8;
     402                    die "dvoImagesAtCoords failed: $rc";
     403                }
     404                # now we have a list of row numbers and components
     405                # eventually we might want to multiple stamp requests for the same image
     406                # into the same ppstamp job but not yet. For now we will queue a new
     407                my @lines = split "\n", join "", @$stdout_buf;
     408                foreach my $line (@lines) {
     409                    # parse the line, ignoring the ra and dec
     410                    my ($rownum, undef, undef, $component) = split " ", $line;
     411
     412                    # I guess since we need this function we should be useing a hash for rowList
     413                    my $row = findRow($rownum, $rowList);
     414                    $row->{components}->{$component} = 1;
     415                }
     416            }
     417           
     418            foreach my $row (@$rowList) {
     419                $num_jobs += queueJobsForRow($row, $stage, $thisRun, $have_skycells, $need_magic);
     420            }
     421        }
     422    }
     423    return $num_jobs;
     424}
     425
     426sub get_run_id
     427{
     428    my $stage = shift;
     429    my $image = shift;
     430
     431    if ($stage eq "raw") {
     432        return $image->{exp_id};
     433    } elsif ($stage eq "chip") {
     434        return $image->{chip_id};
     435    } elsif ($stage eq "warp") {
     436        return $image->{warp_id};
     437    } elsif ($stage eq "stack") {
     438        return $image->{stack_id};
     439    } elsif ($stage eq "diff") {
     440        return $image->{diff_id};
     441    } else {
     442        die "unenexpected stage: $stage found";
     443    }
     444}
     445
     446# extract components from the imageList that have the same run id and return the list
     447sub getOneRun {
     448    my $stage = shift;
     449    my $imageList = shift;
     450
     451    # return if array is empty
     452    return undef if ! @$imageList;
     453
     454    my $last_run_id = 0;
     455    my @runList;
     456    while ($imageList->[0]) {
     457        my $run_id = get_run_id($stage, $imageList->[0]);
     458
     459        last if ($last_run_id and ($run_id ne $last_run_id));
     460
     461        my $image = shift @$imageList;
     462        $image->{stage} = $stage;
     463        push @runList, $image;
     464        $last_run_id = $run_id;
     465    }
     466    return \@runList;
     467}
     468
     469sub same_images_of_interest {
     470    my $r1 = shift;
     471    my $r2 = shift;
     472
     473    return 0 if ($r1->{PROJECT}  ne $r2->{PROJECT});
     474    return 0 if ($r1->{JOB_TYPE} ne $r2->{JOB_TYPE});
     475    return 0 if ($r1->{REQ_TYPE} ne $r2->{REQ_TYPE});
     476    return 0 if ($r1->{IMG_TYPE} ne $r2->{IMG_TYPE});
     477    return 0 if ($r1->{ID} ne $r2->{ID});
     478
     479    if (defined($r1->{COMPONENT})) {
     480        return 0 if !defined $r2->{COMPONENT} or ($r1->{COMPONENT} ne $r2->{COMPONENT});
     481    } elsif (defined($r2->{COMPONENT})) {
     482        return 0;
     483    }
     484
     485    return 1;
     486}
     487
     488sub validNumber
     489{
     490    my $val = shift;
     491
     492    return $val =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
     493}
     494
     495sub validROI
     496{
     497    my $row = shift;
     498    return 0 if !validNumber($row->{CENTER_X});
     499    return 0 if !validNumber($row->{CENTER_Y});
     500    return 0 if !validNumber($row->{WIDTH});
     501    return 0 if !validNumber($row->{HEIGHT});
     502
     503    return 1;
     504}
     505
     506sub findRow
     507{
     508    my $rownum = shift;
     509    my $rowList = shift;
     510
     511    foreach my $row (@$rowList) {
     512        return $row if $row->{ROWNUM} eq $rownum;
     513    }
     514    return undef;
     515}
Note: See TracChangeset for help on using the changeset viewer.