Subs::BAT2FITS (version 0.0)


package Subs::BAT2FITS;
##############################################################################
#
# DESCRIPTION: This subroutine Converts BAT telemetry to FITS files.
# DESCRIPTION: It then merges event and rate data files.
#
# HISTORY: 
# HISTORY: $Log: BAT2FITS.pm,v $
# HISTORY: Revision 1.29  2005/03/25 20:16:39  apsop
# HISTORY: Fix up file names for hk event files.
# HISTORY:
# HISTORY: Revision 1.28  2004/12/10 02:18:11  apsop
# HISTORY: Set override to yes in bat2fits only if mission is not sw.
# HISTORY:
# HISTORY: Revision 1.27  2004/12/07 15:31:01  apsop
# HISTORY: Set lpdspan=no in bat2fits; rename tdrss messages is mission is not sw.
# HISTORY:
# HISTORY: Revision 1.26  2004/12/05 23:22:34  apsop
# HISTORY: Add override option to bat2fits.
# HISTORY:
# HISTORY: Revision 1.25  2004/09/15 22:30:27  apsop
# HISTORY: Changes to account for different convention for naming mask tagged weights and lightcurves.
# HISTORY:
# HISTORY: Revision 1.24  2004/09/03 12:36:05  apsop
# HISTORY: Give mask tagged lc their own type and file class
# HISTORY:
# HISTORY: Revision 1.23  2004/09/03 00:21:45  apsop
# HISTORY: Give mask tagged lc their own type and file class
# HISTORY:
# HISTORY: Revision 1.22  2004/07/23 19:47:41  apsop
# HISTORY: Time sort bat lpd header file
# HISTORY:
# HISTORY: Revision 1.21  2004/07/11 20:36:17  apsop
# HISTORY: Allow for BAT rate files to not have GTIs.
# HISTORY:
# HISTORY: Revision 1.20  2004/06/18 16:13:08  apsop
# HISTORY: Use bat2fits6.
# HISTORY:
# HISTORY: Revision 1.19  2004/05/06 20:02:33  dah
# HISTORY: Add version number back into the header comments.
# HISTORY:
# HISTORY: Revision 1.18  2004/04/28 13:47:35  dah
# HISTORY: Make one method for extracting hk, and put it in Swift2FTIS superclass.
# HISTORY:
# HISTORY: Revision 1.17  2004/04/16 20:21:18  dah
# HISTORY: Begin using embedded history records
# HISTORY:
#
# VERSION: 0.0
#
#
##############################################################################

use Subs::Swift2FITS;
use Util::PseudoFtool;
use Util::GTIlist;

@ISA = ('Subs::Swift2FITS');
use strict;

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

    $self->{DESCRIPTION}="Decoding BAT Telemetry";

    return $self;
}

##################
# METHODS:
##################

sub body {
    my $self=shift;

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


    #######################################
    # get a time-sorted list of LDP files
    #######################################
    my $ldps = Util::LDPlist->new($filename->get("telemetry", "bat", 
                                                 "ldp", "*") )
                            ->sort();

    ##################################################
    # append that to the rest of the telemetry files 
    ##################################################
    my $list = Util::FileList->new($filename->get("telemetry", "bat", 
                                                  "head[23]", "*"),
                                   $ldps->files() );

    #############################
    # check if we got anything
    #############################
    if($list->count() == 0) {
        $log->entry("No BAT CCSDS files to process");
        return;
    } else {
        ########################
        # log what we are doing
        ########################
        $log->entry("Running bat2fits on the following files: ".
                    join " ", $list->files() );
    }


    ###################################
    # set up and run BAT2FITS
    ###################################
    my $bin = $procpar->read("bat2fits");
    my $bat2fits = Util::PseudoFtool->new("$bin/bat2fits6");

    my $mission = $jobpar->read("mission");
    my $filename_base = $mission . $jobpar->read("sequence");

    $bat2fits->params({fitsname  => $filename_base,
		       override  => $mission eq 'sw' ? 'no' : 'yes',
		       ldpspan   => 'no',
                       align     => $filename->fetch_cal('alignment'),
                       path      => "./",
                       telemetry => $list->as_param(),
                       clobber   => "yes",
                       chatter   => 4                  });

    $bat2fits->run();

    if( $mission ne 'sw' ){
      foreach my $file ( glob 'sw???????????ms[bf]*' ){
	my $newfile = $file;
	$newfile =~ s/^sw/${mission}/;
        rename $file, $newfile;
      }
    }
    

    $self->sort_evts();

    #################################
    # Fix up names of event hk files
    #################################
    foreach my $hkevfile ($filename->get('hk', 'bat', 'ev??to', '*')){
      my ($inst, $mode, $index) = $filename->parse($hkevfile, 'hk');
      $mode =~ s/^(.*)to$/$1sp/;
      rename $hkevfile, $filename->get('hk', 'bat', $mode, $index);
    }
    
    ############################################
    # merge the event files and the rate files
    ############################################
    $self->merge_rates();

    $self->combine_masktag();

    ##############################################
    # extract HK files using the unpacket tool
    ##############################################
    $self->hk_extract('bat');
    $self->hk_combine('bat');

} # end of body method


