# This module mereges the LCs of EPIC cameras and RGSs
package LCMerge;
use strict;
use English;
use Carp;
use List::Util qw(reduce);
use List::MoreUtils qw(uniq);
use vars
qw(@ISA $VERSION $name $author $date $version @instList $numberOfStreams);
@ISA = qw(Module);
use ModuleResources;
# Declare identity, version, author, date, etc.
$name = __PACKAGE__;
$VERSION = '1.01';
$version = $VERSION;
$author = 'Jose Vicente Perea';
$date = '2018-05-16';
#
# ChangeLog
# =========
#
# Version 1.01 - 2018-05-16 (JVP)
# ------------
#
# + Light Curves merge per Energy Band
# Final products ( Plot (pdf) + FITS file ) to product/
# Band label: 0 if Timing mode, 8 otherwise
#
# Version 1.00 - 2018-04-24 (JVP)
# ------------
#
# + Light Curves merge per Energy Band
# Merged by 'srcTimeSeriesEnergyBands.py'
#
# Version 0.08 - 2017-06-06 (JVP)
# ------------
#
# + LCMerge plot from plotTimeSeries.py to final product/
# and LCMerge plot from "lcurve" to intermediate/
#
# Version 0.07 - 2017-03-24 (JVP)
# ------------
#
# + Merging logic modified: RGS TS product can be:
# PROPOSAL + NO EPIC ID : (RGS + PN Timing) OR (Only RGS => No plot)
# PROPOSAL + EPIC ID : (RGS + PN Timing + MOS's) OR (RGS + PN + MOS's)
# EPIC ID : (RGS + PN Timing + MOS's) OR (RGS + PN + MOS's)
#
# + plotTimeSeries.py activated again. Products to intermediate/
# + Log file cleaned up
#
# Version 0.06 - 2017-03-09 (JVP)
# ------------
#
# + No PDF plot if only RGS Timeseries are present
#
# Version 0.05 - 2017-01-23 (JVP)
# ------------
#
# + RGS PROPOSAL TS is merged with PN Timing TS, regardless of the EPIC identification in the RGS source list
# Small correction to avoid problems when RGS1 or RGS2 TS is missing
#
# Version 0.04 - 2017-01-19 (JVP)
# ------------
#
# + Light Curve merging by new Python task : plotTimeSeries.py
# Not included yet. Commented code
#
# Version 0.03 - 2016-12-20 (JVP)
# ------------
#
# + Light curve for the rest of EPIC sources only if 'EPIC summary source list' exists
#
# Version 0.02 - 2016-11-22 (JVP)
# ------------
#
# + 3 blocks included:
# - Timing PN TS + RGS TS with no EPIC identification
# - EPIC TS + RGS with EPIC identification
# - Rest of EPIC TS's
#
# Version 0.01 - 2016-09-19 (JVP)
# ------------
#
# + Initial version
#
# Declare list of instruments this module is interested in
@instList = qw(rgs);
# Number of streams
sub numberOfStreams
{
return 1;
}
# Rules method
sub evaluateRules
{
# Ignore this module only if both the EPICSourceProducts and RGSProducts modules are completely ignored
return ignore()
if allIgnored( module => 'EPICSourceProducts' ) and allIgnored( module => 'RGSProducts' );
# Otherwise we should only start if all EPICSourceProducts and RGSProducts instances are either complete
# or ignored
start()
if (allComplete( module => 'EPICSourceProducts' ) and allComplete( module => 'RGSProducts' ));
}
# Action method
sub performAction
{
info("Module version number: $version");
my $order = 1;
my %collect = ();
my (@rgsTSList, @rgs1TSList, @rgs2TSList, @epnTSList, @emos1TSList, @emos2TSList);
my (%rgs1, %rgs2);
my %src_files;
info("******************************************************************************************");
info("********** DEBUG - LCMerge - EPIC SRC_NUM identification in RGS Source Lists *************");
info("******************************************************************************************");
foreach my $inst ( "rgs2", "rgs1" )
{
foreach my $exp_id ( listExposures( instrument => $inst ) )
{
my $srcList = findFile( class => 'product'
, instrument => $inst
, exp_id => $exp_id
, content => 'RGS source list'
);
if (!defined($srcList) || $srcList eq '' || !fileExists(file => $srcList))
{
info("Can't find $inst source list for expid $exp_id");
next;
}
my %src_param = &ModuleUtil::get_rgssources_param( $srcList , 'SRCLIST' , $inst ); # => Only sources with T in PROCESS column in the RGS Source list
info("DEBUG - LCMerge - Inst: $inst , srcList: $srcList");
# Cycle through the processed sources (proposal and pointing sources, which always occupy the first 2 rows of the rgs source list,
# are included unilaterally) and find all existing TS for each source:
my $epic_src_num;
my @rgs_processed_sources = (keys %src_param);
info("DEBUG - LCMerge - Sources with RGS products, src_num_INDEX's : @rgs_processed_sources");
foreach my $src ( sort ( @rgs_processed_sources ) )
{
my $src_num = $src_param{$src}{INDEX};
my $src_label = $src_param{$src}{LABEL};
my $src_process = $src_param{$src}{PROCESS};
info("DEBUG - LCMerge -......");
info("DEBUG - LCMerge -......expid: $exp_id , Src: $src , src_num_INDEX: $src_num , src_num_LABEL: $src_label");
# Search for the corresponding EPIC SRCNUM
if ( $src_label =~ /PROPOSAL/i ){
info("DEBUG - LCMerge -......src_num_LABEL: PROPOSAL => Searching for an EPIC identification.");
##################====================================================================================
#
my $data = readFITSTable(
file => $srcList
, extension => 'SRCLIST'
, colname => [qw( INDEX LABEL RA DEC RATE DELTA_DISP DELTA_XDSP PROCESS FLAG )]
);
my $delta_disp_proposal = $data->{DELTA_DISP}[0];
my $delta_xdsp_proposal = $data->{DELTA_XDSP}[0];
my %label_rate;
for my $i ( 2 .. $data->{-nrows} -1 ){ # Loop start at i=2 to skip PROPOSAL and ONAXIS
my $delta_disp = $data->{DELTA_DISP}[$i];
my $delta_xdsp = $data->{DELTA_XDSP}[$i];
my $label = $data->{LABEL}[$i];
my $process = $data->{PROCESS}[$i];
# Distance to PROPOSAL in arcsec
my $dist = 60 * (($delta_disp - $delta_disp_proposal)**2 + ($delta_xdsp - $delta_xdsp_proposal)**2)**(1/2);
# If distance is < $dist_limit arcsec and the source is different to the other processed
# (!$process) the hash %label_rate is populated
my $dist_limit = 6;
###my $dist_limit = 400;
#info("DEBUG - LCMerge - Distance limit: $dist_limit");
if ($dist < $dist_limit and !$process){
$label_rate{$label} = $data->{RATE}[$i];
}
}
# The LABEL of the source to distance to PROPOSAL < 6 arcsec :
# This function returns the key of the maximum value:
$epic_src_num = List::Util::reduce { $label_rate{$b} > $label_rate{$a} ? $b : $a } keys %label_rate;
$epic_src_num =~ s/EPIC0+//;
info("DEBUG - LCMerge -......EPIC identification, EPIC SRC ID = $epic_src_num");
#
##################====================================================================================
} else {
#info("DEBUG - LCMerge - epic_src_num = $src_label");
$epic_src_num = $src_label;
$epic_src_num =~ s/EPIC//;
$epic_src_num = $epic_src_num + 0;
info("DEBUG - LCMerge -......EPIC identification, EPIC SRC ID = $epic_src_num");
}
# Populate %rgs1 and %rgs2 with index and label info:
if ( $inst =~ /rgs1/){
$rgs1{$src_num} = $epic_src_num;
} elsif ( $inst =~ /rgs2/){
$rgs2{$src_num} = $epic_src_num;
}
} # end loop over source list rows
} # end loop over exposures
} # end loop over instruments
my @epic_sources;
my %rrgs1 = reverse %rgs1;
my %rrgs2 = reverse %rgs2;
info("******************************************************************************************");
info("DEBUG - LCMerge - RGS products vs EPIC identifications:");
foreach my $index ( sort ( keys %rgs1 ) ){
info("DEBUG - LCMerge -......rgs1 index: $index => EPIC SRC ID: $rgs1{$index}");
push @epic_sources, $rgs1{$index};}
info("DEBUG - LCMerge -......");
foreach my $index ( sort ( keys %rgs2 ) ){
info("DEBUG - LCMerge -......rgs2 index: $index => EPIC SRC ID: $rgs1{$index}");
push @epic_sources, $rgs1{$index};}
info("******************************************************************************************");
# List of EPIC SRC IDs identified in RGS Source lists
@epic_sources = grep { $_ ne '' } @epic_sources; # Remove empty elements from the array
my @epic_sources_uniq = uniq @epic_sources;
my @rgs_keys = uniq (keys %rgs1, keys %rgs2);
info("******************************************************************************************");
info("********** DEBUG - LCMerge - Loop over RGS1/2 source products. RGS indices: @rgs_keys **********");
info("******************************************************************************************");
my $check_pn_timing = 0;
foreach my $rgs_key ( sort @rgs_keys ){ ### <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
info("******************************************************************************************");
info("DEBUG - LCMerge -......RGS1/2 index: $rgs_key . EPIC SRC IDs: $rgs1{$rgs_key} , $rgs2{$rgs_key}");
info("******************************************************************************************");
#
# Check if exist RGS PROPOSAL product
my $check_rgs1_proposal = 0;
my $check_rgs2_proposal = 0;
if ( $rgs_key == 1 ){
$check_rgs1_proposal = 1;
$check_rgs2_proposal = 1;
}
my $lcurveFileList;
if ( $rgs_key == 1 && ! $rgs1{$rgs_key}){ # $rgs_key == 1 ==> PROPOSAL && !$rgs1{$rgs_key} ==> it is empty
# PROPOSAL + NO EPIC SRC ID ==> RGS + PN Timing OR Only RGS (=> no plot)
info("DEBUG - LCMerge -......PROPOSAL + NO EPIC SRC ID");
info("DEBUG - LCMerge -......All RGS products will be merged only with PN TIMING TS.");
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
# RGS PROPOSAL + NO EPIC SRC ID: PN TIMING TS + RGS TS with no EPIC identification
#
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
# Looking for EPIC TIMING observations
#
# epic-PN Timing TS should be plotted with RGS PROPOSAL product
# Only PN Time Series are available
# For the time being, No products for MOS's in Timing Mode.
#
my %instr_timing;
my @lines = ();
my @epicTSList;
foreach my $instr (qw(epn emos1 emos2)){
@epicTSList = findFile(
class => 'product'
, instrument => $instr
#, exp_id => $exp_id
, src_num => '0' # src_num = 0 ==> TS from TIMING obs.
, content => 'EPIC source timeseries'
, format => 'FITS'
);
#info("DEBUG - LCMerge - Instrument: $instr , Found " . scalar(@epicTSList) ." Timing TS");
next unless ( scalar(@epicTSList) != 0 );
$instr_timing{$instr} = \@epicTSList;
info("DEBUG - LCMerge -......Instrument: $instr , Timing TS files: @{$instr_timing{$instr}}");
@{$instr_timing{$instr}} = sortByTSTART(@{$instr_timing{$instr}}); ###### -- Sorted by Start Time (TSTART)
foreach my $i ( @{$instr_timing{$instr}} ){
chomp $i;
info("DEBUG - LCMerge -......$instr TSs: $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
}
if ( scalar(@lines) ){ # There is PN Timing TS
$check_pn_timing = 1;
info("DEBUG - LCMerge -......RGS PROPOSAL products + EPIC Timing products.");
}
########################################################################################
#
#info("DEBUG - LCMerge -......Checks rgs1, rgs2 : $check_rgs1_proposal , $check_rgs2_proposal");
if ($check_rgs1_proposal || $check_rgs2_proposal){ # If rgs1 or rgs2 has a PROPOSAL product with no EPIC identification
#info("DEBUG - LCMerge -......RGS1 or RGS2 ");
my @rgs1TSList = findFile(
class => 'product'
, instrument => 'rgs1'
#, exp_id => $exp_id
, src_num => '1' # RGS src_num = INDEX =1 in the SrcList = PROPOSAL
#, order => $order
#, rgsorder => $order
, content => 'RGS SOURCE TIMESERIES'
, format => 'FITS'
);
info("DEBUG - LCMerge -......RGS PROPOSAL product RGS1 : @rgs1TSList");
my @rgs2TSList = findFile(
class => 'product'
, instrument => 'rgs2'
#, exp_id => $exp_id
, src_num => '1' # RGS src_num = INDEX =1 in the SrcList = PROPOSAL
#, order => $order
#, rgsorder => $order
, content => 'RGS SOURCE TIMESERIES'
, format => 'FITS'
);
info("DEBUG - LCMerge -......RGS PROPOSAL product RGS2 : @rgs2TSList");
push @rgsTSList, @rgs1TSList;
push @rgsTSList, @rgs2TSList;
@rgsTSList = grep { $_ ne '' } @rgsTSList; # Remove empty elements from the array
#info("DEBUG - LCMerge -......RGS PROPOSAL products : @rgsTSList");
@lines = grep { $_ ne '' } @lines; # Remove empty elements from the array
if (@lines and scalar (grep { $_ !~ /\/\/\// } $lines[-1]) and @rgsTSList ) { push (@lines, "///\n"); } # Add '///' line only if @lines already has any previous component
# and it is != '///'
@rgsTSList = sortByTSTART(@rgsTSList); ###### -- Sorted by Start Time (TSTART)
foreach my $i ( @rgsTSList ){
chomp $i;
info("DEBUG - LCMerge -......R1/2 LCs: $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
@lines = grep { $_ ne '' } @lines; # Remove empty elements from the array
# SourceID => @lines ( = TS files )
$src_files{1} = '0';
$src_files{2} = \@lines;
my $lcurvePlot_check = lcurvePlot(%src_files);
if ( $lcurvePlot_check ){ info("DEBUG - LCMerge - lcurvePlot completed for RGS PROPOSAL + NO EPIC identification");
info("******************************************************************************************");
info("DEBUG - LCMerge -"); }
}
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
} else {
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
# EPIC TS + RGS with EPIC identification
#
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
# Looking for EPIC sources with RGS1/2 TS:
#
# Loop over sources => One Plot per source
#
info("DEBUG - LCMerge - RGS products with EPIC identification, EPIC SRC ID: @epic_sources_uniq");
foreach my $epic_src_num ( sort @epic_sources_uniq ){
# Find PN LCs
#
#info("DEBUG - LCMerge - DEBUG, DEBUG. check_pn_timing = $check_pn_timing");
my @pnTimingTSList;
if ( ! $check_pn_timing) { # Search for PN TIMING TS only if PN TIMING was not included in the previous loop: RGS PROPOSAL
@pnTimingTSList = findFile(
class => 'product'
, instrument => 'epn'
, src_num => '0' # src_num = 0 ==> TS from TIMING obs.
, content => 'EPIC source timeseries'
, format => 'FITS'
);
} else {
info("DEBUG - LCMerge -......PN TIMING TS was included with RGS PROPOSAL.");
}
# If there is PN Timing TS
if ( scalar(@pnTimingTSList) ){
@epnTSList = @pnTimingTSList;
info("DEBUG - LCMerge -......PN TIMING TS: @epnTSList");
} else {
@epnTSList = findFile(
class => 'product'
, instrument => 'epn'
#, exp_id => $exp_id
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
info("DEBUG - LCMerge -......PN TS for EPIC SRC ID $epic_src_num: @epnTSList");
}
#info("DEBUG - LCMerge - PN source: $epic_src_num");
# Find M1 LCs
@emos1TSList = findFile(
class => 'product'
, instrument => 'emos1'
#, exp_id => $exp_id
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
#info("DEBUG - LCMerge - M1 source: $epic_src_num");
# Find M2 LCs
@emos2TSList = findFile(
class => 'product'
, instrument => 'emos2'
#, exp_id => $exp_id
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
#info("DEBUG - LCMerge - M2 source: $epic_src_num");
# Find RGS LCs
my $src_num_1 = $rrgs1{$epic_src_num};
#info("DEBUG - LCMerge - DEBUG DEBUG \$src_num_1 = $src_num_1");
if ( defined($src_num_1) ){
@rgs1TSList = findFile(
class => 'product'
, instrument => 'rgs1'
#, exp_id => $exp_id
, src_num => $src_num_1 # RGS src_num = INDEX in the SrcList
#, order => $order
#, rgsorder => $order
, content => 'RGS SOURCE TIMESERIES'
, format => 'FITS'
);
#info("DEBUG - LCMerge - R1 index, epic source: $src_num_1 , $epic_src_num");
}
my $src_num_2 = $rrgs2{$epic_src_num};
#info("DEBUG - LCMerge - DEBUG DEBUG \$src_num_2 = $src_num_2");
if ( defined($src_num_2) ){
@rgs2TSList = findFile(
class => 'product'
, instrument => 'rgs2'
#, exp_id => $exp_id
, src_num => $src_num_2 # RGS src_num = INDEX in the SrcList
#, order => $order
#, rgsorder => $order
, content => 'RGS SOURCE TIMESERIES'
, format => 'FITS'
);
#info("DEBUG - LCMerge - R2 index, epic source: $src_num_2 , $epic_src_num");
}
# Create filelist for 'lcurve' tool:
#$lcurveFileList = newFile(
# class => 'intermediate'
# , src_num => $epic_src_num
# , content => 'lcurve fileList'
# , format => 'ASCII'
# );
my @lines = ();
@epnTSList = sortByTSTART(@epnTSList);
foreach my $i ( @epnTSList ){
chomp $i;
info("DEBUG - LCMerge -......PN LCs for EPIC SRC ID $epic_src_num : $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
@lines = grep { $_ ne '' } @lines; # Remove empty elements from the array
if (@lines and scalar (grep { $_ !~ /\/\/\// } $lines[-1]) and @emos1TSList ) { push (@lines, "///\n"); } # Add '///' line only if @lines already has any previous component and it is != '///'
@emos1TSList = sortByTSTART(@emos1TSList);
foreach my $i ( @emos1TSList ){
chomp $i;
info("DEBUG - LCMerge -......M1 LCs for EPIC SRC ID $epic_src_num : $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
if (@lines and scalar (grep { $_ !~ /\/\/\// } $lines[-1]) and @emos2TSList ) { push (@lines, "///\n"); }
@emos2TSList = sortByTSTART(@emos2TSList);
foreach my $i ( @emos2TSList ){
chomp $i;
info("DEBUG - LCMerge -......M2 LCs for EPIC SRC ID $epic_src_num : $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
undef @rgsTSList;
push @rgsTSList, @rgs1TSList;
push @rgsTSList, @rgs2TSList;
@rgsTSList = grep { $_ ne '' } @rgsTSList; # Remove empty elements from the array
if (@lines and scalar (grep { $_ !~ /\/\/\// } $lines[-1]) and @rgsTSList ) { push (@lines, "///\n"); }
@rgsTSList = sortByTSTART(@rgsTSList);
foreach my $i ( @rgsTSList ){
chomp $i;
info("DEBUG - LCMerge -......RGS1/2 LCs for RGS index: $src_num_1,$src_num_2 EPIC SRC ID $epic_src_num: $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
# SourceID => @lines ( = TS files )
$src_files{1} = $epic_src_num;
$src_files{2} = \@lines;
my $lcurvePlot_check = lcurvePlot(%src_files);
if ( $lcurvePlot_check ){ info("DEBUG - LCMerge - lcurvePlot completed for RGS + EPIC SRC IDs: $epic_src_num");
info("******************************************************************************************");
info("DEBUG - LCMerge -"); }
}
}
} ### <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
# Rest of EPIC TS's
#
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
#
# Looking for EPIC sources with TS, but no the RGS one
#
# Loop over sources => One Plot per source
#
info("******************************************************************************************");
info("********** DEBUG - LCMerge - Rest of TS's only for EPIC: PN + MOS's **********************");
info("******************************************************************************************");
my $summaryList = findFile(
class => "product"
, instrument => 'epic'
, content => 'EPIC summary source list'
, format => 'FITS'
);
my $src_num_withTSeries;
if ( fileExists( file => $summaryList )){
# Select sources for which Time Series has been produced:
my $filteredSummaryList = newFile(
class => 'intermediate'
, instrument => 'epic'
, content => 'Filtered EPIC summary source list'
);
doCommand(
'fselect'
, infile => $summaryList."[SRCLIST]"
, outfile => $filteredSummaryList
, expr => "TSERIES"
)
or return exception();
$src_num_withTSeries = readFITSColumn(
file => $filteredSummaryList
, extension => "SRCLIST"
, column => "SRC_NUM"
);
for ( my $i=0 ; defined $$src_num_withTSeries[$i] ; $i++ ){
my $epic_src_num = $$src_num_withTSeries[$i];
if ( $epic_src_num ~~ @epic_sources_uniq ){ next; } # Exclude the sources with RGS identification
info("DEBUG - LCMerge - EPIC source with TS but not RGS product. EPIC SRC ID: $epic_src_num");
# Create Light Curves for SRC_NUM = $epic_src_num
undef @epnTSList;
undef @emos1TSList;
undef @emos2TSList;
# Find PN LCs
@epnTSList = findFile(
class => 'product'
, instrument => 'epn'
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
#info("DEBUG - LCMerge - PN source: $epic_src_num");
# Find M1 LCs
@emos1TSList = findFile(
class => 'product'
, instrument => 'emos1'
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
#info("DEBUG - LCMerge - M1 source: $epic_src_num");
# Find M2 LCs
@emos2TSList = findFile(
class => 'product'
, instrument => 'emos2'
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
#info("DEBUG - LCMerge - M2 source: $epic_src_num");
my @lines = ();
@epnTSList = sortByTSTART(@epnTSList);
@emos1TSList = sortByTSTART(@emos1TSList);
@emos2TSList = sortByTSTART(@emos2TSList);
foreach my $i ( @epnTSList ){
chomp $i;
info("DEBUG - LCMerge -......PN LCs for EPIC SRC ID $epic_src_num : $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
@lines = grep { $_ ne '' } @lines; # Remove empty elements from the array
if (@lines and scalar (grep { $_ !~ /\/\/\// } $lines[-1]) and @emos1TSList ) { push (@lines, "///\n"); } # Add '///' line only if @lines already has any previous component and it is != '///'
#@emos1TSList = sortByTSTART(@emos1TSList);
foreach my $i ( @emos1TSList ){
chomp $i;
info("DEBUG - LCMerge -......M1 LCs for EPIC SRC ID $epic_src_num : $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
if (@lines and scalar (grep { $_ !~ /\/\/\// } $lines[-1]) and @emos2TSList ) { push (@lines, "///\n"); }
#@emos2TSList = sortByTSTART(@emos2TSList);
foreach my $i ( sort @emos2TSList ){
chomp $i;
info("DEBUG - LCMerge -......M2 LCs for EPIC SRC ID $epic_src_num : $i");
push (@lines, "$i\n"); ###### -- Populate lcurve FileList
}
# SourceID => @lines ( = TS files )
$src_files{1} = $epic_src_num;
$src_files{2} = \@lines;
my $lcurvePlot_check = lcurvePlot(%src_files);
if ( $lcurvePlot_check ){ info("DEBUG - LCMerge - lcurvePlot completed for EPIC SRC ID: $epic_src_num");
info("******************************************************************************************");
info("DEBUG - LCMerge -"); }
}
}
#--------------------------------------------------------------------------------
# Light Curves merging per Energy Band:
# Corrected RATE (+bkg+errors) + Energy Bands RATEs (+bkg+errors)
# - ALL exposures and all Energy bands in the same FITS file
# - Merging plot also produced
#
info("DEBUG - LCMerge - Start Light Curves merging per Energy Band");
# Add Timing Mode ( src_num = 0 )
# We add '0' value to the SRC_NUM list : @{$src_num_withTSeries}
#
# If $src_num_withTSeries is NOT defined ( = No 'EPIC summary source list' )
# include (0) to check Timing Mode ( src_num = 0 )
if ( ! defined $src_num_withTSeries ){
@{$src_num_withTSeries} = (0);
} else {
# include (0) to check src_num = 0 ==> Timing Mode
unshift @{$src_num_withTSeries}, 0;
}
# Run Source List over the SRC_NUM's for which TSeries was prodcued in the previous module
for ( my $i=0 ; defined $$src_num_withTSeries[$i] ; $i++ ){
my $epic_src_num = $$src_num_withTSeries[$i];
info("DEBUG - LCMerge - EPIC SRC_NUM: $epic_src_num");
foreach my $instr (qw(epn emos1 emos2)){
info("DEBUG - LCMerge - Corrected Light Curves for $instr");
my @allEnergyRangeCorrLC = findFile(
class => 'product'
, instrument => $instr
, src_num => $epic_src_num
, content => 'EPIC SOURCE TIMESERIES'
, format => 'FITS'
);
# If there are no Spectra_files
if ($#allEnergyRangeCorrLC<0) { info("DEBUG - LCMerge - No Corrected TS for SRC_NUM: $epic_src_num from $instr"); next; }
my @SrcLCsperEnergyBand = findFile(
class => 'intermediate'
, instrument => $instr
, src_num => $epic_src_num
, content => 'Uncorrected source time series per EnergyBand'
, format => 'FITS'
);
my @BkgLCsperEnergyBand = findFile(
class => 'intermediate'
, instrument => $instr
, src_num => $epic_src_num
, content => 'Uncorrected background time series per EnergyBand'
, format => 'FITS'
);
my $allEnergyRangeCorrLC = join(',', @allEnergyRangeCorrLC);
my $SrcLCsperEnergyBand = join(',', @SrcLCsperEnergyBand);
my $BkgLCsperEnergyBand = join(',', @BkgLCsperEnergyBand);
# my $finalTablefile = newFile(
# class => 'intermediate'
# , instrument => $instr
# , src_num => $epic_src_num
# , content => 'Final Corrected Light Curves per Energy Band'
# , format => 'FITS'
# );
# my $plotfile = newFile(
# class => 'intermediate'
# , instrument => $instr
# , src_num => $epic_src_num
# , content => 'Final Corrected Light Curves per Energy Band'
# , format => 'PNG'
# );
# Band = 0 if LC from Timing. Band = 8 otherwise (image)
my $band;
if ($epic_src_num == 0 ) { $band = 0; } else { $band = 8; }
my $finalTablefile = newFile(
class => 'product'
, instrument => $instr
, band => $band
, src_num => $epic_src_num
, content => 'EPIC source timeseries'
, format => 'FITS'
);
my $plotfile = newFile(
class => 'product'
, instrument => $instr
, band => $band
, src_num => $epic_src_num
, content => 'EPIC source timeseries plot'
, format => 'PDF'
);
doCommand(
'srcTimeSeriesEnergyBands.py'
, SrcLCsperEnergyBand => $SrcLCsperEnergyBand
, BkgLCsperEnergyBand => $BkgLCsperEnergyBand
, allEnergyRangeCorrLC => $allEnergyRangeCorrLC
, outfits => $finalTablefile
, plotting => 'Y'
, plotfile => $plotfile
, plotformat => 'pdf'
, verbose => 'N'
) or return exception();
}
}
#--------------------------------------------------------------------------------
return success();
}
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
##\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# -----------------------------------------------------------------------------
sub sortByTSTART {
my @files = @_;
my (%file_tstart, @lines);
foreach my $i ( sort @files ){
my $tstart = readFITSKeyword(file => $i, extension => 'RATE', keyword => 'TSTART');
$file_tstart{$i} = $tstart;}
# Sort the keys of the hash (files) according to the values (TStart)
foreach my $i (sort { $file_tstart{$a} <=> $file_tstart{$b} } keys %file_tstart){
push (@lines, "$i\n");}
return @lines;
}
# -----------------------------------------------------------------------------
sub lcurvePlot {
my (%src_files) = @_;
my $src_num = $src_files{1};
my @lines = @{$src_files{2}};
# Get the number of Input Series for 'lcurve'
#
my $inputSeries = 1 + scalar (grep { $_ =~ /\/\/\// } @lines);
info("******************************************************************************************");
info("DEBUG - LCMerge - Merged TS plot. Number of instruments/plots: $inputSeries");
# Create and populate filelist for 'lcurve' tool:
my $lcurveFileList = newFile(
class => 'intermediate'
, src_num => $src_num
, content => 'lcurve fileList' # or 'timing lcurve fileList'
, format => 'ASCII'
);
if ( fileExists( file => $lcurveFileList )){unlink ( $lcurveFileList );}
writeASCIIFile( name => $lcurveFileList
, text => \@lines
, append => 1
);
###########
#
# lcurve nser=4 cfile1="@filelist.txt" window="-" plot=yes plotdev="/null" dtnb="INDEF" nbint="INDEF" outfile=" " plotdnum=4 < dolc.qdp
#
my $lcurvePlot = newFile(
class => 'intermediate'
, src_num => $src_num
, content => 'lcurve plot'
, format => 'PS'
);
my $lcurveCommands = newFile(
class => 'intermediate'
, src_num => $src_num
, content => 'lcurve commands'
, format => 'ASCII'
);
if ( fileExists( file => $lcurveCommands )){unlink ( $lcurveCommands );}
my @commands = ();
my $j = 1;
my @files = grep { $_ !~ /\/\/\// } @lines;
# Lists with only RGS excluded:
my $files_size = scalar (@files);
my $number_of_RGS_LCs = scalar ( grep { $_ =~ /R1/ } @files) + scalar ( grep { $_ =~ /R2/ } @files);
if ( $files_size eq $number_of_RGS_LCs){
info("DEBUG - LCMerge - List RGS TSs to merge. No plot for those cases.");
return;
}
#
foreach my $file (@files){
info("DEBUG - LCMerge -......\@files : $file");
}
foreach my $i (@files){
my $label;
$j++;
if (scalar ( grep { $_ =~ /PN/ } $i)) {$label = "PN";}
if (scalar ( grep { $_ =~ /M1/ } $i)) {$label = "M1";}
if (scalar ( grep { $_ =~ /M2/ } $i)) {$label = "M2";}
if (scalar ( grep { $_ =~ /R1/ } $i)) {$label = "RGS";}
if (scalar ( grep { $_ =~ /R2/ } $i)) {$label = "RGS";}
#info("DEBUG - LCMerge - j : $j label: $label");
info("DEBUG - LCMerge -......Plot label: $label");
push (@commands, "win $j\n");
push (@commands, "lab y $label\n");
if (scalar (grep { $_ =~ /PN/ } @commands) > 1) {
splice @commands, -2; # Remove the last 2 elements from @commands array
$j = $j -1;
#info("DEBUG - LCMerge - Removing PN lines");
}
if (scalar (grep { $_ =~ /M1/ } @commands) > 1) {
splice @commands, -2;
$j = $j -1;
#info("DEBUG - LCMerge - Removing M1 lines");
}
if (scalar (grep { $_ =~ /M2/ } @commands) > 1) {
splice @commands, -2;
$j = $j -1;
#info("DEBUG - LCMerge - Removing M2 lines");
}
if (scalar (grep { $_ =~ /RGS/ } @commands) > 1) {
splice @commands, -2;
$j = $j -1;
#info("DEBUG - LCMerge - Removing RGS lines");
}
}
push (@commands, "Device $lcurvePlot/vps\n");
push (@commands, "plot\n");
push (@commands, "Device\n");
push (@commands, "exit\n");
writeASCIIFile( name => $lcurveCommands
, text => \@commands
, append => 1
);
#
my $command = 'lcurve nser=' . $inputSeries . ' cfile1="@' . $lcurveFileList .
'" window="-" plot=yes plotdev="/null" dtnb="INDEF" nbint="INDEF" outfile=" " plotdnum=' .
$inputSeries .' < ' . $lcurveCommands;
doCommand("$command");
if ( fileExists(file => $lcurvePlot)){
info("DEBUG - LCMerge - Merged timeseries created");
# PS to PDF
my $lcurveInterPDFPlot = newFile(
class => 'intermediate'
, instrument => 'epic'
, src_num => $src_num
, content => 'EPIC source lcurve timeseries plot'
, format => 'PDF'
);
PStoPDF(
source => $lcurvePlot
, destination => $lcurveInterPDFPlot
) or return exception();
} else {
info("DEBUG - LCMerge - Warning: Merged timeseries was not created");
}
#################################################################################
#
# Python tasks included, but still under investigation
# Testing phase
#
# #
# # Create Plot by Python task
# #
my $LCMergePDFplot = newFile(
class => 'product'
, instrument => 'epic'
, src_num => $src_num
, content => 'EPIC source timeseries plot'
, format => 'PDF'
);
doCommand(
'plotTimeSeries.py'
, infile => $lcurveFileList
, outfile => $LCMergePDFplot
, outformat => 'pdf'
);
#################################################################################
}
# -----------------------------------------------------------------------------
1;