package Subs::UVOTDB;
##############################################################################
#
# DESCRIPTION:
#
# HISTORY:
# HISTORY: $Log: UVOTDB.pm,v $
# HISTORY: Revision 1.9 2005/12/01 20:56:29 apsop
# HISTORY: Fix mapping of extension names which was deleting values. Is this a perl bug?
# HISTORY:
# HISTORY: Revision 1.8 2005/11/08 19:43:57 apsop
# HISTORY: <Previous comment bogus> Add null value for binning column. Add extname column. Handle missing file name.
# HISTORY:
# HISTORY: Revision 1.7 2005/11/08 19:22:28 apsop
# HISTORY: Populate the TIMELIST and DATALIST hashes. Used to be an SWCheckInput.
# HISTORY:
# HISTORY: Revision 1.6 2005/08/30 14:05:31 apsop
# HISTORY: Add new image_loss column. Rename integration_time to exposure. Limit precision on floating values.
# HISTORY:
# HISTORY: Revision 1.5 2005/06/01 19:55:49 apsop
# HISTORY: Add binning column to db fits file.
# HISTORY:
# HISTORY: Revision 1.4 2005/06/01 13:59:46 apsop
# HISTORY: Use event or image mode window sizes for window column as appropriate. More robust method for obtaining pointing_mode.
# HISTORY:
# HISTORY: Revision 1.3 2004/12/22 18:17:06 apsop
# HISTORY: Bug fixes to acquistion of UVOT db values.
# HISTORY:
# HISTORY: Revision 1.2 2004/12/14 02:45:37 apsop
# HISTORY: Test for existence of exposure catalog before making db file.
# HISTORY:
# HISTORY: Revision 1.1 2004/12/10 02:12:44 apsop
# HISTORY: Class for making uvot database files.
# HISTORY:
#
# VERSION: 0.0
#
#
##############################################################################
use Subs::Sub;
@ISA = ("Subs::Sub");
use strict;
use Astro::FITS::CFITSIO qw(:constants);
use Util::HEAdas;
use Util::Date;
use Util::FITStable;
use Subs::UvotNames;
sub new {
my $proto=shift;
my $self=$proto->SUPER::new();
$self->{DESCRIPTION}="Sort and organize UVOT data";
return $self;
}
##################
# METHODS:
##################
sub body
{
my $self=shift;
my $log = $self->log();
my $filename = $self->filename();
my $procpar = $self->procpar();
my $jobpar = $self->jobpar();
# set up the database columns
my @db = (
# alert keys
{ name => 'name',
type => '80A',
# $jobpar->read('object')
},
{ name => 'orig_target_id',
type => '1J',
null => -1,
# $jobpar->read('target')
},
{ name => 'target_id',
type => '1J',
null => -1,
# substr(0, 8, $jobpar->read('sequence'))
},
{ name => 'ra',
type => '1D',
unit => 'degree',
disp => 'F10.5',
# $jobpar->read('ra')
},
{ name => 'dec',
type => '1D',
unit => 'degree',
disp => 'F10.5',
# $jobpar->read('dec')
},
{ name => 'roll_angle',
type => '1D',
unit => 'degree',
disp => 'F10.5',
# $jobpar->read('roll')
},
{ name => 'start_time',
type => '24A',
# ecat column ESTART
},
{ name => 'stop_time',
type => '24A',
# ecat column ESTOP
},
{ name => 'orig_obs_segment',
type => '1J',
disp => 'I3',
null => -1,
# $jobpar->read('obs')
},
{ name => 'obs_segment',
type => '1J',
disp => 'I3',
null => -1,
},
{ name => 'orig_obsid',
type => '11A',
},
{ name => 'obsid',
type => '11A',
},
{ name => 'exposure',
type => '1E',
unit => 's',
},
{ name => 'count',
type => '1J',
null => -1,
},
{ name => 'image_loss',
type => '1E'
},
{ name => 'window_size',
type => '80A',
},
{ name => 'binning',
type => '1J',
null => -1,
},
{ name => 'filter',
type => '80A',
key => 'FILTER', # to string
},
{ name => 'operation_mode',
type => '80A',
# value IMAGE|EVENT|IMAGE&EVENT
},
{ name => 'pointing_mode',
type => '80A',
# SLEW|SETTLING|...
},
{ name => 'filename',
type => '80A',
# either IFILEREF or EFILEREF
},
{ name => 'extname',
type => '80A',
# either IMENAME
},
);
my $db = Util::FITStable->new(\@db,
log => $log,
which => 'uvot',
);
my $path = $filename->get('hk', 'uvot', 'ct');
unless( $path && -f $path ) {
$log->entry("Unable to locate uvot exposure catalog");
return;
}
my $uecat = Util::SimpleFITS->open("<$path");
my $status = $uecat->status;
if (not $uecat or $status) {
$log->error(2, "unable to open uvot exposure catalog [$status]");
return;
}
$uecat->move('EXPCATALOG');
if ($uecat->status) {
$log->error(2, 'unable to move to EXPCATALOG extension');
return;
}
################################################
# Compile the data needed for the UVOT db file
################################################
my $rows;
$uecat->handle->get_num_rows($rows, $status);
my @indef = ('INDEF') x $rows;
# observation
$db->set(name => [ ("'".$jobpar->read('object')."'") x $rows ]);
$db->set(orig_target_id => [ ($jobpar->read('target')) x $rows ]);
$db->set(target_id => [ (substr $jobpar->read('sequence'), 0, 8) x $rows ]);
####################################################################
# Early observations (before PPSTs) had multiple pointings, so set
# pointing to indef
####################################################################
if( $jobpar->read('tstart') > 124383600 ){
$db->set(ra => [ (sprintf '%.5f', $jobpar->read('ra')) x $rows ]);
$db->set(dec => [ (sprintf '%.5f', $jobpar->read('dec')) x $rows ]);
$db->set(roll_angle => [ (sprintf '%.5f', $jobpar->read('roll')) x $rows ]);
}else{
$db->set(ra => \@indef );
$db->set(dec => \@indef );
$db->set(roll_angle => \@indef );
}
# per exposure data
my @estart;
my @estop;
my @segment;
my @enet;
my @windowDWX;
my @windowDWY;
my @windowEVX;
my @windowEVY;
my @binning;
my @filterID;
my @efile;
my @ifile;
my @imename;
my @mode;
my @counts;
my @gevents;
my @gimage;
$status = $uecat
->readcol('ESTART' => TDOUBLE, [ ], \@estart)
->readcol('ESTOP' => TDOUBLE, [ ], \@estop)
->readcol('SEGMENT' => TLONG, [ ], \@segment)
->readcol('ENET' => TDOUBLE, [ ], \@enet)
->readcol('DW_XSIZ ' => TLONG, [ ], \@windowDWX)
->readcol('DW_YSIZ' => TLONG, [ ], \@windowDWY)
->readcol('EV_XSIZ ' => TLONG, [ ], \@windowEVX)
->readcol('EV_YSIZ' => TLONG, [ ], \@windowEVY)
->readcol('BINLVL' => TINT, [ ], \@binning)
->readcol('FILTERID' => TSTRING, [ ], \@filterID)
->readcol('EFILEREF' => TSTRING, [ ], \@efile)
->readcol('IFILEREF' => TSTRING, [ ], \@ifile)
->readcol('IMENAME' => TSTRING, [ ], \@imename)
->readcol('MODEID' => TINT, [ ], \@mode)
->readcol('NEVENTS' => TLONG, [ ], \@counts)
->readcol('GEVENTS' => TLONG, [ ], \@gevents)
->readcol('GIMAGE' => TLONG, [ ], \@gimage)
->status;
if ($status) {
$log->error(2, 'unable to read EXPCATALOG data');
return;
}
my @start = map { $db->timeString($_) } @estart;
my @stop = map { $db->timeString($_) } @estop;
$db->set(start_time => \@start);
$db->set(stop_time => \@stop);
$db->set(orig_obs_segment => [ ($jobpar->read('obs')) x $rows ]);
$db->set(obs_segment => [ (substr $jobpar->read('sequence'), 8, 3) x $rows ]);
$db->set(orig_obsid => [ ($jobpar->read('target') . $jobpar->read('obs')) x $rows ]);
$db->set(obsid => [ ($jobpar->read('sequence')) x $rows ]);
$db->set(exposure => [map {$_=sprintf('%.5f',$_) unless /INDEF/} @enet]);
my @mode_name = map { $Subs::UvotNames::modeNames->[$_] } @mode;
$db->set(operation_mode => \@mode_name);
my @window;
my @gcount;
for (my $i = 0; $i < $rows; ++$i) {
if( $mode_name[$i] =~ /Event/ ){
push(@gcount, $gevents[$i]);
push(@window, "'$windowEVX[$i] x $windowEVY[$i]'");
}else{
push(@gcount, $gimage[$i]);
push(@window, "'$windowDWX[$i] x $windowDWY[$i]'");
}
}
$db->set(window_size => \@window);
$db->set(binning => \@binning);
$db->set(filter => \@filterID);
$db->set(count => \@gcount);
my @filename;
my @pointing_mode;
my @image_loss = ('INDEF') x $rows;
for (my $i = 0; $i < $rows; ++$i) {
if( $efile[$i] ne 'NONE' ){
push(@filename, $efile[$i]);
push(@pointing_mode, $efile[$i] =~ /po_uf.evt/ ? 'POINTING' : 'SLEW');
}elsif( $ifile[$i] ne 'NONE' ){
my $ifits = Util::FITSfile->new($ifile[$i], $imename[$i]);
push(@pointing_mode, $ifits->keyword('OBS_MODE'));
push(@filename, $ifile[$i]);
#######################################################
# Determine the percentage of NULL pixels in the image
#######################################################
my $stats=Util::HEAdas->new("ftstat")
->params({infile => $ifits->fullname(),
centroid => 'no'})
->verbose(0)
->run();
my $parfile = $stats->parfile();
my $nulls = $parfile->read('null');
if( defined $nulls ){
$image_loss[$i] = 0;
if( $nulls ){
$image_loss[$i] = $parfile->read('good') / $nulls;
$image_loss[$i] = 1/(1+$image_loss[$i]);
}
}
}else{
push(@pointing_mode, 'UNKNOWN');
push(@filename, 'UNDEF');
}
}
$db->set(filename => \@filename);
@imename = map {$_= $_ eq 'NONE' ? 'UNDEF' : $_} @imename;
$db->set(extname => \@imename);
$db->set(pointing_mode => \@pointing_mode);
$db->set(image_loss => \@image_loss);
my $outfile = $filename->get('uvdb', 'proc', '', 0);
$db->write($outfile);
} # end of body method