##############################################################################
# Sort and duplicate remove short event file
##############################################################################
sub sort_evts {
  my $self=shift;
  my $filename=$self->filename();

  foreach my $file ($filename->get('unfiltered', 'bat', 'evsh*', '*')) {
    my $fits = new Util::FITSfile($file, 'EVENTS');
    $fits->cols('TIME', 'DET_ID')->sort('shell', 'unique');
  }

  my $hd_file = $filename->get('hk', 'bat', 'hd', '*');
  if($hd_file){
    my $fits = new Util::FITSfile($hd_file, 'LDP_HEADER');
    $fits->cols('TIME')->sort('shell', 'unique');    
  }

}


###############################################################################
# merge the rate files
###############################################################################
sub merge_rates{
    my $self=shift;

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

    $log->entry("Merging rate files");

    my @modes = ('rt1s', 'rtms', 'rtmc', 'rtqd', 'mt' );
    my $mode;
    foreach $mode (@modes) {
      $log->entry("Mode = $mode");
      my $type = 'lightcurve';
      $type = 'rawlc' if $mode eq 'mt';

      #####################################################################
      # Get of list of targets.  Needed for mt lightcurves.
      #####################################################################
      my %targ_list;
      my $targ;
      foreach my $file ($filename->get($type, 'b', $mode.'*', '*')){
	my $tot_mode = ( $filename->parse($file, $type) )[1];
	if( $tot_mode =~ /(\d{8})/ ){
	  $targ_list{$1} = 1;
	}else{
	  $targ_list{''} = 1;
	}
      }
      
      foreach $targ (keys %targ_list){
        ###############################################################
        # get a list of all the raw rate files for this mode and index
        ###############################################################
        my $list = Util::FITSlist->new($filename->get($type, 'b', 
                                                      "${mode}??${targ}", '*') );
        $list->extension(1);

        #########################################
        # make sure there are some files and log
        # what we are doing
        #########################################
        if($list->count() == 0 ) {
            $log->entry("No raw rate files for mode $mode");
            next;
        } else {
            $log->entry("Merging ". join ' ', $list->files() );
        }

        ################################
        # merge the files
        ################################
        my $rate;
        if( $mode eq 'mt' ){
	  $rate = ($list->files())[0];
          $rate =~ s/${mode}..${targ}/${mode}${targ}/;
        }else{
          $rate = $filename->get('rawlc', 'b', "${mode}${targ}", 0);
        }
        my $merged = $list->merge($rate);

        if($merged ne $rate ) {
            ##########################################
            # there was only one file, so we rename it
            ##########################################
            rename $merged, $rate;
        } else {
            ###########################################
            # there were multiple raw files, 
            # first we need to sort and unique by time
            ###########################################
            $log->entry("Sorting $merged");
            Util::FITSfile->new($merged, 1)
                          ->sort("shell", "unique");

            ######################################
            # ...and now merge the GTIs
            ######################################
	    if( $list->extension('GTI') == $list->files() ){
	      $self->merge_gtis($list, $rate);
	    }

	    unlink $list->files();
        }
      }
    } # end of loop over modes
   
} # end of merge_rates method


###########################################################################
# Merge the GTI extensions in a list of FITS files. The merged GTIs are
# appended to the given target file.
###########################################################################
sub merge_gtis {
    my $self=shift;
    my $list = shift;
    my $target = shift;

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


    ##################################
    # now we have to "or" the GTIs
    ##################################
    $log->entry("Merging GTIs for $target");

    Util::GTIlist->new($list->files())
                 ->extension("GTI")
                 ->merge_and_append_to($target);

} # end of merge_gtis method


##############################################################################
# Put in the mask tagged weights as extensions to the mask tagged lightcurves
#############################################################################
sub combine_masktag {
    my $self=shift;

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

    my @mwfiles = $filename->get('maskwt', 'b', '', '*');
    foreach my $mtfile ($filename->get('mtlc', 'b', '', '*')){
      my ($inst, $mode, $index) = $filename->parse($mtfile, 'rawlc');
      if( $mode =~ /(\d{8})/ ){
	my $targ = $1;
	my $mwfile = (grep /mw${targ}/, @mwfiles)[0];
	if($mwfile){
	  Util::Ftool->new('fappend')
	             ->params({infile => $mwfile.'[1]',
			       outfile => $mtfile})
		     ->run();
	  unlink $mwfile;
	}
      }
    }
}


1;