IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 21, 2014, 5:42:34 AM (12 years ago)
Author:
eugene
Message:

merge changes from trunk

Location:
branches/eam_branches/ps2-tc3-20130727
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ps2-tc3-20130727

  • branches/eam_branches/ps2-tc3-20130727/PS-IPP-PStamp/lib/PS/IPP/PStamp/Job.pm

    r35625 r36680  
    3434use POSIX;
    3535use Time::HiRes qw(gettimeofday);
     36use IO::Handle;
    3637
    3738my $dvo_verbose = 0;
     
    176177        $need_magic, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $mjd_min, $mjd_max,
    177178        0, 0,   # fwhm cuts are not applied here
    178         undef, undef, undef, $verbose);
     179        undef, 0, # no cam run information
     180        undef, undef, $verbose);
    179181
    180182    return $results;
     
    243245    if (isnull($filter)) {
    244246        $filter = undef;
     247    }
     248
     249    if ($stage eq 'stack_summary') {
     250        # stack_summary jobs are so different from others that we lookup in a specialized function
     251        return lookup_stack_summary($ipprc, $row, $imagedb, $tess_id, $component, $filter, $data_group, $option_mask, $mjd_min, $mjd_max, $verbose);
    245252    }
    246253
     
    322329        0, $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $mjd_min, $mjd_max,
    323330        getValOrZero($row->{FWHM_MIN}), getValOrZero($row->{FWHM_MAX}),
    324         undef, $release_name, $survey,
     331        undef, 0, $release_name, $survey,
    325332        $verbose);
    326333
     
    351358    my $fwhm_max = shift;
    352359    my $selectedAstrom = shift;
     360    my $selected_cam_id = shift;
    353361    my $release_name = shift;
    354362    my $survey = shift;
     
    460468            $skycell_id = $component;
    461469            $choose_components = 1;
     470            if ($req_type eq 'byskycell' and $skycenter) {
     471                # Add a wide coordinate cut to the releasetool command.
     472                # This greatly speeds up the query by reducing the number of exposures considered
     473                # to those near the region of interest.
     474                # The actual radius value that we use is not critical because the skycell cut does the relevant
     475                # selection.
     476                $command .= " -ra $row->{CENTER_X} -decl $row->{CENTER_Y} -radius 5.0";
     477            }
    462478        } else {
    463479            $command = "$warptool -pstamp_order -dbname $imagedb";
     
    602618        # The image selectors are such that multiple runs my have be returned for the same exposure.
    603619        # Return only the latest one.
    604         $images = filterRuns($stage, $need_magic, $images, $inverse, $verbose);
     620        $images = filterRuns($stage, $choose_components, $need_magic, $images, $inverse, $verbose);
    605621    }
    606622
     
    685701                $out->{data_state} = $out->{state} = $out->{stack_state};
    686702            } else {
    687                 # XXX: Consider looking up skycal results even if we are
     703                $out->{data_state} = $out->{state};
     704
     705                # XXX: Consider looking up skycal and staticsky results even if we are
    688706                # not using releasetool
    689                 $out->{data_state} = $out->{state};
    690707            }
    691708        }
     
    699716                $out->{astrom} = $selectedAstrom;
    700717                $out->{cam_path_base} = $selectedAstrom;
     718                $out->{cam_id} = $selected_cam_id if $selected_cam_id;
    701719                if ($selectedAstrom =~ /\.smf$/) {
    702720                    $out->{cam_path_base} =~ s/\.smf$//;
     
    722740            $out->{mask}   = $ipprc->filename($mask_name,   $mask_base, $class_id) if $mask_name;
    723741            $out->{weight} = $ipprc->filename($weight_name, $base, $class_id) if $weight_name;
    724             $out->{cmf}    = $ipprc->filename($cmf_name,    $base, $class_id) if $cmf_name;
    725             $out->{psf}    = $ipprc->filename($psf_name,    $base, $class_id) if $psf_name;
    726742            $out->{backmdl}= $ipprc->filename($backmdl_name,$base, $class_id) if $backmdl_name;
     743            if ($image->{staticsky_path_base}) {
     744                $out->{psf}    = $ipprc->filename("PSPHOT.STACK.PSF.SAVE", $image->{staticsky_path_base}, $image->{stack_id});
     745                # if astrom was not set above to the skycal cmf get the sources file from staticsky
     746                $out->{cmf}    = $ipprc->filename("PSPHOT.STACK.OUTPUT",   $image->{staticsky_path_base}, $image->{stack_id}) if !$out->{astrom};
     747            } else {
     748                $out->{psf}    = $ipprc->filename($psf_name,    $base, $class_id) if $psf_name;
     749                $out->{cmf}    = $ipprc->filename($cmf_name,    $base, $class_id) if $cmf_name;
     750            }
    727751        }
    728752
     
    731755
    732756    return $output;
     757}
     758
     759sub lookup_stack_summary {
     760    my ($ipprc, $row, $imagedb, $tess_id, $component, $filter, $data_group, $option_mask, $mjd_min, $mjd_max, $verbose) = @_;
     761
     762    $row->{error_code} = $PSTAMP_NO_IMAGE_MATCH;
     763
     764    $component = '' if $component eq 'all';
     765
     766    my $req_type = $row->{REQ_TYPE};
     767    my $results;
     768    if ($req_type eq 'byid') {
     769        my $sass_id = $row->{ID};
     770        my $command = "$stacktool -dbname $imagedb -summary -sass_id $sass_id";
     771        $results = runToolAndParse($command, $verbose);
     772    } else {
     773        my ($release_name, $survey, $default_tess_id) = get_release_info($row);
     774        if (!$tess_id and $default_tess_id) {
     775            $tess_id = $default_tess_id;
     776        }
     777
     778        my $skycells;
     779        if ($req_type eq 'bycoord') {
     780            my $ra = $row->{CENTER_X};
     781            my $dec = $row->{CENTER_Y};
     782            $skycells = lookup_skycell_by_coords($ipprc, $tess_id, $component, $ra, $dec, $verbose);
     783        } elsif ($req_type eq 'byskycell') {
     784            if (!defined $tess_id or !defined $component) {
     785                print STDERR "Error: TESS_ID and  COMPONENT are required for REQ_TYPE byskycell\n";
     786                $row->{error_code} = $PSTAMP_INVALID_REQUEST;
     787            }
     788            my $skycell = {
     789                tess_id    => $tess_id,
     790                component => $component
     791            };
     792            push @$skycells, $skycell
     793        } else {
     794            print STDERR "Error: $req_type is not a valid REQ_TYPE for IMG_TYPE stack_summary\n";
     795            $row->{error_code} = $PSTAMP_INVALID_REQUEST;
     796            return undef;
     797        }
     798
     799        if ($skycells) {
     800            # We have a list of skycells. Find matching projection cells.
     801            # and then matching rows in stackSummary
     802
     803            my %projection_cells_found;
     804            foreach my $skycell (@$skycells) {
     805                my $tess_id = $skycell->{tess_id};
     806                my $skycell_id = $skycell->{component};
     807
     808                my $projection_cell = skycell_id_to_projection_cell($skycell_id);
     809
     810                # only need to include a projection cell once
     811                next if $projection_cells_found{$projection_cell};
     812
     813                $projection_cells_found{$projection_cell} = 1;
     814
     815                # print "$tess_id $skycell_id $projection_cell\n";
     816
     817                my $command;
     818                if ($release_name or $survey) {
     819                    $command = "$releasetool -dbname $imagedb";
     820                    if ($release_name) {
     821                        $command .= " -release_name $release_name";
     822                    } else {
     823                        $command .= " -priority_order";
     824                    }
     825                    $command .= " -surveyName $survey" if $survey;
     826                } else {
     827                    $command = "$stacktool -dbname $imagedb";
     828                }
     829                $command .= " -summary -tess_id $tess_id";
     830                $command .= " -projection_cell $projection_cell";
     831
     832                $command .= " -filter $filter" if $filter;
     833                $command .= " -data_group $data_group" if $data_group;
     834
     835                my $these_results = runToolAndParse($command, $verbose);
     836                push @$results, @$these_results if $these_results;
     837            }
     838        }
     839    }
     840
     841    if ($results) {
     842        foreach my $summary (@$results) {
     843            my $path_base = $summary->{path_base};
     844            my $projection_cell = $summary->{projection_cell};
     845
     846            # we need to flesh out the hashes returned with values that the parser expects
     847            $summary->{stage} = 'stack_summary';
     848            $summary->{component} = $projection_cell;
     849            $summary->{stage_id} = $summary->{sass_id};
     850            $summary->{path_base} = "$path_base.$projection_cell";
     851
     852            # The stack_summary stage doesn't follow the usual ipp conventions for file rules
     853            # and path_base. We leave it up to the program that runs the job to handle this.
     854            # However, the parser uses the image parameter to set the job's outputBase (by removing the .fits)
     855            # so we need to set it. Just use the new path_base.
     856            $summary->{image} = $summary->{path_base};
     857            $summary->{state} = 'full';
     858            $summary->{data_state} = 'full';
     859            $summary->{fault} = 0;
     860            $summary->{imagedb} = $imagedb;
     861            $summary->{row_index} = [];
     862            push @{$summary->{row_index}}, 0;
     863
     864            # XXX: Are there any other required parameters?
     865            # TODO: create a function to validate the components returned
     866            # and make sure that any required elements are there.
     867        }
     868    }
     869
     870    return $results;
    733871}
    734872
     
    9461084                    $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $mjd_min, $mjd_max,
    9471085                    $fwhm_min, $fwhm_max,
    948                     $chip->{astrom}, undef, undef,
     1086                    $chip->{astrom}, $chip->{cam_id}, undef, undef,
    9491087                    $verbose);
    9501088
     
    9641102            setErrorCodes($rowList, $PSTAMP_NO_IMAGE_MATCH);
    9651103        } else {
    966             # XXX: We are not applying the fwhm cuts
     1104            # XXX: We are not applying the fwhm cuts unless we use releasetool
    9671105            foreach my $skycell (@$skycells) {
    9681106                my $these_results = lookup($ipprc, $rowList, $imagedb, "byskycell", $stage, undef,
     
    9701108                    $dateobs_begin, $dateobs_end, $filter, $data_group, $option_mask, $mjd_min, $mjd_max,
    9711109                    $fwhm_min, $fwhm_max,
    972                     undef, $release_name, $survey,
     1110                    undef, 0, $release_name, $survey,
    9731111                    $verbose);
    9741112
     
    11661304
    11671305    my @lines;
    1168     {
     1306    my $looked_up_fast;
     1307    if ($requested_tess_id) {
     1308        # try using the last method first
     1309        $looked_up_fast = lookup_skycells_fast($ipprc, \@lines, $requested_tess_id, $ra, $dec, $verbose);
     1310    }
     1311   
     1312    if (!$looked_up_fast) {
    11691313        my $command = "$whichimage $ra $dec";
    11701314        $command .= " --tess_id $requested_tess_id" if $requested_tess_id;
     
    13021446    $image->{astrom} = $astromFile;
    13031447    $image->{cam_path_base} = $camRoot;
     1448    $image->{cam_id} = $camRun->{cam_id};
    13041449
    13051450    return 1;
     
    16491794sub filterRuns {
    16501795    my $stage      = shift;
     1796    my $drop_duplicate_runs = shift;
    16511797    my $need_magic = shift;
    16521798    my $inputs     = shift;
     
    16941840        }
    16951841
    1696         $printed = 1 if (($exp_id == $last_exp_id) and ($run_id == $last_run_id));
     1842        # $printed = 1 if (($exp_id == $last_exp_id) and ($run_id == $last_run_id));
    16971843
    16981844        # skip if we need magicked run and this one has never been magicked
     
    17021848        }
    17031849
    1704         if (($exp_id == $last_exp_id) and ($run_id != $last_run_id)) {
     1850        if (($exp_id == $last_exp_id) and ($drop_duplicate_runs || ($run_id != $last_run_id))) {
    17051851            print "Skipping duplicate ${stage}Run $run_id for $exp_id\n" if !$printed;
    17061852            next;
     
    18732019    return $diff_mode;
    18742020}
     2021
     2022sub setErrorCodesForRows {
     2023    my $rowList = shift;
     2024    my $error_code = shift;
     2025
     2026    foreach my $row (@$rowList) {
     2027        $row->{error_code} = $error_code;
     2028    }
     2029
     2030}
     2031
     2032# Convert from skycell_id to projection_cell
     2033# This code is not particularly elegant but I think that it matches the SQL used
     2034# to create stackAssocations does.
     2035
     2036sub skycell_id_to_projection_cell {
     2037    my $skycell_id = shift;
     2038
     2039    # split skycell_id into '.' separated components
     2040    my @strs = split '\.', $skycell_id;
     2041
     2042    my $num = scalar @strs;
     2043
     2044    # projection_cell is 'skycell_id' plus all .num values except the last one
     2045    my $projection_cell = $strs[0];
     2046    for (my $i=1; $i < $num - 1; $i++) {
     2047        $projection_cell .= ".$strs[$i]";
     2048    }
     2049
     2050    return $projection_cell;
     2051}
     2052
     2053# lookup_skycells_fast()
     2054# Lookup using a "skycell server" process which is implemented by running dvoImagesAtCoords in "server" mode.
     2055# Repeated calls to this function will reuse an existing process. This avoids having to loading the
     2056# tessellation over and over again for each skycell lookup.
     2057# When this parse process exists, the pipes are closed which causes the skycell server to exit.
     2058
     2059my $scs_tess_id;    # tess_id for existing scs (skycell server) (if any)
     2060my $scs_out;        # reference filehandle for sending data to the scs
     2061my $scs_in;         # filehandle for response from scs
     2062
     2063sub lookup_skycells_fast {
     2064    my ($ipprc, $results, $tess_id, $ra, $dec, $verbose) = @_;
     2065
     2066    # see if we need to start the scs (skycell server)
     2067
     2068    my $very_verbose = 0;
     2069
     2070    if (!$scs_tess_id or ($scs_tess_id ne $tess_id)) {
     2071        if ($scs_tess_id) {
     2072            # tess_id has changed, close down existing scs
     2073            close $scs_out;
     2074            $scs_out = undef;
     2075            close $scs_in;
     2076            $scs_in = undef;
     2077            $scs_tess_id = undef;
     2078        }
     2079
     2080        # convert tess_id to a directory name
     2081        my $tess_dir = $ipprc->tessellation_catdir( $tess_id );
     2082        unless ($tess_dir) {
     2083            print STDERR "Unrecognized tess_id: $tess_id\n";
     2084            return 0;
     2085        }
     2086
     2087        # convert tess_dir to an absolute directory name
     2088        my $tess_dir_resolved = $ipprc->convert_filename_absolute( $tess_dir );
     2089        unless ($tess_dir_resolved and -d $tess_dir_resolved) {
     2090            print STDERR "failed to resolve tessellation directory for $tess_id\n";
     2091            return 0;
     2092        }
     2093
     2094        # start an scs
     2095        print "Starting skycell server for $tess_dir_resolved.\n";
     2096
     2097        # create pipes for communicating with the server
     2098        pipe $scs_in, SERVER_WRITER;
     2099        pipe SERVER_READER, $scs_out;
     2100
     2101        # set our output to be unbuffered
     2102        $scs_out->autoflush(1);
     2103
     2104        # FORK
     2105        my $scs_pid = fork();
     2106
     2107        if (!$scs_pid) {
     2108            unless (defined $scs_pid) {
     2109                # This is still in parent process. No joy.
     2110                print STDERR "fork of skycell server failed: $!";
     2111                return 0;
     2112            }
     2113
     2114            # This code is running in the child process - the skycell server
     2115            # Close file handles for the parent's ends of the pipes
     2116            close $scs_in;
     2117            close $scs_out;
     2118            # close stdio filehandles. we are about to redirect them
     2119            # (STDERR stays open pointing to the parser log)
     2120            close STDIN;
     2121            close STDOUT;
     2122
     2123            # redirect our stdio file handles to the proper end of the pipes
     2124            open (STDIN,  "<&SERVER_READER")   or die "\nSCS: failed to redirect stdin";
     2125            open (STDOUT, ">>&SERVER_WRITER")  or die "\nSCS: failed to redirect stdout";
     2126
     2127            # All set. Now exec dvoImagesAtCoords
     2128
     2129            my $command = "$dvoImagesAtCoords -D CATDIR $tess_dir_resolved -coords -";
     2130
     2131            print STDERR "SCS: execing $command\n" if $very_verbose;
     2132
     2133            unless(exec $command) {
     2134                # note parent will notice that we are gone due to the pipes getting broken
     2135                # when this child dies.
     2136                die "SCS: failed to exec $command";
     2137            }
     2138        }
     2139
     2140        # This code is running in the parent process (the parser).
     2141        # We have succesfully launched the scs process.
     2142        # Close file handles for the scs' end of the pipes.
     2143        close SERVER_WRITER;
     2144        close SERVER_READER;
     2145
     2146        # remember the tess_id
     2147        $scs_tess_id = $tess_id;
     2148    }
     2149
     2150    # send coordinates to the skycell server and wait for the results
     2151    # (which come nearly instantly which is the point of doing this)
     2152
     2153    # If pipes to the skycell server die, don't abort.
     2154    # Our reads and writes detect errors and act sensibly.
     2155    local $SIG{PIPE} = 'IGNORE';
     2156
     2157    # write the coordinates to the pipe
     2158    my $write_ok = print $scs_out "1 $ra $dec\n";
     2159    if (!$write_ok) {
     2160        # server process probably didn't start properly or died. Fail.
     2161        # Caller will attempt to use the conventional method.
     2162        print STDERR "write to skycell server failed. Error is $!\n";
     2163        return 0;
     2164    }
     2165
     2166    print STDERR "  sent coordinates to skycell server\n" if $very_verbose;
     2167
     2168    my $received_done = 0;
     2169
     2170    # Wait for response. If pipe breaks the read returns with no data.
     2171    while (my $line = <$scs_in>) {
     2172        chomp $line;
     2173        if ($line eq 'DONE') {
     2174            # No more results for these coordinates.
     2175            $received_done = 1;
     2176            print STDERR "    received DONE\n" if $very_verbose;
     2177            last;
     2178        }
     2179        print STDERR "    received $line\n" if $very_verbose;
     2180
     2181        # The caller expects the output to be in the format used by whichimage
     2182        # which omits the point number and includes the tess_id.
     2183        my ($ptnum, $raout, $decout, $skycell_id) = split " ", $line;
     2184
     2185        my $out = "$raout $decout $tess_id $skycell_id";
     2186
     2187        # print the result to the log
     2188        print "$out\n" if $verbose;
     2189
     2190        push @$results, $out;
     2191    }
     2192
     2193    print STDERR "Out of wait for responses loop\n" if $very_verbose;
     2194
     2195    if (!$received_done) {
     2196        # something has gone wrong.
     2197        print STDERR "Read loop exited without receiving DONE.\n";
     2198
     2199        die "BAILING out" if $very_verbose;
     2200
     2201        # forget about the existing server instance
     2202        $scs_tess_id = undef;
     2203        close $scs_out;
     2204        close $scs_in;
     2205
     2206        # drop any results received so far
     2207        @$results = ();
     2208        return 0;
     2209    }
     2210
     2211    return 1;
     2212}
     2213
    18752214       
    18762215
Note: See TracChangeset for help on using the changeset viewer.