package Subs::XrtEvents;
##############################################################################
#
# DESCRIPTION: This subroutine runs the XRT tools delivered in build 1
#
# HISTORY:
# HISTORY: $Log: XrtEvents.pm,v $
# HISTORY: Revision 1.41 2014/08/14 10:37:10 apsop
# HISTORY: Skip xrtpcbias for PC Slew and Settling events.
# HISTORY:
# HISTORY: Revision 1.40 2014/02/27 10:01:40 apsop
# HISTORY: Don't use uat attitude file, at request of XRT Team.
# HISTORY:
# HISTORY: Revision 1.39 2013/05/30 07:47:33 apsop
# HISTORY: Log when using srcdetx/y=300 in xrtpcbias/xrtpccorr
# HISTORY:
# HISTORY: Revision 1.38 2013/05/24 02:42:53 apsop
# HISTORY: Add srcdetx=300, srcdety=300 to xrtpcbias call when
# HISTORY: spacecraft is in SLEW or SETTLING mode.
# HISTORY:
# HISTORY: Revision 1.37 2011/01/20 18:52:43 apsop
# HISTORY: Added code to get ra and dec for source GRB in the same way as done
# HISTORY: in other place.
# HISTORY: Added code to use UVOT attitude file if available
# HISTORY:
# HISTORY: Revision 1.36 2007/09/11 17:56:32 apsop
# HISTORY: Add xrtpcbias task, and update parameters for build 21.1.
# HISTORY:
# HISTORY: Revision 1.35 2007/01/31 16:46:33 apsop
# HISTORY: Change to xrtwtcorr parameters.
# HISTORY:
# HISTORY: Revision 1.34 2006/10/06 18:15:14 apsop
# HISTORY: Update keywords in header file after running xrthkproc.
# HISTORY:
# HISTORY: Revision 1.33 2006/09/25 13:30:57 apsop
# HISTORY: Remove code for xrthkproc workaround.
# HISTORY:
# HISTORY: Revision 1.32 2006/09/20 20:35:32 apsop
# HISTORY: Temporary fix, which removes manual mode zero rows from the xrt header file before processing.
# HISTORY:
# HISTORY: Revision 1.31 2006/07/03 19:33:20 apsop
# HISTORY: Delete reconstructed event files if they are empty after filtering.
# HISTORY:
# HISTORY: Revision 1.30 2006/05/17 19:07:55 apsop
# HISTORY: Fix up creation of uf ufre event files for wt mode.
# HISTORY:
# HISTORY: Revision 1.29 2006/05/10 15:16:31 apsop
# HISTORY: Change transition from unfiltered to reconstructed event list in a window timing mode.
# HISTORY:
# HISTORY: Revision 1.28 2006/04/26 20:44:21 apsop
# HISTORY: Change ordering of when xrtflagpix is called. Trap case where
# HISTORY: EVTPHA column does not exist in lt and wt files.
# HISTORY:
# HISTORY: Revision 1.27 2005/11/08 20:08:37 apsop
# HISTORY: Add in xrtwtcorr task, and update a couple of parameters.
# HISTORY:
# HISTORY: Revision 1.25 2005/10/04 13:35:27 apsop
# HISTORY: Pass XRT housekeeping trailer packets to xrttimetag.
# HISTORY:
# HISTORY: Revision 1.24 2005/05/26 13:00:06 apsop
# HISTORY: Param change for xrtpdcorr due to new version of xrt2fits.
# HISTORY:
# HISTORY: Revision 1.23 2005/05/02 13:49:34 apsop
# HISTORY: Fix bug in name of column that is deleted from reconstructed files (EVTPHA).
# HISTORY:
# HISTORY: Revision 1.22 2005/04/29 20:33:04 apsop
# HISTORY: Bug fixes for previous version in use of pifile.tmp.
# HISTORY:
# HISTORY: Revision 1.21 2005/04/29 15:52:00 apsop
# HISTORY: Several parameter changes. Remove EVPHA columns after processing.
# HISTORY:
# HISTORY: Revision 1.20 2005/04/19 15:10:10 apsop
# HISTORY: Changes for build14 tasks, many now use header file. Stop if not header file.
# HISTORY:
# HISTORY: Revision 1.19 2005/04/06 15:46:19 apsop
# HISTORY: Change to using CALDB for cal parameters.
# HISTORY:
# HISTORY: Revision 1.18 2005/02/25 20:29:40 apsop
# HISTORY: Explicitly set method parameter in xrtpdcorr to SG.
# HISTORY:
# HISTORY: Revision 1.17 2004/11/16 15:32:09 apsop
# HISTORY: Changes to fix handling of window timing events.
# HISTORY:
# HISTORY: Revision 1.16 2004/11/09 23:54:56 apsop
# HISTORY: Rework order of tasks to make proper split between level 1 and level1a.
# HISTORY:
# HISTORY: Revision 1.15 2004/11/02 21:25:16 apsop
# HISTORY: Rearrange calling sequence and production of level 1a files.
# HISTORY:
# HISTORY: Revision 1.14 2004/08/30 13:18:37 apsop
# HISTORY: Changes for build 9. NONE does not work, rearrangement for bias info.
# HISTORY:
# HISTORY: Revision 1.13 2004/07/23 16:04:13 apsop
# HISTORY: Fix stupid bug in _fetching_ attitude file. Should be _getting_.
# HISTORY:
# HISTORY: Revision 1.12 2004/07/19 16:04:55 apsop
# HISTORY: Fix bug in using fetch_cal() instead of fetch() to get attitude file.
# HISTORY:
# HISTORY: Revision 1.11 2004/07/11 20:43:51 apsop
# HISTORY: Turn chatter down on timetag and hkproc in order to reduce output to reasonable level.
# HISTORY:
# HISTORY: Revision 1.10 2004/06/29 14:35:33 apsop
# HISTORY: Substantial changes to support build 8.
# HISTORY:
# HISTORY: Revision 1.9 2004/05/06 20:02:34 dah
# HISTORY: Add version number back into the header comments.
# HISTORY:
# HISTORY: Revision 1.8 2004/05/04 16:31:47 dah
# HISTORY: Test for presence of header file before processing it.
# HISTORY:
# HISTORY: Revision 1.7 2004/04/28 13:56:43 dah
# HISTORY: Save reconstructed event lists in seperate files. Change order in which xrtpdcorr
# HISTORY: is called. Fix bug in calling xrthkproc.
# HISTORY:
# HISTORY: Revision 1.6 2004/04/16 20:21:18 dah
# HISTORY: Begin using embedded history records
# HISTORY:
#
# VERSION: $Revision: 1.41 $
#
#
##############################################################################
use Subs::Sub;
use Util::SwiftTags;
@ISA = ("Subs::Sub");
use strict;
sub new {
my $proto=shift;
my $self=$proto->SUPER::new();
$self->{DESCRIPTION}="Running XRT tasks for event list 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();
my ($srcra, $srcdec) = $self->Subs::XrtProducts::GetRaDec();
if (!defined $srcra or !defined $srcdec) {
$log->error(1, "Unable to XrtEvents since coordinates are not fully defined");
return;
}
####################################
# Get lists of event types
####################################
my @phot = $filename->get('unfiltered', 'x', 'pc*', '*');
my @diod = ($filename->get('unfiltered', 'x', 'lr*', '*'),
$filename->get('unfiltered', 'x', 'pu*', '*'));
my @wind = $filename->get('unfiltered', 'x', 'wt*', '*');
my (@wind1a, @diod1a);
############################################
# get attitude file, for xrt only pat or sat
############################################
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, exiting");
return;
}
}
my $filter = $filename->get('filter', 's');
#############################
# xrthkproc
#############################
my $head = $filename->get('hk', 'x', 'hd', '*');
my $trailer = $filename->get('hk', 'x', 'tr', '*');
unless(-f $head){
$log->error([ 1, XRT_NO_HDFILE ], "Unable to find xrt header file $head, cannot continue.");
return;
}
unless(-f $trailer){
$log->error([ 1, XRT_NO_HDFILE ], "Unable to find XRT trailer file $trailer, cannot continue.");
return;
}
#############################################
# First we have to fix up the hk header file
#############################################
my $xrthkproc = Util::HEAdas->new('xrthkproc');
$log->entry("Running ".$xrthkproc->name()." on $head");
$xrthkproc->params({hdfile => $head,
outfile => 'hkout.tmp',
attfile => $attitude,
srcdetx => 300,
srcdety => 300,
srcra => $srcra,
srcdec => $srcdec,
ranom => $jobpar->read('ra'),
decnom => $jobpar->read('dec'),
teldef => 'CALDB',
chatter => 3,
clobber => 'yes',
history => 'yes'})
->run();
unless( $xrthkproc->had_error() ){
unlink $head;
rename 'hkout.tmp', $head;
}
#######################
# update time keywords
#######################
my $head_fits = Util::FITSfile->new($head);
my $start = $head_fits->keyword('TSTART');
my $stop = $head_fits->keyword('TSTOP');
my $start_date = Util::Date->new($start);
my $stop_date = Util::Date->new($stop);
$head_fits->keyword('DATE-OBS', $start_date->date().'T'.$start_date->time() );
$head_fits->keyword('DATE-END', $stop_date->date().'T'.$stop_date->time() );
$head_fits->ext(0);
$head_fits->keyword('DATE-OBS', $start_date->date().'T'.$start_date->time() );
$head_fits->keyword('DATE-END', $stop_date->date().'T'.$stop_date->time() );
$head_fits->keyword('TSTART', $start);
$head_fits->keyword('TSTOP', $stop);
#############
# xrttimetag
#############
my $timetag = Util::HEAdas->new('xrttimetag');
my $timefile = 'timefile.tmp';
$timetag->params({outfile => $timefile,
hdfile => $head,
trfile => $trailer,
usehkkey => 'no',
attfile => $attitude,
usesrcdet => 'no',
srcra => $srcra,
srcdec => $srcdec,
ranom => $jobpar->read('ra'),
decnom => $jobpar->read('dec'),
teldef => 'CALDB',
colfile => 'CALDB',
chatter => 3,
clobber => 'yes',
history => 'yes'});
my $unf;
foreach $unf (@wind){
$log->entry("Running ".$timetag->name()." on $unf");
$timetag->params({infile => $unf})
->run();
unless($timetag->had_error()) {
unlink $unf;
rename $timefile, $unf;
}
}
foreach $unf (@diod){
$log->entry("Running ".$timetag->name()." on $unf");
$timetag->params({infile => $unf})
->run();
if ($timetag->had_error()) {
unlink($timefile);
}
else {
unlink $unf;
rename $timefile, $unf;
#############################
# Filter using generated GTI
#############################
my $difile = $filename->corresponding('unfiltered', 'reconst', $unf);
my $fits = Util::FITSfile->new($unf, 'EVENTS', '[gtifilter()]');
$fits->copy($difile);
my $new_fits = Util::FITSfile->new($difile, 'EVENTS');
if( $new_fits->keyword('NAXIS2') > 0 ){
push @diod1a, $difile;
}else{
$log->entry("File $difile is empty. Deleting.");
unlink $difile;
}
}
}
#############
# xrtpcbias
# Run on each Photon Counting-mode event file (except SLEW and SETTLING
# modes). If successful, replace the original file with the
# bias-corrected one.
#############
my $pcbias = Util::HEAdas->new('xrtpcbias');
$pcbias->params({outfile => 'biasfile.tmp',
teldef => 'CALDB',
attfile => $attitude,
mkffile => $filter,
hdfile => $head,
thrfile => 'CALDB',
srcra => $srcra,
srcdec => $srcdec,
chatter => 3,
clobber => 'yes',
history => 'yes'});
foreach $unf (@phot){
$log->entry("Running ".$pcbias->name()." on $unf");
# When the spacecraft is slewing or settling and XRT is in Photon
# Counting mode, xrtpccorr (which xrtpcbias calls) cannot calculate
# the detector source position, failing with "The .mkf file is not
# appropriate for the ... events file", and causing xrtpcbias to
# fail with an "E2: Unable to correct PHAS values" error.
# Specifying srcdetx=300 and srcdety=300 in this situation should
# fix this, per Matteo Perri, 2013-04-24.
# However this didn't always work, so Matteo has recommended
# instead just skipping xrtpcbias in this case, since the
# associated event files are not used for scientific purposes
# anyway (email 2014-05-31).
#
my $unf_fits = Util::FITSfile->new($unf, 'EVENTS');
my $obs_mode = $unf_fits->keyword('OBS_MODE'); # NB:keyword() trims ws
$log->entry("obs mode = $obs_mode");
if ( defined($obs_mode) &&
(($obs_mode eq 'SLEW') || ($obs_mode eq 'SETTLING')) ) {
$log->entry("skipping xrtpcbias for $obs_mode mode");
next;
# [Previous code that ran with srcdetx=srcdety=300]
# $pcbias->params({ srcdetx => 300,
# srcdety => 300 });
# $log->entry("using srcdetx=srcdety=300 in xrtpccorr " .
# "for SLEW/SETTLING mode");
}
$pcbias->params({infile => $unf})
->run();
unless( $pcbias->had_error() ){
unlink $unf;
rename 'biasfile.tmp', $unf;
}
}
#############
# xrtflagpix
#############
my $flagpix = Util::HEAdas->new('xrtflagpix');
$flagpix->params({outfile => 'flagfile.tmp',
hdfile => $head,
bpfile => 'CALDB',
bptable => 'CALDB',
srcfile => 'CALDB',
thrfile => 'CALDB',
phas1thr => 80,
maxtemp => 0,
userbpfile => 'NONE',
outbpfile => 'NONE',
overstatus => 'yes',
chatter => 3,
clobber => 'yes',
history => 'yes'});
foreach $unf (@phot){
$log->entry("Running ".$flagpix->name()." on $unf");
$flagpix->params({infile => $unf})
->run();
unless( $flagpix->had_error() ){
unlink $unf;
rename 'flagfile.tmp', $unf;
}
}
foreach $unf (@wind){
$log->entry("Running ".$flagpix->name()." on $unf");
$flagpix->params({infile => $unf})
->run();
if( $flagpix->had_error() ){
unlink 'flagfile.tmp';
}else{
unlink $unf;
rename 'flagfile.tmp', $unf;
#############################
# Filter using generated GTI
#############################
my $wtfile = $filename->corresponding('unfiltered', 'reconst', $unf);
my $fits = Util::FITSfile->new($unf, 'EVENTS', '[gtifilter()]');
$fits->copy($wtfile);
my $new_fits = Util::FITSfile->new($wtfile, 'EVENTS');
if( $new_fits->keyword('NAXIS2') > 0 ){
push @wind1a, $wtfile;
}else{
$log->entry("File $wtfile is empty. Deleting.");
unlink $wtfile;
}
}
}
###############################
# xrtwtcorr
###############################
my $wtcorr = Util::HEAdas->new('xrtwtcorr');
$wtcorr->params({outfile => 'wtfile.tmp',
hdfile => $head,
trfile => $trailer,
colfile => 'CALDB',
npixels => 20,
biasth => 200,
thrfile => 'CALDB',
history => 'yes',
nevents => 20,
biasdiff => 2,
nframe => 20,
biasmode => 'M20P',
clobber => 'yes',
chatter => 5});
foreach $unf (@wind1a) {
$log->entry("Running ".$wtcorr->name()." on $unf");
$wtcorr->params({infile => $unf})
->run();
unless( $wtcorr->had_error() ){
unlink $unf;
rename 'wtfile.tmp', $unf;
}
}
###############################
# xrtpdcorr
###############################
my $pdcorr = Util::HEAdas->new('xrtpdcorr');
$pdcorr->params({outfile => 'pdfile.tmp',
biasfile => 'CALDB',
thrfile => 'CALDB',
hdfile => $head,
method => 'MN',
bias => -1,
biasth => 300,
biasdiff => 4095,
history => 'yes',
clobber => 'yes',
chatter => 5});
foreach $unf (@diod1a) {
$log->entry("Running ".$pdcorr->name()." on $unf");
$pdcorr->params({infile => $unf})
->run();
unless( $pdcorr->had_error() ){
unlink $unf;
rename 'pdfile.tmp', $unf;
}
}
#############################
# xrtevtrec
#############################
my $evtrec = Util::HEAdas->new('xrtevtrec');
$evtrec->params({outfile => 'recfile.tmp',
hdfile => $head,
gradefile => 'CALDB',
thrfile => 'CALDB',
addcol => 'no',
delnull => 'yes',
event => 80,
split => 80,
flagneigh => 'yes',
chatter => 5,
clobber => 'yes',
history => 'yes'});
foreach $unf (@diod1a, @wind1a){
$log->entry("Running ".$evtrec->name()." on $unf");
$evtrec->params({infile => $unf})
->run();
unless( $evtrec->had_error() ){
unlink $unf;
rename 'recfile.tmp', $unf;
}
}
###############################
# xrtpcgrade
###############################
my $ph2br = Util::HEAdas->new('xrtpcgrade');
$ph2br->params({outfile => 'gradefile.tmp',
hdfile => $head,
split => 40,
gradefile => 'CALDB',
thrfile => 'CALDB',
ascagrade => 'no',
history => 'yes',
clobber => 'yes',
chatter => 5 });
foreach $unf (@phot) {
$log->entry("Running ".$ph2br->name()." on $unf");
$ph2br->params({infile => $unf})
->run();
unless( $ph2br->had_error() ){
unlink $unf;
rename 'gradefile.tmp', $unf;
}
}
###############################
# xrthotpix
###############################
my $hotpix = Util::HEAdas->new('xrthotpix');
$hotpix->params({outfile => 'pixfile.tmp',
outbpfile => 'NONE',
phamax => 4095,
iterate => 'yes',
gradeiterate => 'yes',
overstatus => 'yes',
cellsize => 3,
hotneigh => 'no',
history => 'yes',
clobber => 'yes',
chatter => 5});
foreach $unf (@phot) {
$log->entry("Running ".$hotpix->name()." on $unf");
$hotpix->params({infile => $unf})
->run();
unless( $hotpix->had_error() ){
unlink $unf;
rename 'pixfile.tmp', $unf;
}
}
####################################
# set up xrtcalcpi
####################################
my $pha2pi = Util::HEAdas->new('xrtcalcpi');
$pha2pi->params({outfile => 'pifile.tmp',
hdfile => $head,
gainfile => 'CALDB',
gainnom => -99.0, # uses default from cal file
offset => 0.0,
randomflag => 'yes',
seed => -1457,
chatter => 2,
clobber => 'yes',
history => 'yes' });
foreach $unf (@phot) {
my ($inst, $mode, $index) = $filename->parse($unf, 'unfiltered');
$log->entry("Running ".$pha2pi->name()." on $unf");
$pha2pi->params({infile => $unf})
->run();
unless( $pha2pi->had_error() ){
unlink $unf;
rename 'pifile.tmp', $unf;
}
}
foreach $unf (@wind1a, @diod1a) {
my ($inst, $mode, $index) = $filename->parse($unf, 'reconst');
$log->entry("Running ".$pha2pi->name()." on $unf");
$pha2pi->params({infile => $unf})
->run();
unless( $pha2pi->had_error() ){
unlink $unf;
my $copy = Util::HEAdas->new('ftcopy')
->params({infile => 'pifile.tmp[EVENTS][col -EVTPHA]',
outfile => $unf});
$copy->seriousness(1);
$copy->run();
if( $copy->had_error() ){
rename 'pifile.tmp', $unf;
}else{
unlink 'pifile.tmp';
}
}
}
} # end of body method
1;