#!/usr/bin/env python
#
"""
This file is part of ESA's XMM-Newton Scientific Analysis System (SAS).
SAS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SAS. If not, see .
Name = ''
VERSION = '1.1';
author = 'Jose Vicente Perea';
date = '2021-03-23';
ChangeLog
=========
Version 1.1 - 2021-03-23 (JVP)
------------
+ Take only rates > 0 to avoid Log axis issues
Different plot style if there is not signal-to-noise plot
Version 1.0 - 2021-03-16 (JVP)
------------
+ Initial version
Task to plot Flaring Background timeseries
and signal-to-noise
"""
__version__ = "1.1"
__author__ = "Jose V. Perea"
__copyright__ = "ESA (C) 2000-2020"
__license__ = "GPL"
########################################################################
def plotFlrBkgTS(rate=None, plotformat=None, outfile=None, pdfoutfile=None):
from astropy.io import fits
# Read FITS file
with fits.open(rate) as hdul:
rates = hdul['RATE'].data
hdr = hdul['RATE'].header
try:
sn_to_no = hdul['SN_TO_BKGCUT'].data
sn = True
except:
print(f'Rate file {rate} does not have SN_TO_BKGCUT extension')
sn = False
tstart = hdr['TSTART']
tstop = hdr['TSTOP']
srcut = hdr['FLCUTTHR']
# Plot
import matplotlib
matplotlib.use('Agg') # To avoid problems with DISPLAY variable
# raise RuntimeError('Invalid DISPLAY variable')
# RuntimeError: Invalid DISPLAY variable.
import matplotlib.pyplot as plt
#
plt.style.use('classic')
from matplotlib.ticker import FormatStrFormatter, AutoLocator
if sn:
fig, ax = plt.subplots( 2 )
else:
fig, ax = plt.subplots( 1 )
ax = [ax, None]
#fig.set_size_inches(8.0,10.0) # => 800 x 1000 pix
scale = 1.5
fig.set_size_inches( 6.12*scale, 7.92*scale ) # => 612 x 792 pix = picture size in XSA
font = 11
rateFile = os.path.basename(rate)
rates = rates[ rates.RATE > 0 ] # Take only positive values to avoid Log axis issues
#T = rates.T_ELAPSED # T_ELAPSED column is not right for mereged TS X000FBKTSR ( no exp's > 1 merged in one )
T = rates.TIME - tstart
if sn:
f='-'
else:
f='.-'
ax[0].plot( T, rates.RATE, f, c='r', ms=5 )
ax[0].axhline( y = srcut, c = 'b' )
ax[0].annotate(f'{srcut:.3f}', xy=(1.01, srcut), xycoords=('axes fraction','data'), verticalalignment="center", fontsize=font, c='b')
ax[0].set_yscale('log')
ax[0].set_title(f'Plot of file {rateFile}', fontsize = font+2)
ax[0].set_xlabel(f'TIME-{tstart} (s)', fontsize=font)
ax[0].set_ylabel('RATE (cts/s)', fontsize=font)
ax[0].yaxis.set_major_formatter(FormatStrFormatter("%.1f"))
#ax[0].yaxis.set_major_locator(AutoLocator())
min_y, max_y = ( min(rates.RATE)-0.2*min(rates.RATE), max(rates.RATE)+0.2*max(rates.RATE) )
ax[0].set_ylim( min_y, max_y )
ax[0].set_xlim( min(T)-200, max(T)+200)
if sn:
fig.subplots_adjust(hspace=0.4) # hspace between plots
ax[1].plot( sn_to_no.BKGRATECUT, sn_to_no.SN_RATIO, c='r', ms=5 )
ax[1].axvline( x = srcut, c = 'b' )
ax[1].annotate(f'{srcut:.3f}', xy=( srcut, -0.10 ), xycoords=('data','axes fraction'), horizontalalignment="center", fontsize=font, c='b')
ax[1].set_title(f'Plot of file {rateFile}[SN_TO_BKGCUT]', fontsize = font+2)
ax[1].set_xlabel(f'Background rate cut (cts/s)', fontsize=font)
ax[1].set_ylabel('Signal-to-noise', fontsize=font)
# Same settings for both axis
[ x.minorticks_on() for x in ax if x ]
[ x.tick_params(axis='both', which='major', labelsize=font) for x in ax if x ]
if plotformat == 'png':
print(f'Saving file : {outfile}')
plt.savefig(outfile)
elif plotformat == 'pdf':
print(f'Saving file : {pdfoutfile}')
plt.savefig(pdfoutfile)
elif plotformat == 'both':
print(f'Saving files : {outfile} and {pdfoutfile}')
plt.savefig(outfile)
plt.savefig(pdfoutfile)
########################################################################
import sys, os
import argparse
import ModuleUtil
version_num = __version__
def input():
# Inut Options
parser = argparse.ArgumentParser(description='Plot Flaring Background light curves',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--version', '-v', action='version', version=f'%(prog)s (%(prog)s-{version_num}) [-]')
parser.add_argument('--rateset', help='Input Flaring Background timeseries file', default='flrBkgTimeseries.fit')
parser.add_argument('--plotfile', help='Output PNG plot file')
parser.add_argument('--pdfplotfile', help='Output PDF plot file')
parser.add_argument('--plotformat', help='Plot format (png/pdf)', choices=['png', 'pdf', 'both'], default='png')
args = parser.parse_args()
return args
def main(args):
flrBkgRate = args.rateset
plotfile = args.plotfile
pdfplotfile = args.pdfplotfile
plotformat = args.plotformat
if plotformat == 'png' and ( not plotfile or not plotfile.lower().endswith('png') ):
print(f'plotformat {plotformat} selected, but input plotfile not set or incorrect extension. Exiting')
sys.exit(1)
if plotformat == 'pdf' and ( not pdfplotfile or not pdfplotfile.lower().endswith('pdf') ):
print(f'plotformat {plotformat} selected, but input pdfplotfile not set or incorrect extension. Exiting')
sys.exit(1)
if plotformat == 'both' and ( not plotfile or not pdfplotfile or not plotfile.lower().endswith('png') or not pdfplotfile.lower().endswith('pdf') ):
print(f'plotformat {plotformat} selected, but input plotfile/pdfplotfile not set or incorrect extension. Exiting')
sys.exit(1)
if not os.path.isfile(flrBkgRate):
print('Input flrBkgRate file does not exist. Exiting')
sys.exit(1)
plot = plotFlrBkgTS( rate = flrBkgRate, plotformat=plotformat, outfile=plotfile, pdfoutfile=pdfplotfile )
########################################################################
if __name__=='__main__':
argsObj = input()
main(argsObj)
sys.exit(0)
########################################################################