Subs::SW0WrapUp (version 0.0)


package Subs::SW0WrapUp;
##############################################################################
#
# DESCRIPTION: This subroutine class handles a number of cleanup tasks which 
# DESCRIPTION: need to be done at the end of each processing run,
# DESCRIPTION: including creating output catalog files and verifying
# DESCRIPTION: the product files. Each of these functions is handled
# DESCRIPTION: by a separate method to make it easier to write a sub-class
# DESCRIPTION: which overriseds the default body method.
# DESCRIPTION: 
# DESCRIPTION: Each processing script should run this subroutine class
# DESCRIPTION: (or a decendant of it) last. 
#
# HISTORY: 
# HISTORY: $Log: SW0WrapUp.pm,v $
# HISTORY: Revision 1.31  2005/03/18 20:17:48  apsop
# HISTORY: Put orbit files back into the distribution.
# HISTORY:
# HISTORY: Revision 1.30  2005/03/17 16:50:06  apsop
# HISTORY: Remove TLE file from distribution.
# HISTORY:
# HISTORY: Revision 1.29  2005/03/15 19:54:54  apsop
# HISTORY: Add in code taken from StartEndTimes for writing UTCFINIT keyword.
# HISTORY:
# HISTORY:
# HISTORY: Revision 1.28  2005/03/02 18:19:16  apsop
# HISTORY: Delete any sha1 checksum files still around.
# HISTORY:
# HISTORY: Revision 1.27  2004/12/22 18:11:57  apsop
# HISTORY: Fix up setting of TIERRELA TIERABSO values so that they have decimal points.
# HISTORY:
# HISTORY: Revision 1.26  2004/12/10 03:36:30  apsop
# HISTORY: Do not write _PNT keywords to tdrss files.
# HISTORY:
# HISTORY: Revision 1.25  2004/12/03 13:35:37  apsop
# HISTORY: Make compatible with test pipeline: st versus sw
# HISTORY:
# HISTORY: Revision 1.24  2004/11/29 15:25:03  apsop
# HISTORY: Fix format of TARG_ID and SEG_NUM keywords
# HISTORY:
# HISTORY: Revision 1.22  2004/11/19 21:46:48  apsop
# HISTORY: New version of xrt2fits.
# HISTORY:
# HISTORY: Revision 1.21  2004/11/16 15:35:58  apsop
# HISTORY: Call swiftversion as a real headas tool.
# HISTORY:
# HISTORY: Revision 1.20  2004/11/09 23:42:29  apsop
# HISTORY: Remove telemetry files before making catalogues.
# HISTORY:
# HISTORY: Revision 1.19  2004/11/02 21:20:20  apsop
# HISTORY: Write DATE* keywords into tapecat file.
# HISTORY:
# HISTORY: Revision 1.18  2004/10/25 14:52:07  apsop
# HISTORY: Write timing keywords to primary hdu. Some general reformatting.
# HISTORY:
# HISTORY: Revision 1.17  2004/10/13 19:53:42  apsop
# HISTORY: Remove checksum file from future_files call.
# HISTORY:
# HISTORY: Revision 1.16  2004/10/12 16:22:21  apsop
# HISTORY: Override and do not make the checksum file. Override verify method and turn off testdata option in fverify to speed this up. Add decimal points where needed in two keyowrd values.
# HISTORY:
# HISTORY: Revision 1.15  2004/09/14 18:54:32  apsop
# HISTORY: Do not write SEQPNUM or (default) OBS_ID into tdrss messages.
# HISTORY:
# HISTORY: Revision 1.14  2004/09/02 00:06:22  apsop
# HISTORY: Store software version and cycle in job.par file.
# HISTORY:
# HISTORY: Revision 1.13  2004/08/17 13:57:11  apsop
# HISTORY: Write keywords for software version and for burst in bat source catalogue.
# HISTORY:
# HISTORY: Revision 1.12  2004/07/06 20:02:57  apsop
# HISTORY: Keep track of calibration files and delete them at the end.
# HISTORY:
# HISTORY: Revision 1.11  2004/06/10 19:57:06  apsop
# HISTORY: Add in writing of OBJ, TARG_ID, SEG_NUM and timing keywords.
# HISTORY:
# HISTORY: Revision 1.10  2004/06/07 17:03:44  apsop
# HISTORY: Switch to using _PNT instead of _NOM for ra, dec and roll parameters.
# HISTORY:
# HISTORY: Revision 1.9  2004/05/28 19:44:06  apsop
# HISTORY: Make sure leading zeroes are included in OBS_ID
# HISTORY:
# HISTORY: Revision 1.8  2004/05/06 20:02:34  dah
# HISTORY: Add version number back into the header comments.
# HISTORY:
# HISTORY: Revision 1.7  2004/04/28 13:51:10  dah
# HISTORY: Change SERQNUM keyword to OBS_ID, and remove leading zeroes from SEQPNUM.
# HISTORY:
# HISTORY: Revision 1.6  2004/04/16 20:21:18  dah
# HISTORY: Begin using embedded history records
# HISTORY:
#
# VERSION: 0.0
#
#
##############################################################################

