- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
pstamp/scripts/pstampparse.pl (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_branches/pstamp/scripts/pstampparse.pl
r25058 r27840 14 14 use PS::IPP::PStamp::Job qw( :standard ); 15 15 use File::Temp qw(tempfile); 16 use File::Basename qw(basename); 17 use Carp; 18 use POSIX; 19 use DateTime; 16 20 17 21 my $verbose; … … 23 27 my $out_dir; 24 28 my $product; 29 my $label; 25 30 my $save_temps; 26 31 my $no_update; … … 31 36 'out_dir=s' => \$out_dir, 32 37 'product=s' => \$product, 38 'label=s' => \$label, 33 39 'mode=s' => \$mode, 34 40 'dbname=s' => \$dbname, … … 39 45 ); 40 46 41 die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq " list_job") or ($mode eq "queue_job");47 die "invalid mode '$mode'" unless ($mode eq "list_uri") or ($mode eq "queue_job"); 42 48 die "--file is required" if !defined($request_file_name); 43 49 … … 61 67 my $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools = 1); 62 68 my $pstampdump = can_run('pstampdump') or (warn "Can't find pstampdump" and $missing_tools = 1); 63 my $dvoImagesAtCoords = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" and $missing_tools = 1);64 69 my $fields = can_run('fields') or (warn "Can't find fields" and $missing_tools = 1); 65 70 … … 69 74 } 70 75 76 # just deal with these arguments once and for all 77 $pstamptool .= " -dbname $dbname" if $dbname; 78 $pstamptool .= " -dbserver $dbserver" if $dbserver; 79 80 # list_job is a deugging mode 71 81 $no_update = 1 if $mode eq "list_job"; 72 82 … … 90 100 91 101 # make sure the file contains what we are expecting 92 93 # we shouldn't get here if this is the case so just die.No need to notify the client102 # This program shouldn't have been run if the request file is bogus. 103 # No need to notify the client 94 104 my_die("$request_file_name is not a PS1_PS_REQEST", $PS_EXIT_PROG_ERROR) if $extname ne "PS1_PS_REQUEST"; 95 105 my_die("REQ_NAME not found in $request_file_name", $PS_EXIT_PROG_ERROR) if (!$req_name); 96 106 my_die("wrong EXTVER $extver found in $request_file_name", $PS_EXIT_PROG_ERROR) if ($extver ne "1"); 107 108 109 # check for duplicate request name 110 my $duplicate_req_name = 0; 111 if ($req_id and !$no_update) { 112 my $command = "$pstamptool -listreq -name $req_name -not_req_id $req_id"; 113 # no verbose so that error message about request not found doesn't appear in parse_error.txt 114 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 115 run(command => $command, verbose => 0); 116 my $exitStatus = $error_code >> 8; 117 if ($success) { 118 # -listreq succeeded duplicate request name 119 print STDERR "REQ_NAME $req_name has already been used\n"; 120 insertFakeJobForRow(undef, 0, $PSTAMP_DUP_REQUEST); 121 $duplicate_req_name = 1; 122 my $datestr = strftime "%Y%m%d%H%M%S.$req_id", gmtime; 123 $req_name = "ERROR.$datestr"; 124 #exit 0; 125 } 126 } 97 127 98 128 if ($req_id and !$no_update) { … … 101 131 my $command = "$pstamptool -updatereq -req_id $req_id -name $req_name"; 102 132 $command .= " -outProduct $product"; 103 $command .= " -dbname $dbname" if $dbname;104 $command .= " -dbserver $dbserver" if $dbserver;105 133 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 106 134 run(command => $command, verbose => $verbose); … … 108 136 my_die("$command failed", $PS_EXIT_UNKNOWN_ERROR); 109 137 } 138 } 139 if ($duplicate_req_name) { 140 exit 0; 110 141 } 111 142 … … 122 153 print STDERR @$stderr_buf; 123 154 } 124 my $table = $mdcParser->parse(join "", @$stdout_buf) or 125 my_die("Unable to parse metdata config doc", $PS_EXIT_UNKNOWN_ERROR); 126 127 $rows = parse_md_list($table); 128 } 129 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 # 130 169 my @rowList; 131 170 my $num_jobs = 0; … … 134 173 my $need_magic; 135 174 foreach my $row (@$rows) { 136 # XXX: TODO: sanity check all parameters 137 138 # XXX: TODO: We shouldn't really just die in this loop. 139 # If we encounter an error for a particular row 140 # add a job with the proper fault code. If there is a db or config error we should probably just 141 # trash the request. 142 143 my $rownum = $row->{ROWNUM}; 144 my $job_type = $row->{JOB_TYPE}; 145 146 # parameters that select the images of interest 147 my $project = $row->{PROJECT}; 148 my $req_type = $row->{REQ_TYPE}; 149 $stage = $row->{IMG_TYPE}; 150 my $id = $row->{ID}; 151 my $component = $row->{COMPONENT}; 152 153 my $filter = $row->{REQFILT}; 154 my $mjd_min = $row->{MJD_MIN}; 155 my $mjd_max = $row->{MJD_MAX}; 156 157 my $option_mask= $row->{OPTION_MASK}; 158 159 my $skycenter = $row->{skycenter} = ! ($row->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS); 160 161 my $search_component = (!defined($component) or ($component eq "null")) ? "" : $component; 162 163 if (!$skycenter and !$search_component) { 164 print STDERR "COMPONENT must be specified for pixel coordinate ROI\n" if $verbose; 165 insertFakeJobForRow($row, 1, 45); 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 166 178 $num_jobs++; 167 179 next; 168 180 } 169 170 $search_component = "" if $search_component eq "all"; 171 172 if (($job_type eq "stamp") and ! validROI($row)) { 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 206 if (scalar @rowList > 0) { 207 $num_jobs += processRows(\@rowList); 208 } 209 210 if (($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 215 exit 0; 216 217 sub 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. 222 223 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 } 229 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 } 235 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)) { 173 303 print STDERR "invalid ROI for row $rownum\n" if $verbose; 174 insertFakeJobForRow($row, 1, 46); 175 $num_jobs++; 176 next; 177 } 178 179 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 180 314 # $mode list_uri is a debugging mode (it may used by the http interface) 181 315 # if this happens just croak 182 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"); 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 338 sub 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 345 my $project = $row->{PROJECT}; 183 346 184 347 # note: resolve_project avoids running pstamptool every time by remembering the … … 187 350 if (!$proj_hash) { 188 351 print STDERR "project $project not found\n" if $verbose; 189 insertFakeJobForRow($row, 1, 46); 190 $num_jobs++; 191 next; 192 } 193 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}; 361 my $component = $row->{COMPONENT}; 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}; 371 my $option_mask= $row->{OPTION_MASK}; 372 194 373 my $image_db = $proj_hash->{dbname}; 195 374 my $camera = $proj_hash->{camera}; 196 $need_magic = $proj_hash->{need_magic};197 198 # collect rows with the same images of interest in a list so that they199 # can be processed optimially200 if ( @rowList) {201 my $firstRow = $rowList[0];202 # if ($skycenter and same_images_of_interest($row, $firstRow)) {203 if (same_images_of_interest($row, $firstRow)) {204 push @rowList, $row;205 # On to the next row206 next;207 } else {208 # queue the jobs for this set of rows 209 $num_jobs += queueJobs($mode, \@rowList, $imageList);210 @rowList = ();211 } 212 }213 214 if ($req_type eq "bycoord") {215 if (!$skycenter) {216 print STDERR "center must be specified in sky coordintes for bycoord" if $verbose;217 insertFakeJobForRow($row, 1, 46); 218 $num_jobs++;219 next;220 }221 print STDERR "lookup bycoord is not yet implemented" if $verbose; 222 insertFakeJobForRow($row, 1, 47);223 $num_jobs++;224 next; 225 } else {226 # Call PS::IPP::PStamp::Job's locate_images subroutine to get the parameters for this227 # request specification. An array reference is returned.228 my ($x, $y); 229 $imageList = locate_images($ipprc, $image_db, $req_type, $stage, $id, $search_component,230 $skycenter, $x, $y, $mjd_min, $mjd_max, $filter, $verbose);231 }232 233 if (!$imageList or !@$imageList) {234 print STDERR "no matching images found for row $rownum\n" if $verbose;235 # note in this case queueJobs inserts the fake job for these rows 236 }237 $row->{need_magic} = $need_magic; 238 push @rowList, $row;239 }240 241 if (@rowList) {242 $num_jobs += queueJobs($mode, \@rowList, $imageList);243 } 244 245 if (($mode eq "queue_jobs") and ($num_jobs eq 0)) { 246 print STDERR "no jobs created for $req_name\n" if $verbose;247 insertFakeJobForRow(undef, 1, 41);248 } 249 exit 0;250 251 252 sub queueJob sForRow375 $need_magic = $proj_hash->{need_magic}; 376 377 # Temporary hack so that MOPS can get at non-magicked data 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 393 # Call PS::IPP::PStamp::Job locate_images subroutine to get the images for this 394 # request specification. An array reference is returned. 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"; 407 408 if (!$imageList or !@$imageList) { 409 print STDERR "no matching images found for row $rownum\n" if $verbose; 410 # note in this case queueJobs inserts the fake job for these rows 411 } 412 # handle this 413 $row->{need_magic} = $need_magic; 414 415 $num_jobs += queueJobs($mode, \@rowList, $imageList); 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 431 sub queueJobForImage 253 432 { 254 433 my $row = shift; 255 434 my $stage = shift; 256 my $imageList = shift; 257 my $have_skycells = shift; 435 my $image = shift; 258 436 my $need_magic = shift; 437 my $mode = shift; 259 438 260 439 my $rownum = $row->{ROWNUM}; 261 440 my $option_mask = $row->{OPTION_MASK}; 262 441 my $components = $row->{components}; 263 my $numComponents = scalar keys %$components;264 if ( $numComponents == 0 ) {265 print STDERR "no jobs for row $rownum\n" if $verbose;266 insertFakeJobForRow($row, 1, 44);267 return 1;268 }269 442 270 443 my $roi_string; 271 444 272 # note values were insured to be numbers in validROI()445 # note values were checked by the function validROI() 273 446 my $x = $row->{CENTER_X}; 274 447 my $y = $row->{CENTER_Y}; … … 276 449 my $h = $row->{HEIGHT}; 277 450 my $coord_mask = $row->{COORD_MASK}; 278 if ($x && ($x ne "null") && $y && ($y ne "null") && $w && ($w ne "null") && $h && ($h ne "null")) { 279 if ($coord_mask & $PSTAMP_CENTER_IN_PIXELS) { 280 $roi_string = "-pixcenter $x $y"; 281 } else { 282 $roi_string = "-skycenter $x $y"; 283 } 284 if ($coord_mask & $PSTAMP_RANGE_IN_PIXELS) { 285 $roi_string .= " -pixrange $w $h"; 286 } else { 287 $roi_string .= " -arcrange $w $h"; 288 } 289 } 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 606 sub 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); 665 sub 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 290 684 291 685 # loop over images 292 my $job_num = 0;293 686 foreach my $image (@$imageList) { 294 my $component; 295 if ($have_skycells) { 296 $component = $image->{skycell_id}; 297 } else { 298 $component = $image->{class_id}; 299 } 300 301 # skip this component if it is not in the list for this row 302 next if ! $components->{$component}; 303 304 $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}); 305 697 306 698 my $imagefile = $image->{image}; 307 699 if (($stage ne "stack") and ($need_magic and !$image->{magicked})) { 308 # XXX: should we add a faulted job so the client can know what happened if no images come back? 309 print STDERR "skippping non-magicked image $imagefile\n" if $verbose; 310 311 # for now assume yes. 312 313 insertFakeJobForRow($row, $job_num, 43); 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. 704 print STDERR "skipping non-magicked image $imagefile\n" if $verbose; 705 insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_DESTREAKED); 706 $num_jobs++; 314 707 315 708 next; … … 317 710 my $exp_id = $image->{exp_id}; 318 711 319 my $args = $roi_string ? $roi_string : "";320 if ($stage eq "raw" or $stage eq "chip") {321 $args .= " -class_id $component" if $component;322 }323 324 # add astrometry file for raw and chip images if one is available325 if (($stage eq "chip") || ($stage eq "raw")) {326 $args .= " -astrom $image->{astrom}" if $image->{astrom};327 }328 329 $args .= " -file $imagefile";330 331 if (($row->{OPTION_MASK} & $PSTAMP_SELECT_MASK) && $image->{mask} ) {332 $args .= " -mask $image->{mask}";333 }334 if (($row->{OPTION_MASK} & $PSTAMP_SELECT_WEIGHT) and $image->{weight} ) {335 $args .= " -variance $image->{weight}";336 }337 338 712 my $output_base = "$out_dir/${rownum}_${job_num}"; 339 my $argslist = "${output_base}.args"; 340 341 # copy the argument list to a file 342 open ARGSLIST, ">$argslist" or my_die("failed to open $argslist", $PS_EXIT_UNKNOWN_ERROR); 343 print ARGSLIST "$args\n"; 344 close ARGSLIST or my_die("failed to close $argslist", $PS_EXIT_UNKNOWN_ERROR); 713 714 write_params($output_base, $image); 345 715 346 716 my $newState = "run"; 347 717 my $fault = 0; 348 if ($image->{data_state} ne "full") { 349 # XXX here is where we need to queue an update job 350 # for now just say that the image is not available 351 $newState = 'stop'; 352 $fault = 49; 718 my $dep_id; 719 720 if ($stage ne 'raw') { 721 my $run_state = $image->{state}; 722 my $data_state = $image->{data_state}; 723 $data_state = $run_state if $stage eq "stack"; 724 if (($run_state eq 'goto_purged') or ($data_state eq 'purged') or 725 ($run_state eq 'goto_scrubbed') or ($data_state eq 'scrubbed')) { 726 # image is gone and it's not coming back 727 $newState = 'stop'; 728 $fault = $PSTAMP_GONE; 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) { 732 $newState = 'stop'; 733 $fault = $PSTAMP_NOT_AVAILABLE; 734 } else { 735 # cause the image to be re-made 736 # set up to queue an update run 737 queue_update_run(\$newState, \$fault, \$dep_id, $image->{image_db}, 738 $run_state, $stage, $image->{stage_id}, $image->{component}, $need_magic); 739 } 740 } 353 741 } 354 742 355 743 $num_jobs++; 356 744 my $command = "$pstamptool -addjob -req_id $req_id -job_type $row->{JOB_TYPE}" 357 . " -outputBase $output_base -rownum $rownum -state $newState ";745 . " -outputBase $output_base -rownum $rownum -state $newState -options $option_mask"; 358 746 $command .= " -fault $fault" if $fault; 359 747 $command .= " -exp_id $exp_id" if $exp_id; 360 $command .= " -dbname $dbname" if $dbname; 361 $command .= " -dbserver $dbserver" if $dbserver; 362 363 if ($mode eq "list_job") { 364 # this is a debugging mode, just print the pstamptool that would have run 365 # this is sort of like the mode -noupdate that some other tools support 366 print "$command\n"; 367 } elsif (!$no_update) { 748 $command .= " -dep_id $dep_id" if $dep_id; 749 750 if (!$no_update) { 368 751 # mode eq "queue_job" 369 752 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = … … 380 763 } 381 764 } 382 return $num_jobs; 383 } 384 385 # queue jobs for a collection of request specifications that have the same Images of Interest 386 sub queueJobs 387 { 388 my $mode = shift; 389 my $rowList = shift; 390 my $imageList = shift; 391 392 my $firstRow = $rowList[0]; 393 my $stage = $firstRow->{IMG_TYPE}; 394 my $job_type = $firstRow->{JOB_TYPE}; 395 my $need_magic = $firstRow->{need_magic}; 396 397 my $num_jobs = 0; 398 399 if ($mode eq "list_uri") { 400 foreach my $image (@$imageList) { 401 print "$image->{image}\n"; 402 } 403 } elsif ($job_type eq "get_image") { 404 print STDERR "get_image jobs not implemented yet" if $verbose; 405 foreach my $row (@$rowList) { 406 insertFakeJobForRow($row, 1, 47); 407 $num_jobs++; 408 } 409 } else { 410 if (!$imageList or (scalar @$imageList eq 0)) { 411 # we didn't find any images for this set of rows. Insert a fake job to carry 412 # the status back to the requestor 413 foreach my $row (@$rowList) { 414 insertFakeJobForRow($row, 1, 42); 415 $num_jobs++; 416 } 417 return $num_jobs; 418 } 419 420 my $have_skycells; 421 if (($stage eq "raw") or ($stage eq "chip")) { 422 $have_skycells = 0; 423 } else { 424 $have_skycells = 1; 425 } 426 427 my $thisRun; 428 429 my ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps); 430 my $npoints = 0; 431 foreach my $row (@$rowList) { 432 $row->{components} = {}; 433 if ($row->{skycenter}) { 434 print $pointsList "$row->{ROWNUM} $row->{CENTER_X} $row->{CENTER_Y}\n"; 435 $npoints++; 436 } else { 437 # this row's center is in pixel coordinates add all images to the component list for this row 438 foreach my $i (@$imageList) { 439 my $component = $have_skycells ? $i->{skycell_id} : $i->{class_id}; 440 my_die( "image found with no value for component", $PS_EXIT_UNKNOWN_ERROR) if !$component; 441 $row->{components}->{$component} = 1; 442 } 443 } 444 } 445 close $pointsList; 446 447 my $tess_dir_abs; 448 my $last_tess_id = ""; 449 while ($thisRun = getOneRun($stage, $imageList)) { 450 if ($npoints) { 451 # we collected a set of sky coordintates above filter the images so that only 452 # those tat contain the centers are processed 453 my $command = "$dvoImagesAtCoords $pointsListName"; 454 if ($have_skycells) { 455 my $tess_id = $thisRun->[0]->{tess_id}; 456 if ($tess_id ne $last_tess_id) { 457 $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id ); 458 $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs ); 459 $last_tess_id = $tess_id; 460 } 461 $command .= " -D CATDIR $tess_dir_abs"; 462 } else { 463 my $astrom = $thisRun->[0]->{astrom}; 464 my_die( "no astrometry file found", $PS_EXIT_UNKNOWN_ERROR) if !$astrom; 465 my $astrom_resolved = $ipprc->file_resolve($astrom); 466 $command .= " -astrom $astrom_resolved"; 467 } 468 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 469 run(command => $command, verbose => $verbose); 470 unless ($success) { 471 print STDERR @$stderr_buf; 472 my $rc = $error_code >> 8; 473 my_die( "dvoImagesAtCoords failed: $rc", $PS_EXIT_UNKNOWN_ERROR); 474 } 475 # now we have a list of row numbers and components 476 # eventually we might want to multiple stamp requests for the same image 477 # into the same ppstamp job but not yet. For now we will queue a new 478 my @lines = split "\n", join "", @$stdout_buf; 479 foreach my $line (@lines) { 480 # parse the line, ignoring the ra and dec 481 my ($rownum, undef, undef, $component) = split " ", $line; 482 483 # I guess since we need this function we should be useing a hash for rowList 484 my $row = findRow($rownum, $rowList); 485 $row->{components}->{$component} = 1; 486 } 487 } 488 489 foreach my $row (@$rowList) { 490 $num_jobs += queueJobsForRow($row, $stage, $thisRun, $have_skycells, $need_magic); 491 } 492 } 765 if ( $num_jobs == 0 ) { 766 print STDERR "no jobs for row $rownum\n" if $verbose; 767 insertFakeJobForRow($row, 1, $PSTAMP_NO_JOBS_QUEUED); 768 $num_jobs = 1; 493 769 } 494 770 return $num_jobs; … … 500 776 my $fault = shift; 501 777 502 my $command = "$pstamptool -addjob -req_id $req_id -job_type $row->{JOB_TYPE}" 503 . " -rownum $row->{ROWNUM} -state stop -fault $fault"; 504 $command .= " -dbname $dbname" if $dbname; 505 $command .= " -dbserver $dbserver" if $dbserver; 506 507 if ($mode eq "list_job") { 508 # this is a debugging mode, just print the pstamptool that would have run 509 # this is sort of like the mode -noupdate that some other tools support 510 print "$command\n"; 511 } elsif (!$no_update) { 778 my ($job_type, $rownum); 779 if ($row) { 780 $job_type = $row->{JOB_TYPE}; 781 $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 } 792 } else { 793 $job_type = "none"; 794 $rownum = 0; 795 } 796 797 my $command = "$pstamptool -addjob -req_id $req_id -job_type $job_type" 798 . " -rownum $rownum -state stop -fault $fault"; 799 800 if (!$no_update) { 512 801 # mode eq "queue_job" 513 802 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = … … 525 814 } 526 815 527 sub get_run_id528 {529 my $stage = shift;530 my $image = shift;531 532 if ($stage eq "raw") {533 return $image->{exp_id};534 } elsif ($stage eq "chip") {535 return $image->{chip_id};536 } elsif ($stage eq "warp") {537 return $image->{warp_id};538 } elsif ($stage eq "stack") {539 return $image->{stack_id};540 } elsif ($stage eq "diff") {541 return $image->{diff_id};542 } else {543 my_die("unenexpected stage: $stage found", $PS_EXIT_PROG_ERROR);544 }545 }546 547 # extract components from the imageList that have the same run id and return the list548 sub getOneRun {549 my $stage = shift;550 my $imageList = shift;551 552 # return if array is empty553 return undef if ! @$imageList;554 555 my $last_run_id = 0;556 my @runList;557 while ($imageList->[0]) {558 my $run_id = get_run_id($stage, $imageList->[0]);559 560 last if ($last_run_id and ($run_id ne $last_run_id));561 562 my $image = shift @$imageList;563 $image->{stage} = $stage;564 push @runList, $image;565 $last_run_id = $run_id;566 }567 return \@runList;568 }569 570 816 sub same_images_of_interest { 571 817 my $r1 = shift; 572 818 my $r2 = shift; 573 819 574 return 0 if ( $r1->{PROJECT} ne $r2->{PROJECT});575 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")); 576 822 return 0 if ($r1->{REQ_TYPE} ne $r2->{REQ_TYPE}); 577 823 return 0 if ($r1->{IMG_TYPE} ne $r2->{IMG_TYPE}); 578 return 0 if ($r1->{ID} ne $r2->{ID}); 579 580 if (defined($r1->{COMPONENT})) { 581 return 0 if !defined $r2->{COMPONENT} or ($r1->{COMPONENT} ne $r2->{COMPONENT}); 582 } elsif (defined($r2->{COMPONENT})) { 583 return 0; 584 } 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)); 585 837 586 838 return 1; … … 591 843 my $val = shift; 592 844 593 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 } 849 sub validID 850 { 851 my $val = shift; 852 853 return 0 if !$val; 854 855 return ! ($val =~ /\D/); 594 856 } 595 857 … … 616 878 } 617 879 880 sub queue_update_run 881 { 882 my ($r_jobState, $r_fault, $r_dep_id, $imagedb, $state, $stage, $stage_id, $component, $need_magic) = @_; 883 884 if (($state ne 'cleaned') and ($state ne 'update') and ($state ne 'goto_cleaned')) { 885 my_die("$stage $stage_id is in unexpected state $state", $PS_EXIT_PROG_ERROR); 886 } 887 888 my $dep_id; 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 898 if (!$no_update) { 899 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 900 run(command => $command, verbose => $verbose); 901 unless ($success) { 902 my_die("$command failed", $PS_EXIT_UNKNOWN_ERROR); 903 } 904 my $output = join "", @$stdout_buf; 905 chomp $output; 906 $dep_id = $output; 907 # 908 # XXX: need to fault the request or something 909 my_die("pstamptool -getdependent returned invalid dep_id", $PS_EXIT_PROG_ERROR) if !$dep_id; 910 } else { 911 print STDERR "skipping $command\n"; 912 $dep_id = 42; 913 } 914 915 $$r_dep_id = $dep_id; 916 $$r_fault = 0; 917 $$r_jobState = 'run'; 918 } 919 920 sub 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 945 sub 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 } 959 } 960 618 961 sub my_die 619 962 { … … 625 968 # we don't fault the request here pstamp_parser_run.pl handles that if necessary 626 969 627 return$fault;628 } 970 exit $fault; 971 }
Note:
See TracChangeset
for help on using the changeset viewer.
