- Timestamp:
- May 3, 2010, 8:41:49 AM (16 years ago)
- Location:
- branches/tap_branches
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/tap_branches
- Property svn:mergeinfo changed
-
branches/tap_branches/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm
r25793 r27838 16 16 locate_images 17 17 resolve_project 18 getCamRunByCamID 18 19 ); 19 20 our %EXPORT_TAGS = (standard => [@EXPORT_OK]); 20 21 22 23 use PS::IPP::PStamp::RequestFile qw( :standard ); 21 24 22 25 use IPC::Cmd 0.36 qw( can_run run ); … … 24 27 use PS::IPP::Config qw( :standard ); 25 28 use Carp; 26 27 ### my @images = locate_images($image_db, $req_type, $img_type, $id, $component, 28 ### $mjd_min, $mjd_max, $filter); 29 use DateTime; 30 use File::Temp qw(tempfile); 31 use File::Basename; 32 use POSIX; 33 34 my $dvo_verbose = 0; 35 my $save_temps = 0; 36 37 # caches of camProcessedExp objects. 38 # Key is $exp_id 39 my %camRunByExpIDCache; 40 # Key is $cam_id 41 my %camRunByCamIDCache; 42 43 # cache of last project looked up 44 my $last_project = ""; 45 46 my ($regtool, $chiptool, $camtool, $warptool, $stacktool, $difftool); 47 my ($pstamptool, $dvoImagesAtCoords, $whichimage, $ppConfigDump); 29 48 30 49 sub locate_images { 31 50 my $ipprc = shift; # required 32 my $image_db = shift; # required 51 my $imagedb = shift; # required 52 my $rowList = shift; # required 33 53 my $req_type = shift; # required 34 54 my $img_type = shift; # required … … 36 56 my $tess_id = shift; 37 57 my $component= shift; # class_id or skycell_id 38 my $ inverse= shift;58 my $option_mask = shift; 39 59 my $need_magic = shift; 40 my $x = shift;41 my $y = shift;42 60 my $mjd_min = shift; 43 61 my $mjd_max = shift; 44 62 my $filter = shift; 45 my $ label= shift;63 my $data_group = shift; 46 64 my $verbose = shift; 47 65 48 49 66 # we die in response to bad data in request files 50 die "Unknown req_type: $req_type" 67 # The caller is responsible for updating the database 68 # pstampparse.pl error checks now so this shouldn't happen 69 &my_die("Unknown req_type: $req_type", $PS_EXIT_PROG_ERROR) 51 70 if ($req_type ne "byid") and 52 71 ($req_type ne "byexp") and … … 55 74 ($req_type ne "byskycell"); 56 75 76 57 77 my $dateobs_begin; 58 78 my $dateobs_end; … … 62 82 if (!iszero($mjd_max)) { 63 83 $dateobs_end = mjd_to_dateobs($mjd_max); 84 } 85 if (isnull($tess_id)) { 86 $tess_id = undef; 87 } 88 if (isnull($data_group)) { 89 $data_group = undef; 90 } 91 if (isnull($filter)) { 92 $filter = undef; 93 } 94 95 if ($req_type eq "bycoord") { 96 my $num_rows = scalar @$rowList; 97 die "Unexpected number of rows found in rowList: $num_rows" if $num_rows != 1; 98 my $row = $rowList->[0]; 99 my $x = $row->{CENTER_X}; 100 my $y = $row->{CENTER_Y}; 101 my $results = lookup_bycoord($ipprc, $rowList, $imagedb, $img_type, $tess_id, $component, $need_magic, $x, $y, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose); 102 return $results; 64 103 } 65 104 … … 69 108 # in one place 70 109 $req_type = "bydiff"; 71 my $results = lookup_diff($ipprc, $ image_db, $id, $component, 1, $inverse, $img_type, $verbose);110 my $results = lookup_diff($ipprc, $rowList, $imagedb, $id, $component, 1, $option_mask, $img_type, $verbose); 72 111 return $results; 73 112 } 74 113 75 114 if ($req_type eq "bydiff") { 76 my $results = lookup_diff($ipprc, $image_db, $id, $component, 0, $inverse, $img_type, $verbose); 115 # for bydiff reuqests we go look up the diffRun to obtain exp_id, chip_id, warp_id, stack_id, or 116 # the image from the diffRun 117 my $results = lookup_diff($ipprc, $rowList, $imagedb, $id, $component, 0, $option_mask, $img_type, $verbose); 77 118 if (!$results) { 78 119 return undef; … … 84 125 85 126 my $image = $results->[0]; 86 if ( ($img_type eq "raw") or ($img_type eq "chip")) {87 $req_type = "by exp";88 $id = $image->{exp_ name};127 if ($img_type eq "raw") { 128 $req_type = "byid"; 129 $id = $image->{exp_id}; 89 130 return undef if !$id; 90 # fall through and lookup byexp 131 # fall through and lookup byid 132 } elsif ($img_type eq "chip") { 133 $req_type = "byid"; 134 $id = $image->{chip_id}; 135 return undef if !$id; 136 # fall through and lookup byid 91 137 } elsif ($img_type eq "warp") { 92 138 $req_type = "byid"; … … 101 147 # fall though and lookup by stack_id 102 148 } else { 103 # shouldn't I checkthis elsewhere?149 # This is checked this elsewhere? 104 150 print STDERR "Error: $img_type is an unknown image type\n"; 105 return undef;106 }107 108 } elsif ($req_type eq "bycoord") {109 110 if ($img_type eq "stack") {111 print STDERR "Error bycoord lookup not implemented for stage stack yet\n";112 151 return undef; 113 152 } … … 123 162 } 124 163 125 my $results = lookup($ipprc, $image_db, $req_type, $img_type, $id, $tess_id, $component, $need_magic, $x, $y, $dateobs_begin, $dateobs_end, $filter, $label, $verbose); 164 my $results = lookup($ipprc, $rowList, $imagedb, $req_type, $img_type, $id, $tess_id, $component, 165 $need_magic, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose); 126 166 127 167 return $results; 128 168 } 169 170 # The subroutine lookup handles byexp, byid, and byskycell lookups including lookups that are 171 # triggered by a bydiff request 129 172 130 173 sub lookup 131 174 { 132 175 my $ipprc = shift; 133 my $image_db = shift; 176 my $rowList = shift; 177 my $imagedb = shift; 134 178 my $req_type = shift; 135 my $ img_type = shift;179 my $stage = shift; 136 180 my $id = shift; 137 181 my $tess_id = shift; 138 182 my $component= shift; 139 183 my $need_magic = shift; 140 my $x = shift;141 my $y = shift;142 184 my $dateobs_begin = shift; 143 185 my $dateobs_end = shift; 144 186 my $filter = shift; 145 my $label = shift; 187 my $data_group = shift; 188 my $option_mask = shift; 146 189 my $verbose = shift; 147 190 148 my $missing_tools; 149 my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1); 150 my $chiptool = can_run('chiptool') or (warn "Can't find chiptool" and $missing_tools = 1); 151 my $warptool = can_run('warptool') or (warn "Can't find warptool" and $missing_tools = 1); 152 my $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1); 153 my $stacktool = can_run('stacktool') or (warn "Can't find stacktool" and $missing_tools = 1); 154 if ($missing_tools) { 155 warn("Can't find required tools."); 156 exit ($PS_EXIT_CONFIG_ERROR); 157 } 191 my $inverse = $option_mask & $PSTAMP_SELECT_INVERSE; 192 my $unconvolved = $option_mask & $PSTAMP_SELECT_UNCONV; 193 my $use_imfile_id = ($req_type eq "byid") && ($option_mask & $PSTAMP_USE_IMFILE_ID); 194 158 195 my $command; 159 196 my $id_opt; # option for the lookup … … 161 198 my $mask_name; 162 199 my $weight_name; 200 my $cmf_name; 201 my $psf_name; 202 my $backmdl_name; 163 203 my $base_name; 164 204 my $want_astrom; … … 171 211 } 172 212 213 # note $magic_arg may be cleared below depending on $req_type 173 214 my $magic_arg = $need_magic ? " -destreaked" : ""; 215 216 # all rows have the same center type 217 my $skycenter = ! ($rowList->[0]->{COORD_MASK} & $PSTAMP_CENTER_IN_PIXELS); 218 174 219 my $component_args; 175 if ($img_type eq "raw") { 220 my $choose_components = 0; 221 if ($stage eq "raw") { 176 222 $class_id = $component; 177 $command = "$regtool -processedimfile -dbname $image _db";223 $command = "$regtool -processedimfile -dbname $imagedb"; 178 224 # XXX: for now restrict lookups to type object 179 225 # are stamps of detrend exposures interesting? 180 226 $command .= " -exp_type object"; 181 $id_opt = "-exp_id";227 $id_opt = $use_imfile_id ? "-raw_imfile_id" : "-exp_id"; 182 228 $component_args = " -class_id $class_id" if $component; 183 229 $want_astrom = 1; 184 230 $set_class_id = 1; 185 } elsif ($ img_type eq "chip") {231 } elsif ($stage eq "chip") { 186 232 $class_id = $component; 187 $command = "$chiptool -processedimfile -dbname $image_db"; 188 $component_args = " -class_id $class_id" if $class_id; 189 $id_opt = "-chip_id"; 233 # if the request is such that it will yield a single image per "run" or the 234 # center is specified in pixel coordinates 235 # use chiptool -processsedimfile. Otherwise use chiptool -listrun and then 236 # choose the chips containing the center pixel by calling selectComponets() below 237 if ($class_id or $use_imfile_id or !$skycenter) { 238 $command = "$chiptool -processedimfile -dbname $imagedb"; 239 $component_args = " -class_id $class_id" if $class_id; 240 } else { 241 $command = "$chiptool -listrun -pstamp_order -dbname $imagedb"; 242 $choose_components = 1; 243 } 244 $id_opt = $use_imfile_id ? "-chip_imfile_id" : "-chip_id"; 245 # XXX: perhaps we should stop resolving images to this level here and do it at job run time. 246 # With the mdc file it has all of the information that it needs. 190 247 $image_name = "PPIMAGE.CHIP"; 191 248 $mask_name = "PPIMAGE.CHIP.MASK"; 192 249 $weight_name = "PPIMAGE.CHIP.VARIANCE"; 250 $cmf_name = "PSPHOT.OUTPUT"; 251 $psf_name = "PSPHOT.PSF.SAVE"; 252 $backmdl_name = "PSPHOT.BACKMDL"; 193 253 $base_name = "path_base"; # name of the field for the chiptool output 194 254 $want_astrom = 1; 195 255 $set_class_id = 1; 196 } elsif ($ img_type eq "warp") {256 } elsif ($stage eq "warp") { 197 257 $skycell_id = $component; 198 $command = "$warptool -warped -dbname $image_db"; 199 $component_args = " -skycell_id $skycell_id" if $skycell_id; 200 $id_opt = "-warp_id"; 258 if ($skycell_id or $use_imfile_id or !$skycenter) { 259 $command = "$warptool -warped -dbname $imagedb"; 260 $component_args = " -skycell_id $skycell_id" if $skycell_id; 261 } else { 262 $command = "$warptool -listrun -pstamp_order -dbname $imagedb"; 263 $choose_components = 1; 264 } 265 $id_opt = $use_imfile_id ? "-warp_skyfile_id" : "-warp_id"; 201 266 $image_name = "PSWARP.OUTPUT"; 202 267 $mask_name = "PSWARP.OUTPUT.MASK"; 203 268 $weight_name = "PSWARP.OUTPUT.VARIANCE"; 269 $cmf_name = "PSWARP.OUTPUT.SOURCES"; 270 $psf_name = "PSPHOT.PSF.SKY.SAVE"; 204 271 $base_name = "path_base"; # name of the field for the warptool output 205 } elsif ($ img_type eq "diff") {272 } elsif ($stage eq "diff") { 206 273 $skycell_id = $component; 207 $command = "$difftool -diffskyfile -dbname $image_db"; 208 $component_args = " -skycell_id $skycell_id" if $skycell_id; 209 $id_opt = "-diff_id"; 274 if ($skycell_id or $use_imfile_id or !$skycenter) { 275 $command = "$difftool -diffskyfile -dbname $imagedb"; 276 $component_args = " -skycell_id $skycell_id" if $skycell_id; 277 } else { 278 $command = "$difftool -listrun -pstamp_order -dbname $imagedb"; 279 $choose_components = 1; 280 } 281 $id_opt = $use_imfile_id ? "-diff_skyfile_id" : "-diff_id"; 210 282 $image_name = "PPSUB.OUTPUT"; 211 283 $mask_name = "PPSUB.OUTPUT.MASK"; 212 284 $weight_name = "PPSUB.OUTPUT.VARIANCE"; 285 $cmf_name = "PPSUB.OUTPUT.SOURCES"; 286 $psf_name = "PSPHOT.PSF.SKY.SAVE"; 213 287 $base_name = "path_base"; 214 } elsif ($ img_type eq "stack") {288 } elsif ($stage eq "stack") { 215 289 $skycell_id = $component; 216 $command = "$stacktool -sumskyfile -dbname $image _db";290 $command = "$stacktool -sumskyfile -dbname $imagedb"; 217 291 $id_opt = "-stack_id"; 218 292 $component_args = " -skycell_id $skycell_id" if $skycell_id; 219 293 220 $image_name = "PPSTACK.OUTPUT"; 221 $mask_name = "PPSTACK.OUTPUT.MASK"; 222 $weight_name = "PPSTACK.OUTPUT.VARIANCE"; 294 if (!$unconvolved) { 295 $image_name = "PPSTACK.OUTPUT"; 296 $mask_name = "PPSTACK.OUTPUT.MASK"; 297 $weight_name = "PPSTACK.OUTPUT.VARIANCE"; 298 } else { 299 $image_name = "PPSTACK.UNCONV"; 300 $mask_name = "PPSTACK.UNCONV.MASK"; 301 $weight_name = "PPSTACK.UNCONV.VARIANCE"; 302 } 303 # this is wrong but gets the right answer. Need to figure out how to find the 304 # rule properly 305 #$cmf_name = "PSPHOT.OUTPUT"; # this puts .fpa. in the name 306 $cmf_name = "PSWARP.OUTPUT.SOURCES"; 307 $psf_name = "PPSTACK.TARGET.PSF"; 223 308 $base_name = "path_base"; 224 309 } else { 225 die "Unknown img_type supplied: $img_type"; 226 } 227 310 die "Unknown IMG_TYPe supplied: $stage"; 311 } 312 313 my $filter_runs = 0; 228 314 if ($req_type eq "byid") { 229 315 $command .= " $id_opt $id"; 230 316 $command .= $component_args if $component_args; 317 # don't include -destreaked if lookup is byid. Let pstampparse check so that the 318 # error code returned to the client for a given component is 'not destreaked' 319 # instead of 'not found' 320 $magic_arg = ""; 231 321 } elsif ($req_type eq "byexp") { 232 322 $command .= " -exp_name $id"; 233 323 $command .= $component_args if $component_args; 324 # don't include -destreaked if lookup is byexp. Let pstampparse check so that the error code gives 325 # the reason as 'not destreaked' 326 $magic_arg = ""; 327 # remove duplicate runs for the same exposure. 328 $filter_runs = 1; 234 329 } elsif ($req_type eq "byskycell") { 235 330 die "tess_id and component are required for byskycell" if !$tess_id or ! $skycell_id; 236 331 $command .= " -tess_id $tess_id -skycell_id $skycell_id"; 237 } elsif ($req_type eq "bycoord") {238 $command .= " -radius 3.0 -ra $x -decl $y";239 332 } else { 240 die "Unknown req_type supplied: $req_type"; 241 } 242 243 if ($img_type ne "stack") { 333 # this should be caught by caller 334 &my_die("Unexpected req_type supplied: $req_type", $PS_EXIT_PROG_ERROR); 335 } 336 337 if ($stage ne "stack") { 244 338 $command .= $magic_arg; 245 339 $command .= " -dateobs_begin $dateobs_begin" if $dateobs_begin; … … 248 342 249 343 $command .= " -filter $filter" if !isnull($filter); 250 $command .= " -label $label" if !isnull($label); 251 252 # run the tool and parse the output 253 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 254 run(command => $command, verbose => $verbose); 255 unless ($success) { 256 # not sure if we should die here 257 print STDERR @$stderr_buf; 344 $command .= " -data_group $data_group" if !isnull($data_group); 345 346 my $images = runToolAndParse($command, $verbose); 347 348 if (!$images or scalar @$images == 0) { 258 349 return undef; 259 350 } 260 351 261 my $buf = join "", @$stdout_buf; 262 if (!$buf) { 263 return; 264 } 265 266 my $mdcParser = PS::IPP::Metadata::Config->new; 267 my $images = parse_md_fast($mdcParser, $buf) 268 or die ("Unable to parse metadata config doc"); 269 352 if ($filter_runs) { 353 # The image selectors are such that multiple runs my have be returned for the same exposure. 354 # Return only the latest one. 355 $images = filterRuns($stage, $need_magic, $images, $verbose); 356 } 357 if ($choose_components) { 358 # the list of "images" is actually a list of "Runs" 359 # match the coords in the rows to the components in the runs 360 # returns an actual list of images 361 $images = selectComponents($ipprc, $imagedb, $req_type, $stage, $rowList, $images, $verbose); 362 } else { 363 # put each of the rows into all of the the images 364 setRowRefs($rowList, $images); 365 } 366 367 my $camera; 270 368 my $output = []; 271 272 my $camera;273 369 foreach my $image (@$images) { 274 370 my $base; 275 371 276 372 next if $image->{fault}; 277 next if ($ img_type ne "raw") and $image->{quality};373 next if ($stage ne "raw") and $image->{quality}; 278 374 279 375 if ($base_name) { … … 299 395 # (we do this here for raw stage) 300 396 $out->{image} = $image->{uri}; 397 301 398 if ($set_class_id) { 302 399 $class_id = $image->{class_id}; 303 400 $out->{component} = $class_id; 401 } else { 402 $out->{component} = $image->{skycell_id}; 304 403 } 305 404 my $stage_id; 306 if ($ img_type eq "raw") {405 if ($stage eq "raw") { 307 406 $stage_id = $image->{exp_id}; 308 } elsif ($ img_type eq "chip") {309 $stage_id = $image->{chip };310 } elsif ($ img_type eq "warp") {407 } elsif ($stage eq "chip") { 408 $stage_id = $image->{chip_id}; 409 } elsif ($stage eq "warp") { 311 410 $stage_id = $image->{warp_id}; 312 } elsif ($ img_type eq "diff") {411 } elsif ($stage eq "diff") { 313 412 $stage_id = $image->{diff_id}; 314 } elsif ($img_type eq "stack") { 413 if ($inverse && $image->{bothways}) { 414 $image_name = "PPSUB.INVERSE"; 415 $mask_name = "PPSUB.INVERSE.MASK"; 416 $weight_name = "PPSUB.INVERSE.VARIANCE"; 417 $cmf_name = "PPSUB.INVERSE.SOURCES"; 418 } 419 } elsif ($stage eq "stack") { 315 420 $stage_id = $image->{stack_id}; 316 421 } 317 $image->{stage_id} = $stage_id; 318 $image->{stage} = $img_type; 319 $image->{image_db} = $image_db; 320 321 # find the mask and weight images 422 $out->{stage_id} = $stage_id; 423 $out->{stage} = $stage; 424 $out->{imagedb} = $imagedb; 425 322 426 if ($base) { 323 427 $out->{image} = $ipprc->filename($image_name, $base, $class_id) if $image_name; 324 428 $out->{mask} = $ipprc->filename($mask_name, $base, $class_id) if $mask_name; 325 429 $out->{weight} = $ipprc->filename($weight_name, $base, $class_id) if $weight_name; 326 } 327 $out->{astrom} = find_astrometry($ipprc, $image_db, $image, $verbose) if $want_astrom; 430 $out->{cmf} = $ipprc->filename($cmf_name, $base, $class_id) if $cmf_name; 431 $out->{psf} = $ipprc->filename($psf_name, $base, $class_id) if $psf_name; 432 $out->{backmdl}= $ipprc->filename($backmdl_name, $base, $class_id) if $backmdl_name; 433 } 434 if ($want_astrom and ! defined $out->{astrom}) { 435 $out->{astrom} = find_astrometry($ipprc, $imagedb, $image, $verbose); 436 } 328 437 329 438 push @$output, $out; … … 332 441 return $output; 333 442 } 443 334 444 sub lookup_diff { 335 445 my $ipprc = shift; 336 my $image_db = shift; 446 my $rowList = shift; 447 my $imagedb = shift; 337 448 my $id = shift; 338 449 my $skycell_id = shift; 339 450 my $byid = shift; 340 my $ inverse= shift;451 my $option_mask = shift; 341 452 my $img_type = shift; 342 453 my $verbose = shift; 343 454 344 my $missing_tools; 345 my $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1); 346 if ($missing_tools) { 347 warn("Can't find required tools."); 348 exit ($PS_EXIT_CONFIG_ERROR); 349 } 350 351 my $command = "$difftool -diffskyfile -dbname $image_db"; 455 my $inverse = $option_mask & $PSTAMP_SELECT_INVERSE; 456 457 my $command = "$difftool -dbname $imagedb"; 352 458 353 459 if ($byid) { 354 $command .= " - diff_id $id";460 $command .= " -listrun -diff_id $id"; 355 461 } else { 356 $command .= " -diff _skyfile_id $id";462 $command .= " -diffskyfile -diff_skyfile_id $id"; 357 463 } 358 464 $command .= " -skycell_id $skycell_id" if $skycell_id; 359 465 360 # run the tool and parse the output 361 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 362 run(command => $command, verbose => $verbose); 363 unless ($success) { 364 # not sure if we should die here 365 print STDERR @$stderr_buf; 366 return undef; 367 } 368 369 my $buf = join "", @$stdout_buf; 370 if (!$buf) { 371 return undef; 372 } 373 374 my $mdcParser = PS::IPP::Metadata::Config->new; 375 my $images = parse_md_fast($mdcParser, $buf) 376 or die ("Unable to parse metadata config doc"); 377 378 my $n = @$images; 466 my $output = runToolAndParse($command, $verbose); 467 468 my $n = @$output; 379 469 if (!$byid && ($n > 1)) { 380 470 die ("difftool returned an unexpected number of diffskyfiles: $n"); … … 383 473 } 384 474 475 my $images; 476 if ($byid) { 477 $images = selectComponents($ipprc, $imagedb, 'byid', 'diff', $rowList, $output, $verbose); 478 } else { 479 $images = $output; 480 } 481 385 482 my @results; 386 483 foreach my $image (@$images) { … … 395 492 # so we interpret the requested image in that way 396 493 397 my $stack_id = $image->{stack2};398 494 # XXX difftool currently returns max long long for null 399 # this line is ready if we switch the code to return zero for null 400 if ($stack_id and ($stack_id != 9223372036854775807)) { 495 # these checks are ready if we switch the code to return zero for null 496 my $stack1 = $image->{stack1}; 497 if (($stack1 == 0) or ($stack1 == 9223372036854775807)) { 498 $stack1 = undef 499 } 500 my $stack2 = $image->{stack2}; 501 if (($stack2 == 0) or ($stack2 == 9223372036854775807)) { 502 $stack2 = undef 503 } 504 my $stack_id; 505 if ($stack1 and $stack2) { 506 # we have a stack - stack diff (well it might be stack - warp....) 507 # but at any rate we only handle image type diff and stack 508 if (($img_type ne "diff") and ($img_type ne "stack")) { 509 print STDERR "lookup_diff: cannot lookup IMG_TYPE $img_type bydiff from a stack stack diff run\n"; 510 next; 511 } 512 # stack-stack diff 513 # XXX: define another flag for this 514 if (! $inverse) { 515 $stack_id = $stack1; 516 } else { 517 $stack_id = $stack2; 518 } 401 519 $image->{stack_id} = $stack_id; 402 }403 404 my ($warp_id, $exp_id, $exp_name);405 if ($inverse and !$image->{bothways}) {406 print STDERR "Inverse images requested for diffRun that is not bothways. Ignoring.\n";407 $inverse = 0;408 }409 if ($inverse) {410 $warp_id = $image->{warp2};411 $exp_id = $image->{exp_id_2};412 $exp_name = $image->{exp_name_2};413 520 } else { 414 $warp_id = $image->{warp1}; 415 $exp_id = $image->{exp_id_1}; 416 $exp_name = $image->{exp_name_1}; 417 } 418 # XXX difftool currently returns max long long for null 419 # this line is ready if we switch the code to return zero for null 420 if ($warp_id and ($warp_id != 9223372036854775807)) { 421 $image->{warp_id} = $warp_id; 422 $image->{exp_id} = $exp_id; 423 $image->{exp_name} = $exp_name; 424 } else { 425 print STDERR "unexpected result warp_id not defined\n"; 426 next; 427 } 521 my ($warp_id, $exp_id, $exp_name, $chip_id, $cam_id); 522 if ($inverse and !$image->{bothways}) { 523 print STDERR "Inverse images requested for diffRun that is not bothways. Ignoring inverse.\n"; 524 $inverse = 0; 525 } 526 if ($inverse) { 527 $warp_id = $image->{warp2}; 528 $exp_id = $image->{exp_id_2}; 529 $exp_name = $image->{exp_name_2}; 530 $chip_id = $image->{chip_id_2}; 531 $cam_id = $image->{cam_id_2}; 532 } else { 533 $warp_id = $image->{warp1}; 534 $exp_id = $image->{exp_id_1}; 535 $exp_name = $image->{exp_name_1}; 536 $chip_id = $image->{chip_id_1}; 537 $cam_id = $image->{cam_id_1}; 538 } 539 # XXX difftool currently returns max long long for null 540 # this line is ready if we switch the code to return zero for null 541 if ($warp_id and ($warp_id != 9223372036854775807)) { 542 $image->{warp_id} = $warp_id; 543 $image->{exp_id} = $exp_id; 544 $image->{exp_name} = $exp_name; 545 $image->{chip_id} = $chip_id; 546 $image->{cam_id} = $cam_id; 547 } 548 } 549 550 # XXX: If difftool doesn't return a camera insert it here 551 if (!$image->{camera}) { 552 $image->{camera} = "GPC1"; 553 # lie about the magicked status since stack stack diffs don't require destreaking 554 # we can remove this once diff_mode gets included 555 $image->{magicked} = 42; 556 } 557 428 558 if ($img_type eq "diff") { 559 my @imageList = ($image); 560 561 setRowRefs($rowList, \@imageList); 429 562 # the $image is going to be returned directly in this case so we need to duplicate 430 563 # some of processing that lookup does for other img_types … … 435 568 $image->{mask} = $ipprc->filename($filerule_base . ".MASK", $image->{path_base}); 436 569 $image->{weight} = $ipprc->filename($filerule_base . ".VARIANCE", $image->{path_base}); 570 $image->{cmf} = $ipprc->filename($filerule_base . ".SOURCES", $image->{path_base}); 571 $image->{psf} = $ipprc->filename("PSPHOT.PSF.SKY.SAVE", $image->{path_base}); 572 $image->{stage_id} = $image->{diff_id}; 573 $image->{stage} = "diff"; 574 $image->{imagedb} = $imagedb; 575 $image->{component} = $image->{skycell_id}; 437 576 } else { 438 # XXX this will only happen if the minuend is not a warp 439 print STDERR "WARNING: cannot resolve camera so cannot get weight and mask images\n";577 # XXX this will only happen if the minuend is not a warp. See hack above 578 print STDERR "WARNING: cannot resolve camera so cannot get resolve file rules\n"; 440 579 next; 441 580 } … … 447 586 448 587 sub lookup_bycoord { 449 my $ipprc = shift; 450 my $image_db = shift; 451 my $x = shift; 452 my $y = shift; 588 my $ipprc = shift; 589 my $rowList = shift; 590 my $imagedb = shift; 591 my $img_type = shift; 592 my $tess_id = shift; 593 my $component = shift; 594 my $need_magic = shift; 595 my $ra = shift; 596 my $dec = shift; 453 597 my $dateobs_begin = shift; 454 my $dateobs_end = shift; 455 my $filter = shift; 456 my $verbose = shift; 457 458 my $missing_tools; 459 my $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1); 460 if ($missing_tools) { 461 warn("Can't find required tools."); 462 exit ($PS_EXIT_CONFIG_ERROR); 463 } 464 465 # XXX TODO: 466 # Full lookups by coordinate require looking at the DVO database. However, 467 # dateobs and filter which is all that MOPS has asked for. 468 469 my $args; 470 if (!isnull($dateobs_begin)) { 471 $args .= " -dateobs_begin $dateobs_begin"; 472 } 473 if (!isnull($dateobs_end)) { 474 $args .= " -dateobs_end $dateobs_end"; 475 } 476 if (!isnull($filter)) { 477 $args .= " -filter $filter"; 478 } 479 480 if (!$args) { 481 # avoid returning every exposure in the DB 482 print STDERR "no query arguments provided for bycoord\n"; 598 my $dateobs_end = shift; 599 my $filter = shift; 600 my $data_group = shift; 601 my $option_mask = shift; 602 my $verbose = shift; 603 604 my $results = (); 605 if (($img_type eq "raw") or ($img_type eq "chip")) { 606 607 my $runs = lookup_runs_by_cam_id_and_coords($ipprc, $imagedb, $img_type, 608 $ra, $dec, $need_magic, $dateobs_begin, $dateobs_end, $filter, $data_group, $verbose); 609 610 # lookup is going to filter these we don't need to do it here 611 # $runs = filterRuns($img_type, $need_magic, $runs, $verbose); 612 foreach my $run (@$runs) { 613 next if $component and ($run->{component} ne $component); 614 my $these_results = lookup($ipprc, $rowList, $imagedb, "byid", $img_type, $run->{id}, 615 $tess_id, $run->{component}, $need_magic, 616 $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose); 617 618 next if !$these_results; 619 push @$results, @$these_results; 620 } 621 622 } else { 623 # this should be checked elsewhere 624 die "unexpected image type $img_type" if ($img_type ne "warp") 625 and ($img_type ne "stack") and ($img_type ne "diff"); 626 627 my $skycells = lookup_skycell_by_coords($ipprc, $tess_id, $component, $ra, $dec, $verbose); 628 629 foreach my $skycell (@$skycells) { 630 my $these_results = lookup($ipprc, $rowList, $imagedb, "byskycell", $img_type, undef, 631 $skycell->{tess_id}, $skycell->{component}, $need_magic, 632 $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $verbose); 633 634 next if !$these_results; 635 push @$results, @$these_results; 636 } 637 } 638 639 return $results; 640 } 641 642 # lookup_runs_by_cam_id_and_coords 643 # given an ra, dec, and optionally other paramters, find camera runs for exposures 644 # that are within some distance of the coordinates 645 sub lookup_runs_by_cam_id_and_coords { 646 my $ipprc = shift; 647 my $imagedb = shift; 648 my $img_type = shift; 649 my $ra = shift; 650 my $dec = shift; 651 my $need_magic = shift; 652 my $dateobs_begin = shift; 653 my $dateobs_end = shift; 654 my $filter = shift; 655 my $data_group = shift; 656 my $verbose = shift; 657 658 my $camruns; 659 660 { 661 my $command = "$camtool -dbname $imagedb -processedexp -pstamp_order"; 662 $command .= " -ra $ra -decl $dec -radius 1.6"; 663 $command .= " -dateobs_begin $dateobs_begin" if $dateobs_begin; 664 $command .= " -dateobs_end $dateobs_end" if $dateobs_end ; 665 $command .= " -filter $filter" if $filter; 666 # NOTE: we are applying the data_group to the camera run. 667 # If we're looking for chip stage images there is no guarentee that 668 # chipRun.data_group = camRun.data_group. In practice this is almost 669 # always the case. If this turns out to be a problem we can defer 670 # the data_group test to when we look up the chipProcessedImfiles 671 $command .= " -data_group $data_group" if $data_group; 672 $command .= " -destreaked" if $need_magic; 673 674 # run the tool and parse the output 675 $camruns = runToolAndParse($command, $verbose); 676 } 677 if (!$camruns) { 483 678 return undef; 484 679 } 485 486 # XXX TODO: This query doesn't work Something appears to be out of 487 # sync about the times I'm passing and what regtool and or the DB expect 488 # the query I used in the C version of locateimages used 489 # WHERE dateobs >= FROM_UNIXTIME(%ld) AND dateobs <= FROM_UNIXTIME(%ld + exp_time) 490 491 my $command = "$regtool -processedexp -dbname $image_db $args"; 492 493 # run the tool and parse the output 680 my $runs; 681 my $last_exp_id = 0; 682 foreach my $camRun (@$camruns) { 683 my $cam_id = $camRun->{cam_id}; 684 my $exp_id = $camRun->{exp_id}; 685 686 next if $exp_id eq $last_exp_id; 687 688 next if $camRun->{quality}; 689 next if $camRun->{fault}; 690 691 updateCamRunCache($camRun); 692 693 $last_exp_id = $exp_id; 694 695 # XXX Use file rule 696 my $astrom = $camRun->{path_base} . ".smf"; 697 my $astrom_resolved = $ipprc->file_resolve($astrom); 698 next if !$astrom_resolved; 699 700 my $start_dvo = DateTime->now->mjd; 701 my $command = "$dvoImagesAtCoords -astrom $astrom_resolved $ra $dec"; 702 # run the tool and parse the output 703 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 704 run(command => $command, verbose => $dvo_verbose); 705 my $dtime_dvo = (DateTime->now->mjd - $start_dvo)* 86400.; 706 # print "Time to run dvoImagesAtCoords: $dtime_dvo\n"; 707 unless ($success) { 708 my $result_code = $error_code >> 8; 709 if ($result_code == $PSTAMP_NO_OVERLAP) { 710 print "no overlap for $astrom\n" if $verbose; 711 next; 712 } 713 # unexpected result code 714 die "unexpected result code: $result_code from $command\n"; 715 } 716 717 my $output = join "", @$stdout_buf; 718 if (!$output) { 719 # this shouldn't happen when dvoImagesAtCoord exits with zero status 720 die "no output returned from $command\n"; 721 } 722 723 # dvoImagesAtCoords should return a single line 724 # rownum ra dec class_id 725 my @lines = split "\n", $output; 726 my $n = scalar @lines; 727 if ($n != 1) { 728 print STDERR "unexpected number of lines returned by dvoImagesAtCoords: $n\n"; 729 730 # XXX: There is a bug in dvo where each component is listed twice 731 # When that gets fixed remove the conditional and just die 732 die "unexpected number lines returned by dvoImagesAtCoords: $n" 733 if ($n != 2) or ($lines[0] ne $lines[1]); 734 } 735 736 my (undef, $ra_out, $dec_out, $class_id) = split " ", $lines[0]; 737 if (!$class_id) { 738 die "unexpected output from dvoImagesAtCoords: $lines[0]"; 739 } 740 741 print "cam_id $cam_id exp_id $camRun->{exp_id} chip_id $camRun->{chip_id} $class_id\n"; 742 743 # build the hash to return 744 my $run = { 745 exp_id => $camRun->{exp_id}, 746 exp_name => $camRun->{exp_name}, 747 chip_id => $camRun->{chip_id}, 748 cam_id => $camRun->{cam_id}, 749 astrom => $astrom_resolved, 750 class_id => $class_id, 751 component => $class_id 752 }; 753 if ($img_type eq "chip") { 754 $run->{id} = $camRun->{chip_id}; 755 $run->{state} = $camRun->{chip_state}; 756 $run->{magicked} = $camRun->{chip_magicked}; 757 } else { 758 $run->{id} = $camRun->{exp_id}; 759 $run->{state} = 'full'; 760 $run->{magicked} = $camRun->{raw_magicked}; 761 } 762 push @$runs, $run; 763 } 764 765 return $runs; 766 } 767 768 sub lookup_skycell_by_coords { 769 my $ipprc = shift; 770 my $requested_tess_id = shift; 771 my $requested_skycell = shift; 772 my $ra = shift; 773 my $dec = shift; 774 my $verbose = shift; 775 776 $requested_tess_id = "" if isnull($requested_tess_id); 777 $requested_skycell = "" if isnull($requested_skycell); 778 779 my @lines; 780 { 781 my $command = "$whichimage $ra $dec"; 782 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 783 run(command => $command, verbose => $verbose); 784 unless ($success) { 785 print STDERR @$stderr_buf; 786 return undef; 787 } 788 789 my $output = join "", @$stdout_buf; 790 if (!$output) { 791 print STDERR "no output returned from $command\n" if $verbose; 792 return undef; 793 } 794 @lines = split "\n", $output; 795 if (!scalar @lines) { 796 # can this happen? if $output is not null? 797 print STDERR "no output returned from $command\n" if $verbose; 798 return undef; 799 } 800 } 801 my $runs; 802 foreach my $line (@lines) { 803 my ($ra_out, $dec_out, $tess_id, $skycell_id) = split " ", $line; 804 die "unexpected output from whichimage" if !$tess_id or !$skycell_id; 805 806 if ($requested_tess_id) { 807 next if ($requested_tess_id ne $tess_id); 808 } else { 809 # skip these obsolete tesselations unless they were explicitly asked for 810 # should I do this? 811 next if $tess_id eq "FIXNS"; 812 next if $tess_id eq "ALLSKY"; 813 } 814 next if $requested_skycell and ($skycell_id ne $requested_skycell); 815 816 # build the hash to return 817 my $run = { 818 tess_id => $tess_id, 819 component => $skycell_id, 820 }; 821 push @$runs, $run; 822 } 823 824 return $runs; 825 } 826 827 # cache of results of ppConfigDump 828 my %astromSources; 829 my $last_exp_id = 0; 830 my $lastAstromFile; 831 832 # find the astrometry file for a given exposure 833 # return undef if no completed camRun exists 834 sub find_astrometry { 835 my $ipprc = shift; 836 my $imagedb = shift; 837 my $image = shift; # hashref to output of the lookup tool 838 my $verbose = shift; 839 840 my $mdcParser; 841 842 my $exp_id = $image->{exp_id}; 843 if (($exp_id eq $last_exp_id) and $lastAstromFile) { 844 # running camtool 60 times is really expensive when the answer is the same every time 845 return $lastAstromFile; 846 } 847 $last_exp_id = 0; 848 $lastAstromFile = undef; 849 850 my $camRun = getCamRunByExpID($exp_id); 851 if (!$camRun) { 852 my $command = "$camtool -dbname $imagedb -processedexp -exp_id $exp_id -pstamp_order"; 853 # run the tool and parse the output 854 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 855 run(command => $command, verbose => $verbose); 856 unless ($success) { 857 print STDERR @$stderr_buf; 858 return undef; 859 } 860 861 $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files 862 863 my $output = join "", @$stdout_buf; 864 if (!$output) { 865 print STDERR "no output returned from $command\n" if $verbose; 866 return undef; 867 } 868 my $camruns = parse_md_fast($mdcParser, $output); 869 if (!$camruns) { 870 return undef; 871 } 872 873 # If there are multiple cam runs for this exposure, take the last completed one with good quality 874 # on the assumption that it has the best astrometry. 875 foreach $camRun (@$camruns) { 876 last if (($camRun->{state} eq 'full') and ($camRun->{quality} eq 0) and ($camRun->{fault} eq 0)); 877 } 878 # XXX: this looks like a bug at least if ASTROM.SOURCE eq PSASTRO.OUTPUT 879 if (!$camRun) { 880 # no cam runs for this exposure id therefore best astrometry is whatever is in the header 881 return undef; 882 } 883 updateCamRunCache($camRun); 884 } 885 my $camRoot = $camRun->{path_base}; 886 my $camera = $image->{camera}; 887 my $astromSource = $astromSources{$camera}; 888 if (!$astromSource) { 889 if ($camera eq "GPC1") { 890 # CHEATER ! 891 $astromSource = "PSASTRO.OUTPUT"; 892 } else { 893 my $command = "$ppConfigDump -camera $camera -dump-recipe PSWARP -"; 894 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 895 run(command => $command, verbose => $verbose); 896 unless ($success) { 897 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 898 die("Unable to perform ppConfigDump: $error_code"); 899 } 900 $mdcParser = PS::IPP::Metadata::Config->new if !$mdcParser; # Parser for metadata config files 901 my $metadata = $mdcParser->parse(join "", @$stdout_buf) or 902 die("Unable to parse metadata config doc"); 903 $astromSource = metadataLookupStr($metadata, 'ASTROM.SOURCE'); 904 } 905 $astromSources{$camera} = $astromSource; 906 } 907 908 # XXX: Is this code correct if ASTROM.SOURCE ne "PSASTRO.OUTPUT" 909 my $astromFile = $ipprc->filename($astromSource, $camRoot); 910 if ($astromFile) { 911 $lastAstromFile = $astromFile; 912 $last_exp_id = $exp_id; 913 } 914 915 return $astromFile; 916 } 917 918 # splits meta data config input stream into single units to work around the pathalogically 919 # slow parser. This is similar to and adapted from code in various ippScripts. 920 sub parse_md_fast { 921 my $mdcParser = shift; 922 my $input = shift; 923 my $output = (); 924 925 my @whole = split /\n/, $input; 926 my @single = (); 927 928 my $n; 929 while ( ($n = @whole) > 0) { 930 my $value = shift @whole; 931 push @single, $value; 932 if ($value =~ /^\s*END\s*$/) { 933 push @single, "\n"; 934 935 my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or 936 print STDERR "Unable to parse metdata config doc" and return undef; 937 # my $num = @$list; 938 # print STDERR "list has $num elments\n"; 939 push @$output, $list->[0]; 940 941 @single = (); 942 } 943 } 944 return $output; 945 } 946 947 sub mjd_to_dateobs { 948 my $mjd = shift; 949 950 my $ticks = ($mjd - 40587.0) * 86400; 951 952 my ($sec, $min, $hr, $day, $mon, $year) = gmtime($ticks); 953 954 return sprintf "'%4d-%02d-%02dT%02d:%02d:%02dZ'", $year+1900, $mon+1, $day, $hr, $min, $sec; 955 } 956 957 sub isnull { 958 my $val = shift; 959 960 return (!defined($val) or ($val eq "") or (lc($val) eq "null")); 961 } 962 963 sub iszero { 964 my $val = shift; 965 return (!defined($val) or ($val == 0)); 966 } 967 968 # resolve_project() 969 # get project specific information 970 sub resolve_project { 971 my $ipprc = shift; 972 my $project_name = shift; 973 974 findTools(); 975 976 if (!$project_name) { 977 carp ("project is not defined"); 978 return undef; 979 } 980 981 if ($last_project and ($project_name eq ($last_project->{name}))) { 982 return $last_project; 983 } 984 985 my $dbname = shift; 986 my $dbserver = shift; 987 988 my $verbose = 0; 989 990 my $command = "$pstamptool -project -name $project_name"; 991 $command .= " -dbname $dbname" if defined $dbname; 992 $command .= " -dbserver $dbserver" if defined $dbserver; 993 994 my $proj_hash = runToolAndParse($command, $verbose); 995 if (!$proj_hash or scalar @$proj_hash == 0) { 996 print STDERR "Project $project_name not found\n"; 997 return undef; 998 } 999 1000 $last_project = $proj_hash->[0]; 1001 1002 return $last_project; 1003 } 1004 1005 sub updateCamRunCache { 1006 my $camRun = shift; 1007 die "updateCamRunCache: camRun is nil" if !$camRun; 1008 1009 my $exp_id = $camRun->{exp_id}; 1010 die "updateCamRunCache: exp_id is nil" if !$exp_id; 1011 1012 my $cam_id = $camRun->{cam_id}; 1013 die "updateCamRunCache: cam_id is nil" if !$cam_id; 1014 1015 $camRunByCamIDCache{$cam_id} = $camRun; 1016 1017 # if this camRun is newer than previous update the cache. 1018 # This assumes that the newest has the "best" astrometry 1019 my $previous = $camRunByExpIDCache{$exp_id}; 1020 if ($previous) { 1021 my $previous_cam_id = $previous->{cam_id}; 1022 return if $cam_id < $previous_cam_id; 1023 } 1024 1025 $camRunByExpIDCache{$exp_id} = $camRun; 1026 } 1027 1028 sub getCamRunByExpID { 1029 my $exp_id = shift; 1030 &my_die ("getCamRun: exp_id is nil", $PS_EXIT_PROG_ERROR) if !$exp_id; 1031 1032 return $camRunByExpIDCache{$exp_id}; 1033 } 1034 1035 sub getCamRunByCamID { 1036 my $cam_id = shift; 1037 &my_die ("getCamRun: cam_id is nil", $PS_EXIT_PROG_ERROR) if !$cam_id; 1038 1039 return $camRunByCamIDCache{$cam_id}; 1040 } 1041 1042 sub selectComponents { 1043 my $ipprc = shift; 1044 my $imagedb = shift; 1045 my $req_type = shift; 1046 my $stage = shift; 1047 my $rowList = shift; 1048 my $runList = shift; 1049 my $verbose = shift; 1050 my $results = []; 1051 1052 my ($pointsList, $pointsListName) = tempfile ("/tmp/pointsList.XXXX", UNLINK => !$save_temps); 1053 my $npoints = 0; 1054 foreach my $row (@$rowList) { 1055 print $pointsList "$npoints $row->{CENTER_X} $row->{CENTER_Y}\n"; 1056 $npoints++; 1057 } 1058 close $pointsList; 1059 1060 # XXX: need to loop over these 1061 # my $run = $runList->[0]; 1062 if (($req_type eq "byid") or ($req_type eq "byexp")) { 1063 my ($last_tess_id, $tess_dir_abs, $astrom_file) = ("", "", ""); 1064 foreach my $run (@$runList) { 1065 my $command = "$dvoImagesAtCoords -coords $pointsListName"; 1066 if (($stage eq "chip") or ($stage eq "raw")) { 1067 # XXX: use file rule and handle cameras where the astrometry is solved at 1068 # the chip stage. 1069 $astrom_file = $run->{cam_path_base} . ".smf"; 1070 my $astrom_file_resolved = $ipprc->file_resolve($astrom_file); 1071 $command .= " -astrom $astrom_file_resolved"; 1072 } else { 1073 my $tess_id = $run->{tess_id}; 1074 if ($tess_id ne $last_tess_id) { 1075 $tess_dir_abs = $ipprc->tessellation_catdir( $tess_id ); 1076 $tess_dir_abs = $ipprc->convert_filename_absolute( $tess_dir_abs ); 1077 $last_tess_id = $tess_id; 1078 } 1079 $command .= " -D CATDIR $tess_dir_abs" 1080 } 1081 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 1082 run(command => $command, verbose => $dvo_verbose); 1083 unless ($success) { 1084 # don't fail if the program exited normally and exit status was PSTAMP_NO_OVERLAP 1085 # # That just means that the coordinate didn't match any image/skycell 1086 if (!WIFEXITED($error_code) || (WEXITSTATUS($error_code) ne $PSTAMP_NO_OVERLAP)) { 1087 print STDERR @$stderr_buf; 1088 my $rc = WIFEXITED($error_code) ? WEXITSTATUS($error_code) : $PS_EXIT_SYS_ERROR; 1089 &my_die( "dvoImagesAtCoords failed: $rc", $rc); 1090 } 1091 } 1092 my %components; 1093 my @lines = split "\n", join "", @$stdout_buf; 1094 foreach my $line (@lines) { 1095 my ($ptnum, undef, undef, $component) = split " ", $line; 1096 my $ref = $components{$component}; 1097 if (!$ref) { 1098 $ref = $components{$component} = []; 1099 } 1100 push @$ref, $ptnum; 1101 } 1102 if ($verbose) { 1103 foreach my $c (keys %components) { 1104 my $ref = $components{$c}; 1105 print "component $c contains: "; 1106 foreach my $i (@$ref) { 1107 print "$i "; 1108 } 1109 print "\n"; 1110 } 1111 } 1112 # now find the images for this run 1113 foreach my $c (keys %components) { 1114 my $command; 1115 my $stage_id; 1116 if ($stage eq 'raw') { 1117 $stage_id = $run->{exp_id}; 1118 $command = "$regtool -processedimfile -exp_id $stage_id -class_id $c"; 1119 } elsif ($stage eq 'chip') { 1120 $stage_id = $run->{chip_id}; 1121 $command = "$chiptool -processedimfile -chip_id $stage_id -class_id $c"; 1122 } elsif ($stage eq 'warp') { 1123 $stage_id = $run->{warp_id}; 1124 $command = "$warptool -warped -warp_id $stage_id -skycell_id $c"; 1125 } elsif ($stage eq 'diff') { 1126 $stage_id = $run->{diff_id}; 1127 $command = "$difftool -diffskyfile -diff_id $stage_id -skycell_id $c"; 1128 } 1129 $command .= " -dbname $imagedb"; 1130 my $images = runToolAndParse($command, $verbose); 1131 if (!defined $images) { 1132 # XXX: need to get the set error_code to $PSTAMP_NO_OVERLAP 1133 print "No components containing coordinates found for ${stage}_id $stage_id\n"; 1134 foreach my $row (@$rowList) { 1135 $row->{error_code} = $PSTAMP_NO_OVERLAP; 1136 } 1137 next; 1138 } 1139 if (scalar @$images != 1) { 1140 my $num_images = scalar @$images; 1141 &my_die ("unexpected number of images returned: $num_images\n", $PS_EXIT_PROG_ERROR); 1142 } 1143 my $image = $images->[0]; 1144 1145 my $ref = $components{$c}; 1146 $image->{row_index} = $ref; 1147 if (($stage eq "raw") or ($stage eq 'chip')) { 1148 $image->{astrom} = $astrom_file; 1149 $image->{cam_id} = $run->{cam_id}; 1150 $image->{cam_path_base} = $run->{cam_path_base}; 1151 } 1152 push @$results, $image; 1153 } 1154 } 1155 } else { 1156 &my_die ("sorry not done with $req_type\n", $PS_EXIT_PROG_ERROR); 1157 } 1158 return $results; 1159 } 1160 1161 sub filterRuns { 1162 my $stage = shift; 1163 my $need_magic = shift; 1164 my $inputs = shift; 1165 my $verbose = shift; 1166 1167 if ($inputs and (scalar @$inputs) == 1) { 1168 # one run nothing to do 1169 return $inputs; 1170 } 1171 1172 my $output = []; 1173 1174 return $output if (!$inputs or scalar @$inputs == 0); 1175 1176 my $id_name = $stage . "_id"; 1177 1178 # input list is "order by exp_id, run_id DESC" run_id is one of (chip_id, warp_id, diff_id) 1179 print "Starting filterRuns\n"; 1180 my $last_exp_id = 0; 1181 my $last_run_id = 0; 1182 my $printed = 0; 1183 foreach my $input (@$inputs) { 1184 my $exp_id = $input->{exp_id}; 1185 my $run_id = $input->{$id_name}; 1186 my $magicked = $input->{magicked}; # this will be either stageRun.magicked or stage%file.magicked 1187 my $state = $input->{state}; 1188 1189 # can't process run in these states 1190 if (($state eq 'new') or ($state eq 'purged') or ($state eq 'scrubbed')) { 1191 print "skipping ${stage}Run $run_id for exp_id $exp_id in state $state\n"; 1192 next; 1193 } 1194 1195 $printed = 1 if (($exp_id == $last_exp_id) and ($run_id == $last_run_id)); 1196 1197 # skip if we need magicked run and this one has never been magicked 1198 if ($need_magic and !$magicked) { 1199 print "skipping ${stage}Run $run_id for exp_id $exp_id not magicked\n" if !$printed; 1200 next; 1201 } 1202 1203 if (($exp_id == $last_exp_id) and ($run_id != $last_run_id)) { 1204 print "Skipping duplicate ${stage}Run $run_id for $exp_id\n" if !$printed; 1205 next; 1206 } 1207 print "Keeping ${stage}Run $run_id for $exp_id\n"; 1208 push @$output, $input; 1209 $last_exp_id = $exp_id; 1210 $last_run_id = $run_id; 1211 $printed = 0; 1212 } 1213 1214 my $num_runs = scalar @$output; 1215 print "filterRuns returning $num_runs ${stage}Run\n"; 1216 1217 return $output; 1218 } 1219 1220 # run a command that produces metadata output and parse the results into an array of objects 1221 sub runToolAndParse { 1222 my $command = shift; 1223 my $verbose = shift; 1224 1225 my ($program) = split " ", $command; 1226 $program = basename($program); 1227 1228 print "Running $command\n" if !$verbose; 1229 my $start_tool = DateTime->now->mjd; 1230 # run the command and parse the output 1231 494 1232 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 495 1233 run(command => $command, verbose => $verbose); … … 499 1237 return undef; 500 1238 } 501 my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files 502 503 my $output = join "", @$stdout_buf; 504 if (!$output) { 505 print STDERR "no output returned from $command\n" if $verbose; 1239 1240 my $now = DateTime->now->mjd; 1241 my $dtime_tool = (DateTime->now->mjd - $start_tool) * 86400.; 1242 print "Time to run $program: $dtime_tool\n"; 1243 1244 my $buf = join "", @$stdout_buf; 1245 if (!$buf) { 506 1246 return undef; 507 1247 } 508 my $images = parse_md_fast($mdcParser, $output) or die ("Unable to parse metadata config doc"); 509 510 return $images; 511 } 512 513 # cache of results of ppConfigDump 514 my %astromSources; 515 my $last_exp_id = 0; 516 my $lastAstromFile; 517 518 # find the astrometry file for a given exposure 519 # return undef if no completed camRun exists 520 sub find_astrometry { 521 my $ipprc = shift; 522 my $image_db = shift; 523 my $image = shift; # hashref to output of the lookup tool 524 my $verbose = shift; 525 526 my $exp_id = $image->{exp_id}; 527 if (($exp_id eq $last_exp_id) and $lastAstromFile) { 528 # running camtool 60 times is really expensive when the answer is the same 529 return $lastAstromFile; 530 } 531 $last_exp_id = 0; 532 $lastAstromFile = undef; 1248 1249 my $start_parse = DateTime->now->mjd; 1250 1251 my $mdcParser = PS::IPP::Metadata::Config->new; 1252 my $results = parse_md_fast($mdcParser, $buf) 1253 or die ("Unable to parse metadata config doc"); 1254 1255 my $dtime_parse = (DateTime->now->mjd - $start_parse) * 86400.; 1256 print "Time to parse results from $program: $dtime_parse\n"; 1257 1258 return $results; 1259 } 1260 1261 sub findTools { 1262 return if ($regtool); 533 1263 534 1264 my $missing_tools; 535 my $camtool = can_run("camtool") or (warn "Can't find camtool" and $missing_tools = 1); 536 my $ppConfigDump = can_run('ppConfigDump') or (warn "Can't find ppConfigDump" and $missing_tools = 1); 1265 $regtool = can_run('regtool') or (warn "Can't find regtool" and $missing_tools = 1); 1266 $chiptool = can_run('chiptool') or (warn "Can't find chiptool" and $missing_tools = 1); 1267 $camtool = can_run('camtool') or (warn "Can't find camtool" and $missing_tools = 1); 1268 $warptool = can_run('warptool') or (warn "Can't find warptool" and $missing_tools = 1); 1269 $difftool = can_run('difftool') or (warn "Can't find difftool" and $missing_tools = 1); 1270 $stacktool = can_run('stacktool') or (warn "Can't find stacktool" and $missing_tools = 1); 1271 $pstamptool = can_run('pstamptool') or (warn "Can't find pstamptool" and $missing_tools = 1); 1272 $dvoImagesAtCoords = can_run('dvoImagesAtCoords') or (warn "Can't find dvoImagesAtCoords" 1273 and $missing_tools = 1); 1274 $whichimage = can_run('whichimage') or (warn "Can't find whichimage" and $missing_tools = 1); 1275 $ppConfigDump = can_run('ppConfigDump') or (warn "Can't find ppConfigDump" and $missing_tools = 1); 537 1276 if ($missing_tools) { 538 1277 warn("Can't find required tools."); 539 1278 exit ($PS_EXIT_CONFIG_ERROR); 540 1279 } 541 542 my $command = "$camtool -dbname $image_db -processedexp -exp_id $exp_id"; 543 # run the tool and parse the output 544 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 545 run(command => $command, verbose => $verbose); 546 unless ($success) { 547 print STDERR @$stderr_buf; 548 return undef; 549 } 550 551 my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files 552 553 my $output = join "", @$stdout_buf; 554 if (!$output) { 555 print STDERR "no output returned from $command\n" if $verbose; 556 return undef; 557 } 558 my $camruns = parse_md_fast($mdcParser, $output); 559 if (!$camruns) { 560 return undef; 561 } 562 563 # If there are multiple cam runs for this exposure, take the last one 564 # assuming that it has the best astrometry 565 my $camdata = pop @$camruns; 566 if (!$camdata) { 567 # no cam runs for this exposure id therefore best astrometry is whatever is in the header 568 return undef; 569 } 570 my $camRoot = $camdata->{path_base}; 571 my $camera = $image->{camera}; 572 my $astromSource = $astromSources{$camera}; 573 if (!$astromSource) { 574 my $command = "$ppConfigDump -camera $camera -dump-recipe PSWARP -"; 575 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 576 run(command => $command, verbose => $verbose); 577 unless ($success) { 578 $error_code = (($error_code >> 8) or $PS_EXIT_PROG_ERROR); 579 die("Unable to perform ppConfigDump: $error_code"); 580 } 581 my $metadata = $mdcParser->parse(join "", @$stdout_buf) or 582 die("Unable to parse metadata config doc"); 583 $astromSource = metadataLookupStr($metadata, 'ASTROM.SOURCE'); 584 $astromSources{$camera} = $astromSource; 585 } 586 587 my $astromFile = $ipprc->filename($astromSource, $camRoot); 588 if ($astromFile) { 589 $lastAstromFile = $astromFile; 590 $last_exp_id = $exp_id; 591 } 592 593 return $astromFile; 594 } 595 596 # splits meta data config input stream into single units to work around the pathalogically 597 # slow parser. This is similar to and adapted from code in various ippScripts. 598 sub parse_md_fast { 599 my $mdcParser = shift; 600 my $input = shift; 601 my $output = (); 602 603 my @whole = split /\n/, $input; 604 my @single = (); 605 606 my $n; 607 while ( ($n = @whole) > 0) { 608 my $value = shift @whole; 609 push @single, $value; 610 if ($value =~ /^\s*END\s*$/) { 611 push @single, "\n"; 612 613 my $list = parse_md_list( $mdcParser->parse( join("\n", @single ) ) ) or 614 print STDERR "Unable to parse metdata config doc" and return undef; 615 # my $num = @$list; 616 # print STDERR "list has $num elments\n"; 617 push @$output, $list->[0]; 618 619 @single = (); 620 } 621 } 622 return $output; 623 } 624 625 sub mjd_to_dateobs { 626 my $mjd = shift; 627 628 my $ticks = ($mjd - 40587.0) * 86400; 629 630 my ($sec, $min, $hr, $day, $mon, $year) = gmtime($ticks); 631 632 return sprintf "'%4d-%02d-%02dT%02d:%02d:%02dZ'", $year+1900, $mon+1, $day, $hr, $min, $sec; 633 } 634 635 sub isnull { 636 my $val = shift; 637 638 return (!defined($val) or (lc($val) eq "null")); 639 } 640 641 sub iszero { 642 my $val = shift; 643 return (!defined($val) or ($val == 0)); 644 } 645 646 # resolve_project() 647 # get project specific information 648 my $last_project = ""; 649 sub resolve_project { 650 my $ipprc = shift; 651 my $project_name = shift; 652 653 if (!$project_name) { 654 carp ("project is not defined"); 655 return undef; 656 } 657 658 if ($project_name eq $last_project) { 659 return $last_project; 660 } 661 662 my $dbname = shift; 663 my $dbserver = shift; 664 665 my $verbose = 0; 666 667 my $missing_tools; 668 my $pstamptool = can_run("pstamptool") or (warn "Can't find pstamptool" and $missing_tools = 1); 669 if ($missing_tools) { 670 warn("Can't find required tools."); 671 exit ($PS_EXIT_CONFIG_ERROR); 672 } 673 674 my $command = "$pstamptool -project -name $project_name"; 675 $command .= " -dbname $dbname" if defined $dbname; 676 $command .= " -dbserver $dbserver" if defined $dbserver; 677 # run the tool and parse the output 678 my ( $success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) = 679 run(command => $command, verbose => $verbose); 680 unless ($success) { 681 print STDERR @$stderr_buf; 682 return undef; 683 } 684 685 my $mdcParser = PS::IPP::Metadata::Config->new; # Parser for metadata config files 686 687 my $output = join "", @$stdout_buf; 688 if (!$output) { 689 print STDERR "no output returned from $command\n" if $verbose; 690 return undef; 691 } 692 my $proj_hash = parse_md_fast($mdcParser, $output); 693 694 $last_project = $proj_hash->[0]; 695 696 return $last_project; 1280 } 1281 1282 # add a row_index array to a set of images with entries for each of the rows in a list 1283 sub setRowRefs { 1284 my $rowList = shift; 1285 my $images = shift; 1286 1287 my $row_index = []; 1288 for (my $i = 0; $i < scalar @$rowList; $i++) { 1289 push @$row_index, $i; 1290 } 1291 foreach my $image (@$images) { 1292 $image->{row_index} = $row_index; 1293 } 1294 } 1295 1296 sub my_die 1297 { 1298 my $msg = shift; 1299 my $fault = shift; 1300 1301 carp $msg; 1302 1303 # we don't fault the request here pstamp_parser_run.pl handles that if necessary 1304 1305 return $fault; 697 1306 } 698 1307 1;
Note:
See TracChangeset
for help on using the changeset viewer.