use Subs::Sub;
use Subs::WrapUp;
use Util::SWCatalogue;
@ISA = ("Subs::WrapUp");
use strict;


#########################################
# constructor
#########################################
sub new {
    my $proto=shift;
    my $self=$proto->SUPER::new();

    $self->{DESCRIPTION}="Doing final wrapup of all swift files";

    $self->{FILES}=();
    $self->{FITS_FILES}=();

    $self->{CHECKSUM_TYPE}="checksum";
    $self->{HTML_CAT_TYPE}="fileinfo";

    return $self;
}

#########################################################################
# add standard keywords to the headers of all the FITS files.
#########################################################################
sub write_standard_keywords {

    my $self=shift;

    my $log      = $self->log();
    my $filename = $self->filename();
    my $jobpar   = $self->jobpar();
    my $procpar  = $self->procpar();

    $log->entry("Writing standard keywords to all FITS files");

    #######################
    # Setup for UTCF value
    #######################
    my $time_file = $filename->get('timedata', 'swift', '', 0);
    my (@utcf_times, @utcf);
    if( -f $time_file ){
      my $time_fits = Util::FITSfile->new($time_file, 'UTCF');
      @utcf_times = $time_fits->cols('TIME')->table();
      @utcf = $time_fits->cols('UTCF')->table();
    }

    ####################################
    # Get software versions
    ####################################
    my $fversion;
    open VER, $procpar->read('ftools').'/syspfiles/ftools.par';
    while (<VER>){
      $fversion = $1 if /version,s,h,"([^"]*)"/;
    }
    close VER;

    my $sversion = Util::HEAdas->new('swiftversion')
                               ->is_script(1)
                               ->run();

    my $soft_version = 'Hea_' . $fversion . '_' . $sversion->stdout();
    chomp $soft_version;

    $jobpar->set({softver => $soft_version,
		  cycle   => 1});

    ####################################
    # loop over all FITS files
    ####################################
    my $file;
    foreach $file (Util::SWCatalogue->fits_files() ) {

        my $fits = Util::FITSfile->new($file);
	my $is_tdrss = $file =~ /s[wt][t\d]\d{10}ms/;
	my $is_batevt = $file =~ /s[wt][t\d]\d{10}bev/;
	my $is_eng = $file =~ /s[wt][t\d]\d{10}.*en\.hk$/;

        ##################################
        # loop over HDUs in the FITS file
        ##################################
        my $nhdus = $fits->nhdus();
	unless ($nhdus) {
	  $self->log()->error(2, "Cannot get number of HDUs for FITS file $file.");
	  next;
	}

        my $hdu;
        for($hdu=0; $hdu<$nhdus; $hdu++) {
            $fits->ext($hdu);
	    my $extname = $fits->keyword('EXTNAME');

            ################################
            # write keywords to the file
            ################################
            $fits->begin_many_keywords();

            $fits->keyword('PROCVER', $procpar->read('version'), 
                           'Processing script version' );

	    unless( $is_eng || ($extname && $extname=~/GTI/) ){
	      $fits->keyword('SOFTVER', $soft_version, 'HEASOFT and Swift versions');
	    }	    

	    if($hdu==0){
	      $fits->keyword('TIMESYS', 'TT', 'time measured from');
	      $fits->keyword('MJDREFI', 51910, 'MJD reference day');
	      $fits->keyword('MJDREFF', 7.428703700000000E-04, 
			     'MJD reference (fraction of day)');
	      $fits->keyword('CLOCKAPP', 'F', 'default');
	      $fits->keyword('TIMEUNIT', 's', 'unit for time keywords');
	    }else{
	      $fits->keyword('TIERRELA', '1.0E-8', '[s/s] Estimated relative clock rate error');
	      $fits->keyword('TIERABSO', '1.0', '[s] Estimated absolute clock offset error');
	    }

	    unless($is_tdrss){
              $fits->keyword('OBS_ID', sprintf("'%011d'", $jobpar->read('sequence')), 
                             'Observation ID' );

              $fits->keyword('SEQPNUM', int($jobpar->read('seqprocnum')), 
                             'Number of times the dataset processed' );

	      $fits->keyword('TARG_ID', int(sprintf("%d",$jobpar->read('target'))),
			     'Target ID');
	      $fits->keyword('SEG_NUM', int(sprintf("%d",$jobpar->read('obs'))),
			     'Segment number');

	      $fits->keyword('OBJECT', $jobpar->read('object'), 'Object name');
	      $fits->keyword('RA_OBJ', $jobpar->read('burst_ra'), '[deg] RA Object');
	      $fits->keyword('DEC_OBJ', $jobpar->read('burst_dec'), '[deg] Dec Object');

	      $fits->keyword('RA_PNT', $jobpar->read('ra'), '[deg] RA pointing');
	      $fits->keyword('DEC_PNT', $jobpar->read('dec'), '[deg] Dec pointing');
	      $fits->keyword('PA_PNT', $jobpar->read('roll'), '[deg] Position angle (roll)');
	    }

	    if($is_batevt){
	      $fits->keyword('CATSRC',
			     $jobpar->read('burst_cat_src') eq 'yes' ? 'T' : 'F'); 
	    }

            #############################
            # Determine and set UTCFINIT
            #############################
            my $tstart = $fits->keyword('TSTART');
            unless( $tstart ){
              my $date = $fits->keyword('DATE-OBS');
              if( $date ){
                my $start = Util::Date->new($date);
                $tstart = $start->seconds();
              }
            }

            if( $tstart && @utcf ){
	      my $itime = 0;
	      while( $tstart > $utcf_times[$itime] && 
                     $itime < $#utcf_times){ $itime++ }
	      $fits->keyword('UTCFINIT', $utcf[$itime], '[s] UTCF at TSTART');
            }

            $fits->end_many_keywords();
        }

    }

} # end of write_standard_keywords method

