#!/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) ########################################################################