Subs::XRT2FITS (version $)


package Subs::XRT2FITS;
##############################################################################
#
# DESCRIPTION: This subroutine runs the XRT tools delivered in build 1
#
# HISTORY: $Log: XRT2FITS.pm,v $
# HISTORY: Revision 1.11  2014/02/28 10:55:52  apsop
# HISTORY: Add ATTFLAG keyword =100 to ATTITUDE extensions of XRT TDRSS
# HISTORY: *msxim_rw.fits and *msxpc_uf.evt files (requested by XRT Team).
# HISTORY:
# HISTORY: Revision 1.10  2012/01/12 06:52:03  apsop
# HISTORY: Changes going to proc3.15.03
# HISTORY:
# HISTORY: 2011-11-16 Jeff Guerber as apsop:
# HISTORY:   Set TIMEPIXR keyword to 0.5 in *xwt*uf files, per XRT team
# HISTORY:   (expected to propagate to *xwt*ufre and *xwt*cl files too).
# HISTORY:
# HISTORY: Revision 1.9  2008/08/12 17:06:53  apsop
# HISTORY: Remove out-of-spatial-range events from pc slew event lists.
# HISTORY:
# HISTORY: Revision 1.8  2006/03/06 15:05:21  apsop
# HISTORY: Add value for new align parameter in xrt2fits.
# HISTORY:
# HISTORY: Revision 1.7  2005/08/31 16:25:02  apsop
# HISTORY: Delete empty window timing files.
# HISTORY:
# HISTORY: Revision 1.6  2004/12/10 02:19:38  apsop
# HISTORY: Changes to support mission pneumonic other than sw.
# HISTORY:
# HISTORY: Revision 1.5  2004/12/05 23:23:17  apsop
# HISTORY: Add override option to bat2fits.
# HISTORY:
# HISTORY: Revision 1.4  2004/05/06 20:02:34  dah
# HISTORY: Add version number back into the header comments.
# HISTORY:
# HISTORY: Revision 1.3  2004/04/16 20:21:18  dah
# HISTORY: Begin using embedded history records
# HISTORY:
#
# VERSION: $Revision: 1.11 $
#
##############################################################################


use Subs::SwiftSub;
use Util::PseudoFtool;
use Util::LDPlist;

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

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

    $self->{DESCRIPTION}="Decoding XRT 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", "xrt",
                                                 "ldp", "*") )
                            ->sort();

    ##################################################
    # append that to the rest of the telemetry files
    ##################################################
    my $list = Util::FileList->new($filename->get("telemetry", "xrt",
                                                  "head[23]", "*"),
                                   $ldps->files() );
    if($list->count() == 0) {
        ######################
        # no XRT telemetry
        ######################
        $log->entry("No XRT CCSDS files to process");
        return;
    } else {
        ########################
        # log what we are doing
        ########################
        $log->entry("Running xrt2fits on the following files: ".
                    join " ", $list->files() );
    }

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

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

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

    $xrt2fits->run();

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

    ########################################################
    # For all the WT event files,
    # 1) Remove empty ones
    # 2) Set TIMEPIXR keyword to 0.5 in the EVENTS extension
    ########################################################
    my $setTimepixr = Util::HEAdas->new( 'fthedit' )
	->params({
	    keyword   => 'TIMEPIXR',
	    operation => 'add',
	    value     => 0.5,
	    comment   => "Bin time beginning=0 middle=0.5 end=1"
	    });

    foreach my $file ( $filename->get('unfiltered', 'x', 'wt*', '*') ){
	my $fitsfile = Util::FITSfile->new($file, 'EVENTS');
	unless($fitsfile->nrows()){
	    $log->error(1, "XRT file $file is empty. Deleting.");
	    unlink $file;
	} else {
	    $setTimepixr->params({ infile => $file . "[EVENTS]" })
		->run();
	    $log->entry("Set TIMEPIXR=0.5 in " . $file . "[EVENTS]");
	}
    }

    ##############################################################
    # Remove out of spatial range events from pc slew event lists
    ##############################################################
    my $filter_expr = '[EVENTS][RAWX >= TLMIN5 && RAWX <= TLMAX5 && RAWY >= TLMIN6 && RAWY <= TLMAX6]';
    my $out_file =  "events.tmp";
    my $copy = Util::HEAdas->new('ftcopy')
                           ->params({outfile => $out_file});
    foreach my $file ( $filename->get('unfiltered', 'x', 'pc*sl', '*') ){
      my $fitsfile = Util::FITSfile->new($file, 'EVENTS');
      my $init_rows = $fitsfile->nrows();

      $log->entry("Removing events out of RAW[XY] range from ". $file ." .");
      $copy->params({infile => $file . $filter_expr})
           ->run();
      next if $copy->had_error();

      rename $out_file, $file;
      my $filtered_rows = $fitsfile->nrows();
      if( $filtered_rows < $init_rows ){
        $log->error(1, $init_rows-$filtered_rows ." events removed from file ". $file ." .");
      }
    }
    unlink $out_file;

    ########################################################################
    # Add ATTFLAG keyword to the ATTITUDE extensions of the XRT TDRSS
    # *msxim_rw* and *msxpc_uf* files.  Requested by the XRT team (Matteo
    # Perri).  Matteo says this should be 100: "This is because these files
    # store in a specific extension (named 'ATTITUDE') the attitude
    # information to be used for their processing ... and this attitude is
    # the one promptly downlinked after a burst detection, therefore it is
    # not the UVOT and/or jump corrected ones but the original SAT one."
    # (Note: the sat file hasn't been created yet.)
    ########################################################################

    foreach my $file ( $filename->get('tdrawimage', 'x', 'im', '*'),
		       $filename->get('tdunfilter', 'x', 'pc', '*') ) {
	my $ext = 'ATTITUDE';
	my $attflag = '100';    # value should have

	my $fitsfile = Util::FITSfile->new($file, $ext);
	my $existattflag = $fitsfile->keyword('ATTFLAG');

	if ( defined($existattflag) ) {
	    # Note if there already was an ATTFLAG and if it didn't
	    # agree with what we expected.  But leave it as is.
	    if ($existattflag ne $attflag) {
		$log->error(1, "Expected ATTFLAG=${attflag}, " .
			    "found ${existattflag}, in ${file}[${ext}]" );
	    } else {
		$log->entry("Found ATTFLAG=${existattflag} in ${file}[${ext}]");
	    }
	} else {
	    # No existing ATTFLAG, so write the expected value
	    $fitsfile->keyword('ATTFLAG', "'$attflag'",
			       "Attitude: 100=spacecraft (from xrt tdrss)");
	    $log->entry("Set ATTFLAG=$attflag in ${file}[${ext}]");
	}
    }

} # end of body method