###########################################################################
# make all FITS catalogs and the HTML file catalog
###########################################################################
sub make_catalogs {
    my $self=shift;

    my $jobpar   = $self->jobpar();

    my $filename=$self->filename();

    unlink @{$filename->{CAL_FILES}};
    unlink $filename->any('telemetry');
    ###    unlink $filename->fetch_orbit();
    unlink glob '*.sha1';

    ######################################################
    # get names of catalogs, and assume the HTML catalog 
    # has the same files as the first FITS catalog
    ######################################################
    my @fits_catalogs=$filename->catalog_types();
    my $html_cat_is_like=$fits_catalogs[0];

    ##########################################################
    # register the files we have yet to make with the 
    # Catalog class
    ##########################################################
    Util::SWCatalogue->filename($filename);
    Util::SWCatalogue->future_files((map     {$_=>'FITS'} @fits_catalogs),
				    'fileinfo' =>'HTML');

    ###############################################
    # create FITS catalogs
    ###############################################
    my $type;
    foreach $type (@fits_catalogs ) {

        Util::SWCatalogue->new($type)
	                 ->make()
                         ->register_in_parfile();
    }
    
    my $date = Util::Date->new();
    my $fitscat = Util::FITSfile->new($filename->get('tapecat', 'proc', '', 0));
    foreach my $ext (0,1){
      $fitscat->ext($ext);
      $fitscat->keyword('DATE-OBS', $jobpar->read('obsdate') .'T'. $jobpar->read('obstime'));
      $fitscat->keyword('DATE-END', $jobpar->read('enddate') .'T'. $jobpar->read('endtime'));
      $fitscat->keyword('DATE', $date->date() .'T'. $date->time());
    }



    ########################################
    # create the HTML catalog
    ########################################
    Util::HTMLcatalog->new($html_cat_is_like,'fileinfo')
                     ->make();

} # end of make_catalogs method

########################################################
# Don't make a checksum file.  This is done by the DTS
########################################################
sub make_checksum_file {
    my $self=shift;

    my $log=$self->log();

    $log->entry('Not making a checksum file');

} # end of make_checksums method


#####################################
# run fverify on all the FITS files
#####################################
sub verify {
    my $self=shift;

    my $log=$self->log();

    $log->entry('Running fverify on all FITS files');

    #######################################################
    # set up fverify. Set testdata='no' to speed things up
    #######################################################
    my $fverify=Util::Ftool->new('fverify')
                           ->params({outfile=>'STDOUT',
                                     prhead=>'no',
                                     testdata=>'no'})
                           ->verbose(0);

    ######################################
    # loop over all FITS files
    ######################################
    my $file;
    foreach $file (Util::Catalog->fits_files() ) {

        Util::FITSfile->new($file)
                      ->verify();
    }

 
} # end of verify method