Download

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

########################################################################