# 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;