package USNOExtract; use strict; use English; use Carp; use vars qw(@ISA $VERSION $name $author $date $version @instList $numberOfStreams); @ISA = qw(Module); use ModuleResources; use FITSUtils; # Declare identity, version, author, date, etc. $name=__PACKAGE__; $VERSION='0.07'; $version = $VERSION; $author='Ian Stewart,Duncan John Fyfe, Duncan Law-Green'; $date='2012-03-21'; # # ChangeLog # ========= # # version 0.07 - 2012-03-21 DLG # ------------ # # + use CALIND file as input to catprep instead of dummy image # # Version 0.06 - 2012-02-29 DLG # ------------ # # + Modifications for catprep in place of imcat # # Version 0.05 - 2010-01-12 DLG # ------------ # # + Manual set of DATE and CREATOR keywords in output REFCAT file # # Version 0.04 - 2009-10-13 DLG # ------------ # # + REFCAT takes subset of FITS headers from Attitude Timeseries (ATTTSR) file # # Version 0.03 - 2009-10-11 DLG # ------------ # # + Added generation of USNO reference catalogue (REFCAT) as final product # # Version 0.02 - 2005-11-22 DJF # ------------ # # + Added call to crosscorrelationCatalogue to get catalogue details from the pipeline configuration. # # Version 0.01 - 2005-11-18 IMS # ------------ # # + First production version. # # Declare list of instruments this module is interested in @instList=qw(all); # Number of streams sub numberOfStreams { return 1; } sub evaluateRules { # If upstream module has been ignored, so if this one return ignore() if allIgnored( module => 'ExpChooser' , instrument => 'epn' ) and allIgnored( module => 'ExpChooser' , instrument => 'emos1' ) and allIgnored( module => 'ExpChooser' , instrument => 'emos2' ) and allIgnored( module => 'ExpChooser' , instrument => 'om' ); # Start conditions start() if allComplete( module => 'ExpChooser' , instrument => 'epn' ) and allComplete( module => 'ExpChooser' , instrument => 'emos1' ) and allComplete( module => 'ExpChooser' , instrument => 'emos2' ) and allComplete( module => 'ExpChooser' , instrument => 'om' ) and complete( module => 'GlobalHK' , instrument => 'all' , stream => 1 ); } sub performAction { info("Module version number: $version"); my $attFile=findFile( class => 'product' , instrument => 'all' , content => 'Attitude time series' , required => 'true' ); my $raDeg = readFITSKeyword( file => $attFile , extension => 'PRIMARY' , keyword => 'MAHFRA' ); my $decDeg = readFITSKeyword( file => $attFile , extension => 'PRIMARY' , keyword => 'MAHFDEC' ); my $raDegStr = sprintf "%21.14e", $raDeg; my $decDegStr = sprintf "%21.14e", $decDeg; my $kwdAsciiFile=newFile( class => 'intermediate' , instrument => thisInstrument , content => 'fimgcreate kwds' , format => 'ASCII' ); open(FMT, ">$kwdAsciiFile"); print FMT "CTYPE1 = 'RA---TAN' / Coord. type: RA tangent plane projection\n"; print FMT "CRPIX1 = 3.24506250000000E+02 / WCS reference pixel\n"; print FMT "CRVAL1 = $raDegStr / [deg] coord. at X axis ref. pixel\n"; print FMT "CUNIT1 = 'deg ' / Physical units of X axis\n"; print FMT "CDELT1 = -1.11111111111111E-03 / WCS pixel size\n"; print FMT "CTYPE2 = 'DEC--TAN' / Coord. type: DEC tangent plane projection\n"; print FMT "CRPIX2 = 3.24506250000000E+02 / WCS reference pixel\n"; print FMT "CRVAL2 = $decDegStr / [deg] coord. at Y axis ref. pixel\n"; print FMT "CUNIT2 = 'deg ' / Physical units of Y axis\n"; print FMT "CDELT2 = 1.11111111111111E-03 / WCS pixel size\n"; print FMT "RA_PNT = $raDegStr / [deg] RA of instrument pointing\n"; print FMT "DEC_PNT = $decDegStr / [deg] Dec of instrument pointing\n"; close(FMT); my $dummyImageFile=newFile( class => 'intermediate' , instrument => thisInstrument , content => 'dummy image' ); doCommand( 'fimgcreate' , bitpix => 8 , naxes => "'648,648'" , datafile => "none" , outfile => $dummyImageFile , headfile => $kwdAsciiFile ) or return exception(); my $calIndex = findFile( class => 'product' , instrument => 'all' , content => 'Calibration index file' , format => 'FITS' ); my $usnoList = newFile( class => 'intermediate' , instrument => thisInstrument , content => 'Reference catalogue' , format => 'FITS' ); # Provides catalogue and variant values. #my $cat = crosscorrelationCatalogue(); #usnoSourceSearch( # %$cat # ,image => $dummyImageFile # ,list => $usnoList # ); # call catprep to generate multi-catalogue file # pass dummy image file rather than source list, need catprep-0.3+ # Hopefully downstream OM tasks will now cope with this? # Try using CALIND file as this has RA_PNT, DEC_PNT headers doCommand( 'catprep' , srclistset => $calIndex , catextract => $usnoList ); # Generate USNO reference catalogue as final product my $usnoProdList = newFile( class => 'product' , instrument => thisInstrument, , content => 'Reference catalogue' , format => 'FITS' ); copyFile( source => $usnoList , destination => $usnoProdList ); # Copy subset of fits headers from Attitude Time Series file # This is an ugly hack. The PCMS code needs a FITS header block copy function and I can't find one ;-p # pre-define hash of headers and types, since there isn't a utility function readFITSType either... my %hdrsToCopy = ( "TELESCOP" => '"string"', "OBS_MODE" => '"string"', "OBS_ID" => '"string"', "RA_OBJ", => '"real"', "DEC_OBJ" => '"real"', "DATE-OBS" => '"string"', "DATE-END" => '"string"', ); # Define comment strings my $comment_start = "*** Additional keywords copied from " . $attFile; my $comment_end = "============= END OF COPY =========="; # Add leading comment # disable this temporarily until dsaddcomment registered in config (sigh...) # doCommand( # 'dsaddcomment' # , text => $comment_start # , object => $usnoProdList # ); # Loop over comments to add my @headers = (); my @types = (); my @commentsToCopy = (); my @stringValuesToCopy = (); my @realValuesToCopy = (); my $header; # Loop over headers to copy foreach $header ( keys %hdrsToCopy ) { # Read keywords, comments from attitude time series push(@headers, $header); push(@types, $hdrsToCopy{$header}); my $keywordval = readFITSKeyword( file => $attFile , extension => 'PRIMARY' , keyword => $header ); my $commentval = readFITSComment( file => $attFile , extension => 'PRIMARY' , keyword => $header ); info("Reading keyword $header value $keywordval comment $commentval"); # Branch depending on FITS header type if ($hdrsToCopy{$header} =~ /string/) { push(@commentsToCopy, $commentval); push(@stringValuesToCopy, $keywordval); } else { push(@commentsToCopy, $commentval); push(@realValuesToCopy, $keywordval); } } # Write headers to output REFCAT file doCommand('addattribute' , set => $usnoProdList , attributename => [ @headers ] , attributetype => [ @types ] , stringvalue => [ @stringValuesToCopy ] , realvalue => [ @realValuesToCopy ] , attributecomment => [ @commentsToCopy ] ) or return exception(); # Produce an appropriately formatted creation date my @creationdate = localtime; my $creationdate = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d.000', $creationdate[5]+1900, $creationdate[4]+1, $creationdate[3], $creationdate[2], $creationdate[1], $creationdate[0] ); # Write creation date to FITS header (instantiation should do this automatically and reliably dammit!) # doCommand('addattribute' # , set => $usnoProdList # , attributename => '"DATE"' # , attributetype => '"string"' # , stringvalue => $creationdate # , attributecomment => '"\"creation date\""' # ) or return exception(); FITSUtils::writeKeyword($usnoProdList, "PRIMARY", "DATE" => { value => "$creationdate", comment => "creation date"}); # Write file creator to FITS header my $creator = 'USNOExtract-0.05'; # doCommand('addattribute' # , set => $usnoProdList # , attributename => '"CREATOR"' # , attributetype => '"string"' # , stringvalue => $creator # , attributecomment => '"\"name of code which created this file\""' # ) or return exception(); FITSUtils::writeKeyword($usnoProdList, "PRIMARY", "CREATOR" => {value => "$creator", comment => "name of code which created this file"}); # Add trailing comment # doCommand( # 'dsaddcomment' # , text => $comment_end # , object => $usnoProdList # ); return success(); } 1;