package Subs::BATBurst;
##############################################################################
#
# DESCRIPTION: This subroutine does calibration of BAT event data.
# DESCRIPTION: It runs bateconvert to do energy scale calibrations,
# DESCRIPTION: and then runs batmaskwtevt to calculate mask weights for
# DESCRIPTION: each event which correspond to the burst position.
#
# DESCRIPTION: Port of Craig Markwardt's BAT::maskwt module to SDC.
#
#
# HISTORY: $Log: BATBurst.pm,v $
# HISTORY: Revision 1.60 2014/02/27 09:22:47 apsop
# HISTORY: Don't use uat attitude file, at request of BAT Team/C.Markwardt.
# HISTORY:
# HISTORY: Revision 1.59 2013/08/19 20:29:24 apsop
# HISTORY: Only log fetch_from_repository result if fetch succeeded, to
# HISTORY: avoid a Perl message about using an undefined variable. (If
# HISTORY: unsuccessful, fetch_from_repository already logs an error.)
# HISTORY:
# HISTORY: Revision 1.58 2013/05/30 07:54:54 apsop
# HISTORY: Log fetches from BAT repository
# HISTORY:
# HISTORY: Revision 1.57 2012/01/12 06:52:03 apsop
# HISTORY: Changes going to proc3.15.03
# HISTORY:
# HISTORY: 2011-08-31 JRG as apsop: In slew_only(), skip rest & issue error
# HISTORY: if @rows is empty (currently still returns 1 if so, but should it?)
# HISTORY:
# HISTORY: Revision 1.56 2011/01/20 17:12:44 apsop
# HISTORY: Removed older version of a subroutine and some commented code
# HISTORY:
# HISTORY: Revision 1.54 2009/04/13 14:08:03 apsop
# HISTORY: added check if bevbu.gti file exist
# HISTORY:
# HISTORY: Revision 1.53 2009/03/12 14:43:49 apsop
# HISTORY: GTI_PRE changed in 1 extension bevbu.gti file
# HISTORY:
# HISTORY: Revision 1.52 2008/12/10 14:00:30 apsop
# HISTORY: Add gtinam parameter to extractor calls.
# HISTORY:
# HISTORY: Revision 1.51 2008/05/15 19:29:14 apsop
# HISTORY: Move creation of GTI files to a SwiftSub method. Check for existence of pointing GTIs before using.
# HISTORY:
# HISTORY: Revision 1.50 2007/10/23 14:21:55 apsop
# HISTORY: Bug fix for interval algorithm.
# HISTORY:
# HISTORY: Revision 1.49 2007/10/22 20:38:12 apsop
# HISTORY: Craig;s algorithm for determining pre, slew, and post intervals.
# HISTORY:
# HISTORY: Revision 1.47 2007/10/11 18:16:41 apsop
# HISTORY: Change slew_start criteria to handle non-slew bursts.
# HISTORY:
# HISTORY: Revision 1.46 2007/10/09 16:52:34 apsop
# HISTORY: Refine algorithm for determining slew time intervals for a burst.
# HISTORY:
# HISTORY: Revision 1.45 2007/10/08 21:06:36 apsop
# HISTORY: Use proper targ-pointing GTI instead of on-target GTI for time intervals.
# HISTORY:
# HISTORY: Revision 1.44 2007/10/05 14:19:45 apsop
# HISTORY: Change of algorhythm for determining the pre and post slew intervals of a burst. Now use on-target GTIs.
# HISTORY:
# HISTORY: Revision 1.43 2007/09/12 18:07:08 apsop
# HISTORY: Throw error if cant find gain/offset file, instead of crashing bateconvert task.
# HISTORY:
# HISTORY: Revision 1.42 2007/03/15 21:34:10 apsop
# HISTORY: For slew-only the data, allow for possible absence of slew file as well as pointing file.
# HISTORY:
# HISTORY: Revision 1.41 2007/02/12 02:14:14 apsop
# HISTORY: Another bug fix for db file editing.
# HISTORY:
# HISTORY: Revision 1.40 2007/02/10 21:46:17 apsop
# HISTORY: Fix bug in editing of badb.hk file.
# HISTORY:
# HISTORY: Revision 1.39 2007/02/08 14:27:59 apsop
# HISTORY: Allow for possibility that slew-only data can actually contain some pointing data.
# HISTORY:
# HISTORY: Revision 1.38 2007/01/31 20:23:40 apsop
# HISTORY: Identify bat event data taken during slews and tag as such.
# HISTORY:
# HISTORY: Revision 1.37 2006/09/10 20:07:22 apsop
# HISTORY: Add new distfile parameter for build 19.
# HISTORY:
# HISTORY: Revision 1.36 2006/04/27 16:27:02 apsop
# HISTORY: Set parameter pcodethresh to 0.05 in batmaskwtevt task.
# HISTORY:
# HISTORY: Revision 1.35 2006/01/16 17:50:21 apsop
# HISTORY: Dont split or update TSTART of dph files that dont need it.
# HISTORY:
# HISTORY: Revision 1.34 2005/12/19 16:10:32 apsop
# HISTORY: Add timing keywords to evaux file - should really be done in bat tool.
# HISTORY:
# HISTORY: Revision 1.33 2005/11/16 01:03:20 apsop
# HISTORY: Only make evaux file for slew-pointing event data.
# HISTORY:
# HISTORY: Revision 1.32 2005/11/08 17:01:20 apsop
# HISTORY: Change qualcal call for new filename.
# HISTORY:
# HISTORY: Revision 1.31 2005/07/05 14:56:16 apsop
# HISTORY: Caught SDC up to date with BAT pipeline with exception of BAT
# HISTORY: position refinement.
# HISTORY:
# HISTORY: Revision 1.30 2005/06/01 16:03:07 apsop
# HISTORY: Change the burst gti file type from gti to burstgti.Subs/BATIntervals.pm
# HISTORY:
# HISTORY: Revision 1.29 2005/04/19 15:40:18 apsop
# HISTORY: Change calmode parameter to INDEF.
# HISTORY:
# HISTORY: Revision 1.28 2005/04/06 15:40:31 apsop
# HISTORY: Change to using CALDB for cal parameters.
# HISTORY:
# HISTORY: Revision 1.27 2005/03/25 22:53:53 apsop
# HISTORY: Change pointing gti extname form STDGTI to GTI
# HISTORY:
# HISTORY: Revision 1.26 2005/03/07 20:22:31 apsop
# HISTORY: Comment out filtering of TIME<1000. This now done in StartEndTimes.
# HISTORY:
# HISTORY: Revision 1.25 2005/02/09 23:39:01 apsop
# HISTORY: Added message identifiers.
# HISTORY:
# HISTORY: Revision 1.24 2005/02/08 18:26:52 apsop
# HISTORY: Fix bateconvert call to work with build 11. Remove events with time of less than 1000.
# HISTORY:
# HISTORY: Revision 1.23 2004/12/07 17:34:57 apsop
# HISTORY: Change log message to error message when bat files cannot be split. Downstream error messages that result have been changed to log messages.
# HISTORY:
# HISTORY: Revision 1.22 2004/12/05 23:26:54 apsop
# HISTORY: Split event list after calibration
# HISTORY:
# HISTORY: Revision 1.21 2004/11/19 21:46:48 apsop
# HISTORY: New version of xrt2fits.
# HISTORY:
# HISTORY: Revision 1.20 2004/11/10 18:01:06 apsop
# HISTORY: Replace SimpleFITS call for getting TSTART with FITSfile call.
# HISTORY:
# HISTORY: Revision 1.19 2004/11/09 22:03:14 apsop
# HISTORY: Reverted mode of short events GTI.
# HISTORY:
# HISTORY: Revision 1.18 2004/11/08 18:38:40 apsop
# HISTORY: Updated with Craig's BAT::maskwt code.
# HISTORY:
# HISTORY: Revision 1.17 2004/10/25 14:47:27 apsop
# HISTORY: Fix bugs in splitting of DPH files.
# HISTORY:
# HISTORY: Revision 1.16 2004/10/24 20:00:55 apsop
# HISTORY: Rework of split_events method. Now make pemanent GTI file.
# HISTORY:
# HISTORY: Revision 1.15 2004/08/30 13:23:06 apsop
# HISTORY: Fix up parameters for batmaskwtevt, including using bat_z and origin_z
# HISTORY:
# HISTORY: Revision 1.14 2004/08/16 15:23:09 apsop
# HISTORY: Turn on writing of HISTORY keywords.
# HISTORY:
# HISTORY: Revision 1.13 2004/08/13 14:28:31 apsop
# HISTORY: Test for case where slew times cannot be determined.
# HISTORY:
# HISTORY: Revision 1.12 2004/06/29 14:21:13 apsop
# HISTORY: Add residfile and pulserfile to bateconvert call.
# HISTORY:
# HISTORY: Revision 1.11 2004/06/11 19:49:48 apsop
# HISTORY: Handle case where there is no pointing time.
# HISTORY:
# HISTORY: Revision 1.10 2004/05/06 20:02:33 dah
# HISTORY: Add version number back into the header comments.
# HISTORY:
# HISTORY: Revision 1.9 2004/04/16 20:21:18 dah
# HISTORY: Begin using embedded history records
# HISTORY:
#
# VERSION: $Revision: 1.60 $
#
##############################################################################
use Subs::Sub;
@ISA = ("Subs::Sub");
use strict;
use Util::SwiftTags;
use Util::GTIfile;
sub new {
my $proto=shift;
my $self=$proto->SUPER::new();
$self->{DESCRIPTION}="BAT Burst Processing";
return $self;
}
##################
# METHODS:
##################
sub body {
my $self=shift;
my $log =$self->log();
my $filename=$self->filename();
my $procpar =$self->procpar();
my $jobpar =$self->jobpar();
################################################
# Events file times of less than 1000 are bogus
################################################
my @event_files = $filename->get('unfiltered', 'bat', 'ev??to', '*');
# my $copy = Util::HEAdas->new('ftcopy');
# my $filter = '[EVENTS][TIME > 1000]';
foreach my $unf (@event_files){
my ($inst, $mode, $index) = $filename->parse($unf, 'unfiltered');
my $new_name = $filename->get('unfiltered', 'bat', substr($mode,0,4).'sp', $index);
# $copy->params({infile => $unf . $filter,
# outfile => $new_name})
# ->run();
# unlink $unf;
rename $unf, $new_name;
}
$self->calibrate_events;
unless( $self->slew_only() ){
$self->mask_weight_events;
}
###################################################
# Split up the bat event list based on time period
###################################################
$self->split_events();
my $gti_pre = $filename->get('burstgti', 'bat', '', 0);
if(-e $gti_pre ){
Util::HEAdas->new('fthedit')
->params({infile => $gti_pre.'[1]',
keyword =>'EXTNAME',
value =>'GTI_PRE ',
comment =>' / name of this binary table extension'})
->run();
}
} # end of body method
sub determine_trigger_time
{
my $self = shift;
my $log =$self->log();
my $filename=$self->filename();
my $procpar =$self->procpar();
my $jobpar =$self->jobpar();
my $root = $filename->sequence_specific();
# this could be done once and stored in $jobpar
my $ack = Util::BATCave::get_tdrss_ack($self);
if (not $ack) {
$log->error([ 1, BAT_NO_CENTROID ],
'No burst ack message to provide trigger time.');
return;
}
my $batack = Util::FITSfile->new($ack, 0);
my $trigtime = $batack->keyword('TRIGTIME');
$log->entry("BAT trigger time based on $ack is $trigtime .");
return $trigtime;
}
################################################################
# Split up the bat event lists and dph's based on time period
###############################################################
sub split_events{
my $self=shift;
my $log =$self->log();
my $filename=$self->filename();
my $procpar =$self->procpar();
my $jobpar =$self->jobpar();
my @dph_files = $filename->get('rawdph', 'bat', 'svto', '*');
my @event_files = $filename->get('unfiltered', 'bat', 'evshsp', '*');
my $trigtime = $self->determine_trigger_time;
if (not $trigtime) {
$log->error([ 1, BAT_NO_CENTROID ],
'No trigger time so will not split BAT event files.');
foreach my $raw (@dph_files){
my ($inst, $mode, $index) = $filename->parse($raw, 'dph');
my $new_name = $filename->get('rawdph', 'bat', 'svpb'.substr($mode,4), $index);
rename $raw, $new_name;
}
return;
}
####################################
# Do the splitting of events lists
#####################################
$log->entry("Split BAT event lists based on end of slew time.");
# TODO: want to rename this from po => as, but po set in Attitude.pm
my $gtipath = $filename->get('gti', 's', 'po', 0);
my (@start, @stop, @ot_start, @ot_stop);
if (-f $gtipath) {
my $spo_gti = Util::FITSfile->new($gtipath, 'GTI');
@start = $spo_gti->cols('START')->table();
@stop = $spo_gti->cols('STOP')->table();
my $ot_path = $filename->get('gti', 's', 'tp', 0);
if( -f $ot_path){
my $sot_gti = Util::FITSfile->new($ot_path, 'GTI');
@ot_start = $sot_gti->cols('START')->table();
@ot_stop = $sot_gti->cols('STOP')->table();
}
}else {
$log->error([ 1, BAT_NO_GTIS ],
'No spo GTI so will not split BAT event files.');
}
#######################################################################
# Slewing senarios which are handled:
#
# point ----------- -------------
# | | | |
# slew ----- ---------- ---------
# *
# trigger
#
#
#
# point ----- -------------
# | | | |
# slew ----------- ---------- ---------
# *
# trigger
#
#
#
# point ------------------------------------------------
# |
# slew -----
# *
# trigger
#
###########################################################################
my ($slew_stop, $slew_start, $preslew_start, $preslew_stop, $postslew_start, $postslew_stop);
#
# Definitions of terms:
#
# * "Pre-slew" - the pointing which contains the trigger (or in
# rare cases where the trigger is during the settling interval,
# the pointing that just follows the trigger).
#
# * "Pre-burst" - the portion of the pre-slew pointing which
# contains no burst emission. (this is selected in BATImages.pm
# as the GTI intersection of the pre-slew interval with
# GTI_BKG1). Note that this could be empty if the burst emission
# occupies all of the pointing.
#
# * "Slew" - the slew which follows the trigger. Note the slew
# may not be a slew to the burst position.
#
# * "After-slew" - the pointing which follows the "slew"
# interval. Note the following pointing may not always be
# pointed at the burst.
#
# Defaults:
# * If no good pointing is available during the trigger:
# pre-slew = all of the event data (and no slew or after-slew data)
# * If no "after-slew" pointing is available:
# pre-slew = normal
# slew = all data after pre-slew
#
if(@start){
my ($i, $ifound);
# Find the pointing that precedes the trigger time
foreach $i (reverse(0 .. $#start)) {
if ($trigtime >= $start[$i]) {
# Double check that the trigger comes *during* the pointing.
# This may fail if the trigger comes during the settling period.
# In that case, advance to the next pointing.
$ifound = $i;
if ($trigtime >= $stop[$i]) { $ifound = $i + 1; }
last;
}
}
if (defined($ifound)) {
# We found a pointing interval that brackets the trigger!
# Extract start/stop times based on this interval and the
# following one if it exists.
$preslew_start = $start[$ifound];
$preslew_stop = $stop[$ifound];
$slew_start = $stop[$ifound];
$slew_stop = $start[$ifound+1]; # May be undefined
$postslew_start= $start[$ifound+1]; # May be undefined
$postslew_stop = $stop[$ifound+1]; # May be undefined
}
}
# Fill in the defaults
$preslew_start = 0 unless $preslew_start;
$preslew_stop = 1.0E12 unless $preslew_stop;
$slew_start = 1.1E12 unless $slew_start;
$slew_stop = 1.1E12 unless $slew_stop;
$postslew_start = 1.2E12 unless $postslew_start;
$postslew_stop = 1.2E12 unless $postslew_stop;
$log->entry("Slew start/stop based on ACS settled flags: $slew_start / $slew_stop .");
$log->entry("Pre-slew start/stop: $preslew_start / $preslew_stop .");
$log->entry("Post-slew start/stop: $postslew_start / $postslew_stop .");
##############################
# Set up to split event files
##############################
my $gti_pre = $filename->get('burstgti', 'bat', '', 0);
my $gti_post = 'bat_post_gti.tmp';
my $gti_slew = 'bat_slew_gti.tmp';
Util::GTIfile->new($gti_pre, $preslew_start, $preslew_stop);
Util::GTIfile->new($gti_slew, $slew_start, $slew_stop);
Util::GTIfile->new($gti_post, $postslew_start, $postslew_stop);
my $extractor = Util::Extractor->new();
foreach my $unf (@event_files) {
$log->entry("Splitting file $unf.");
my ($inst, $mode, $index) = $filename->parse($unf, 'unfiltered');
my $submode = substr($mode, 0, 4);
$extractor->instrument('bat', 'EVENT')
->infiles($unf);
my $post_file = $filename->get('unfiltered', 'b', $submode.'as', $index);
$extractor->gti($gti_post)
->outfile($post_file, 'event');
$extractor->params({gtinam => 'GTI'})
->run();
unlink $post_file
unless Util::FITSfile->new($post_file, 'EVENTS')->nrows();
my $pre_file = $filename->get('unfiltered', 'b', $submode.'ps', $index);
$extractor->gti($gti_pre)
->outfile($pre_file, 'event');
$extractor->params({gtinam => 'GTI'})
->run();
unlink $pre_file
unless Util::FITSfile->new($pre_file, 'EVENTS')->nrows();
my $slew_file = $filename->get('unfiltered', 'b', $submode.'sl', $index);
$extractor->gti($gti_slew)
->outfile($slew_file, 'event');
$extractor->params({gtinam => 'GTI'})
->run();
unlink $slew_file
unless Util::FITSfile->new($slew_file, 'EVENTS')->nrows();
}
##############################################
# Combine gtis together into gti product file
##############################################
my $fappend = Util::Ftool->new('fappend')
->params({outfile => $gti_pre});
$fappend->params({infile => "$gti_slew\[1\]\[col EXTNAME='GTI_SLEW'\]"})
->run();
$fappend->params({infile => "$gti_post\[1\]\[col EXTNAME='GTI_POST'\]"})
->run();
unlink $gti_post, $gti_slew;
############################
# Set up to split DPH files
############################
my $gti_merged = 'gti_merged.tmp';
$fappend->params({infile => $gti_merged.'[1]'});
my $mgtime = Util::Ftool->new('mgtime')
->params({merge => 'AND'});
my $fdelhdu = Util::Ftool->new('fdelhdu')
->params({confirm => 'no',
proceed => 'yes'});
$log->entry('Do splitting of DPH files based on slew times.');
unlink $gti_post;
$gti_pre = 'bat_pre_gti.tmp';
Util::GTIfile->new($gti_pre, 0, $trigtime);
Util::GTIfile->new($gti_post, $trigtime, 1.E12);
#################################################################
# Do the splitting of dphs
#################################################################
foreach my $unf (@dph_files) {
$log->entry("Splitting file $unf.");
my ($inst, $mode, $index) = $filename->parse($unf, 'dph');
my $gaoff = substr($mode, 4);
##########################
# Get the after burst part
##########################
my $post_file = $filename->get('rawdph', 'b', 'svab'.$gaoff, $index);
my $post_start = Util::FITSfile->new($unf)->keyword('TSTART');
if($post_start >= $trigtime){
rename $unf, $post_file;
next;
}
Util::Ftool->new('fcopy')
->params({infile => "$unf\[BAT_DPH\][gtifilter(\'${gti_post}\[1\]\')]",
outfile => $post_file})
->run();
my $post_fits = Util::FITSfile->new($post_file, 'BAT_DPH');
if( $post_fits->nrows() ){
$post_fits->keyword('TSTART', $trigtime);
$fdelhdu->params({infile => $post_file.'[GTI]'})
->run();
$mgtime->params({ingtis => "$unf\[GTI\], $gti_post\[1\]",
outgti => $gti_merged})
->run();
$fappend->params({outfile => $post_file})
->run();
$post_fits->ext('STDGTI');
$post_fits->keyword('TSTART', $trigtime);
$post_fits->keyword('EXTNAME', 'GTI');
unlink $gti_merged;
}else{
unlink $post_file;
}
########################
# Get the pre-burst part
########################
my $pre_file = $filename->get('rawdph', 'b', 'svpb'.$gaoff, $index);
Util::Ftool->new('fcopy')
->params({infile => "$unf\[BAT_DPH\][gtifilter(\'${gti_pre}\[1\]\')]",
outfile => $pre_file})
->run();
my $pre_fits = Util::FITSfile->new($pre_file, 'BAT_DPH');
if( $pre_fits->nrows() ){
$pre_fits->keyword('TSTOP', $trigtime);
$fdelhdu->params({infile => $pre_file.'[GTI]'})
->run();
$mgtime->params({ingtis => "$unf\[GTI\], $gti_pre\[1\]",
outgti => $gti_merged})
->run();
$fappend->params({outfile => $pre_file})
->run();
$pre_fits->ext('STDGTI');
$pre_fits->keyword('TSTOP', $trigtime);
$pre_fits->keyword('EXTNAME', 'GTI');
unlink $gti_merged;
}else{
unlink $pre_file;
}
unlink $unf;
}
unlink $gti_pre, $gti_post;
}
sub calibrate_events
{
my $self = shift;
my $log = $self->log;
my $filename = $self->filename;
my $procpar = $self->procpar;
my $jobpar = $self->jobpar;
###############################################
# make sure we have some event data to work on
###############################################
my @all_event_files = $filename->get('unfiltered', 'bat', 'evsh??', '*');
unless(@all_event_files) {
$log->entry("No BAT event mode data");
return;
}
############################################################
# fill calibrated energy column
# here we need to add a system to handle the calibration
# files. (shared across sequences)
###########################################################
$log->entry("Running bateconvert on all event files");
my %common = (
residfile => 'CALDB',
pulserfile => 'CALDB',
fltpulserfile => 'CALDB',
outfile => 'NONE',
clobber => 'yes',
chatter => 3,
history => 'yes',
calmode => 'INDEF',
zeroit => 'no',
scaled_energy => 'yes'
);
my $tool = Util::HEAdas->new('bateconvert')
->params(\%common);
foreach my $unf (@all_event_files) {
$log->entry("Calibrating $unf");
###############################################
# get the gain offset calibration file to use
# for this event file
###############################################
my $unf_fits = Util::FITSfile->new($unf, 0);
my $time = $unf_fits->keyword('TSTART');
unless($time) {
$log->error(2, "unable to calibrate $unf, missing TSTART");
next;
}
$log->entry("BATBurst.pm requesting from repository " .
"bgaoff: $time");
my $gainoff = $filename->fetch_from_repository('bgaoff',
'b', '', $time);
unless($gainoff) {
$log->error(2, "unable to obtain gain/offset file for time $time");
next;
}
$log->entry("fetched from repository " .
"bgaoff: \$gainoff=$gainoff");
$log->entry("Using gain/offset cal file $gainoff " .
"based on a start time of $time .");
###########################
# now run the calibration
###########################
$tool->params({
calfile => $gainoff,
infile => $unf,
})
->run;
} # end of bateconvert loop over files
}
sub mask_weight_events
{
my $self = shift;
my $log = $self->log;
my $filename = $self->filename;
my $procpar = $self->procpar;
my $jobpar = $self->jobpar;
$log->entry('Computing BAT mask weighting for the desired source');
my @events = $filename->get('unfiltered', 'bat', 'evsh??', '*');
if (not @events) {
$log->entry('no BAT (short) event files to process');
return;
}
my $attitude = $filename->get('attcorr', 'p');
if (-e $attitude) {
$log->entry("Got pat attitude file $attitude");
} else {
$log->error(1, "$attitude pat attitude file does not exist, trying sat file");
$attitude = $filename->get('attitude', 's');
if (-e $attitude) {
$log->entry("Got sat attitude file $attitude");
} else {
$log->error(1, "Unable to find attitude file, bailing");
return;
}
}
my %common = (
# attitude => $filename->get('attitude', 's'),
attitude => $attitude,
ra => $jobpar->read('burst_ra'),
dec => $jobpar->read('burst_dec'),
bat_z => $jobpar->read('bat_z'),
aperture => 'CALDB',
detmask => $filename->get('qualcal', 'bat', ''),
coord_type => 'sky',
rebalance => 'yes',
corrections => 'flatfield,ndets,pcode,maskwt',
teldef => 'CALDB',
distfile => 'CALDB',
origin_z => $jobpar->read('bat_origin_z'),
# clobber => 'yes',
pcodethresh => 0.05
);
my $tool = Util::HEAdas->new('batmaskwtevt')
->params(\%common);
my $trigtime = $self->determine_trigger_time;
my $stats=Util::HEAdas->new("ftstat")
->verbose(0);
my $idx = 0;
my @evAux = ();
foreach my $file (@events) {
# set TRIGTIME in EVENT extension
if ($trigtime) {
Util::FITSfile->new($file, 'EVENTS')
->keyword(TRIGTIME => $trigtime,
'[s] MET Trigger Time')
;
}
my $evaux = 'NONE';
$evaux = $filename->get('eventaux', 'b', '', 0) if $file=~/bevshsp/;
if($evaux ne 'NONE'){
$evaux = $evaux.'_'.$idx;
if(-e $evaux){
unlink $evaux;
}
push @evAux, $evaux;
$idx++;
}
# print "Running batmaskwtevt using infile=$file, auxfile=$evaux, trigtime=$trigtime\n";
$tool->params({
infile => $file,
auxfile => $evaux,
})
->run;
if($evaux ne 'NONE'){
my $auxfits = Util::FITSfile->new($evaux, 1);
$auxfits->specs('[col TIME]');
$stats->params({infile => $auxfits->fullname(),
centroid => 'no'})
->run();
my $parfile = $stats->parfile();
my $start = Util::Date->new( $parfile->read('min') );
my $stop = Util::Date->new( $parfile->read('max') );
$auxfits->ext(0);
$auxfits->specs('');
$auxfits->begin_many_keywords();
$auxfits->keyword('TSTART', $start->seconds());
$auxfits->keyword('TSTOP', $stop->seconds());
$auxfits->keyword('DATE-OBS', $start->date() .'T'.$start->time() );
$auxfits->keyword('DATE-END', $stop->date() .'T'.$stop->time() );
$auxfits->end_many_keywords();
}
}
if($idx > 1){
my $Nevaux = $evAux[0];
$Nevaux =~ s/\_0$//;
$log->entry("Merging files $evAux[1] and $evAux[0] into $Nevaux");
Util::HEAdas->new('ftmerge')
->params({infile => "$evAux[1], $evAux[0]",
outfile => $Nevaux,
clobber => 'yes'})
->run();
foreach(my $i=2; $i<$idx; $i++){
my $outfile = $Nevaux.'_merged';
$log->entry("Merging files $evAux[$i] and $Nevaux into $outfile");
Util::HEAdas->new('ftmerge')
->params({infile => "$evAux[$i], $Nevaux",
outfile => $outfile,
clobber => 'yes'})
->run();
rename $outfile, $Nevaux;
}
foreach my $f (@evAux){
if(-e $f){
unlink $f;
}
}
my $auxfits = Util::FITSfile->new($Nevaux, 1);
$auxfits->specs('[col TIME]');
$stats->params({infile => $auxfits->fullname(),
centroid => 'no'})
->run();
my $parfile = $stats->parfile();
my $start = Util::Date->new( $parfile->read('min') );
my $stop = Util::Date->new( $parfile->read('max') );
$auxfits->ext(0);
$auxfits->specs('');
$auxfits->begin_many_keywords();
$auxfits->keyword('TSTART', $start->seconds());
$auxfits->keyword('TSTOP', $stop->seconds());
$auxfits->keyword('DATE-OBS', $start->date() .'T'.$start->time() );
$auxfits->keyword('DATE-END', $stop->date() .'T'.$stop->time() );
$auxfits->end_many_keywords();
$auxfits->ext(1);
$auxfits->specs('');
$auxfits->begin_many_keywords();
$auxfits->keyword('TSTART', $start->seconds());
$auxfits->keyword('TSTOP', $stop->seconds());
$auxfits->keyword('DATE-OBS', $start->date() .'T'.$start->time() );
$auxfits->keyword('DATE-END', $stop->date() .'T'.$stop->time() );
$auxfits->end_many_keywords();
} elsif ($idx == 1){
my $Nevaux = $evAux[0];
$Nevaux =~ s/\_0$//;
rename $evAux[0], $Nevaux;
}
}
sub slew_only {
my $self = shift;
my $log = $self->log;
my $filename = $self->filename;
my $procpar = $self->procpar;
my $jobpar = $self->jobpar;
##########################################################
# if automatic target, should be more than just slew data
##########################################################
return 0 if( Util::BATCave::get_tdrss_ack($self) );
my @events = $filename->get('unfiltered', 'bat', 'evsh??', '*');
my $gtipointing = $filename->get('gti', 's', 'po', 0);
my $gtinotpoint = $filename->get('gti', 's', 'np', 0);
if( @events == 1 ){
my $file = $events[0];
my $pofile = $filename->get('unfiltered', 'bat', 'evshpo', 0);
my $slfile = $filename->get('unfiltered', 'bat', 'evshsl', 0);
my $extractor = Util::Extractor->new();
$extractor->instrument('bat', 'EVENT')
->infiles($file);
if( -f $gtipointing ){
$extractor->gti($gtipointing)
->outfile($pofile, 'event');
$extractor->params({gtinam => 'GTI'})
->run();
}
if( -f $gtinotpoint ){
$extractor->gti($gtinotpoint)
->outfile($slfile, 'event');
$extractor->params({gtinam => 'GTI'})
->run();
}
unlink $file;
my $pofits = Util::FITSfile->new($pofile);
my $slfits = Util::FITSfile->new($slfile);
my $non_slew = $pofits->keyword("NAXIS2");
my $is_slew = $slfits->keyword("NAXIS2");
if($non_slew){
$pofits->keyword('OBS_MODE', 'POINTING');
}else{
unlink $pofile;
}
if($is_slew){
$slfits->keyword('OBS_MODE', 'SLEW');
}else{
unlink $slfile;
}
##################################
# Update the entries in the db file
##################################
my $hkfile = $filename->get('hk', 'proc', 'badb', 0);
my $hkfits = Util::FITSfile->new($hkfile)->cols('filename');
my @names = $hkfits->table();
my $row = 1;
my @rows;
foreach my $name (@names){
push @rows, $row if $file eq $name;
$row++;
}
$row = shift @rows;
if (@rows) {
Util::HEAdas->new('ftdelrow')
->params({infile => $hkfile,
outfile => 'none',
rows => join(',',@rows),
confirm => 'YES'})
->run();
my $edit = Util::HEAdas->new('ftedit')
->params({infile => $hkfile,
row => $row,
history => 'yes'});
if($is_slew){
$edit->params({column => 'filename',
value => $slfile})
->run();
$edit->params({column => 'pointing_mode',
value => 'SLEW'})
->run();
$edit->params({column => 'start_time',
value => $slfits->keyword('TSTART')})
->run();
$edit->params({column => 'exp_start',
value => $slfits->keyword('TSTART')})
->run();
$edit->params({column => 'stop_time',
value => $slfits->keyword('TSTOP')})
->run();
$edit->params({column => 'exp_stop',
value => $slfits->keyword('TSTOP')})
->run();
}
#################################################################
# If there is both slew and non-slew data, need to add an hk row
#################################################################
my $hktemp = "badb.tmp";
my $hktemp1 = "badb1.tmp";
if( $is_slew && $non_slew ){
Util::HEAdas->new('ftcopy')
->params({outfile => $hktemp,
infile => $hkfile . "[1][#row==$row]"})
->run();
$edit->params({infile => $hktemp,
row => 1});
}
################################################
# Add a db entry for pointing file if it exists
################################################
if( $non_slew ){
$pofits->keyword('OBS_MODE', 'POINTING');
$edit->params({column => 'filename',
value => $pofile})
->run();
$edit->params({column => 'pointing_mode',
value => 'POINTING'})
->run();
$edit->params({column => 'start_time',
value => $pofits->keyword('TSTART')})
->run();
$edit->params({column => 'exp_start',
value => $pofits->keyword('TSTART')})
->run();
$edit->params({column => 'stop_time',
value => $pofits->keyword('TSTOP')})
->run();
$edit->params({column => 'exp_stop',
value => $pofits->keyword('TSTOP')})
->run();
}
if( $is_slew && $non_slew ){
Util::HEAdas->new('ftmerge')
->params({infile => "$hkfile,$hktemp",
outfile => $hktemp1})
->run();
rename $hktemp1, $hkfile;
unlink $hktemp;
}
} else {
$log->error(1, "BATBurst,slew_only: rows is empty, file=$file");
}
}
return 1;
}
1;