version_num = "1.1"
import sys,os
import warnings
import argparse
parser = argparse.ArgumentParser(description='Get the Flaring Background filtering threshold cut from the Source Time Series', prog='srcBkgGti.py')
parser.add_argument('--version', '-v', action='version', version='%(prog)s (%(prog)s-{}) [-]'.format(version_num))
parser.add_argument('--srctslist', help='Input Source Time Series FITS file. Default: SourceTimeSeries.ds', default='SourceTimeSeries.ds')
parser.add_argument('--diagplot' , help='Create a diagnostic plot. Default: No', default='No')
parser.add_argument('--outfile' , help='Output figure file. Default: figure. If the output filename already has a valid extension, it will be kept', default='figure')
parser.add_argument('--outformat', help='Output figure format. Default: png', choices=['png', 'pdf'], default='png')
args = parser.parse_args()
from astropy.io import fits
from astropy.table import Table
from astropy.coordinates import SkyCoord
from astropy import units as u
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
srcTSList = args.srctslist
ext = args.outformat
diagPlot = args.diagplot
diagPlotTest = 0
yes = ('yes', 'y')
no = ('no', 'n')
if diagPlot.lower() in yes:
diagPlotTest = 1
elif diagPlot.lower() in no:
print('No plot produced.')
else:
print('Wrong option for --diagplot. No plot produced.')
def isNotNaN(num):
return num == num
if args.outfile.lower().endswith(('.png', '.pdf')):
figure = args.outfile
else:
figure = args.outfile + '.' + ext
if os.path.isfile(srcTSList) and os.access(srcTSList, os.W_OK):
pass
else:
print("\nEither file " + srcTSList + " is missing or has not write persmissions.\n")
sys.exit(1)
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=Warning)
tsr = Table.read(srcTSList, hdu=1)
tsr_not_sorted = Table.read(srcTSList, hdu=1)
obs_id = tsr.meta['OBS_ID']
instrument = tsr.meta['INSTRUME']
if instrument == 'EPN' or instrument == 'EMOS1' or instrument == 'EMOS2':
try:
ra_deg = tsr.meta['SRC_RA']
dec_deg = tsr.meta['SRC_DEC']
srcnum = tsr.meta['SRCNUM']
coord = SkyCoord(ra=ra_deg*u.degree, dec=dec_deg*u.degree)
coords_hmsdms = coord.to_string('hmsdms')
except KeyError:
pass
tsr.sort('BACKV')
rate = np.nan_to_num(tsr['RATE']) * np.nan_to_num(tsr['FRACEXP'] )
crate = (np.fmax(rate, rate*0)).cumsum()
erate = np.sqrt( ((np.nan_to_num(tsr['ERROR'])**2)*tsr['FRACEXP']).cumsum() )
crate = np.ma.masked_array(crate, mask=(erate == 0))
erate = np.ma.masked_array(erate, mask=(erate == 0))
s2nc = np.nan_to_num(crate/erate)
imax = s2nc.argmax()
s2nmax = s2nc[imax]
backvmax = tsr['BACKV'][imax]
covered_time_fraction = 100.*(imax+1.)/len(s2nc)
s2nlast = s2nc[-1]
diff_max_last = 100*(abs(s2nmax - s2nlast)/s2nmax)
if diff_max_last < 20 or s2nmax < 10:
backvmax = tsr['BACKV'][ isNotNaN(tsr['BACKV']) ][-1]
covered_time_fraction = 100.
print('Bkg rate threshold cut = {0:.4f}; fraction of time covered = {1:.4f} %'.format(backvmax, covered_time_fraction))
fits.setval(srcTSList, 'FLCUTTHR', value = backvmax, ext=1)
if diagPlotTest:
f = plt.figure(1)
f.set_size_inches(8.0,10.0)
plt.subplot(3, 1, 1)
plt.plot(tsr['BACKV'], s2nc, ms=4, ls='-')
plt.plot( backvmax, s2nmax, 'rs', fillstyle='none', ms=8)
plt.axvline( x=backvmax, color='r', ls='--')
plt.xlabel('{0}'.format('Background rate (BACKV)'))
plt.ylabel('{0}'.format('Cummulative S/N'))
plt.annotate('Max. Cumm. S/N: {0:.2f}'.format(s2nmax), xy=(0.4, 0.2), xycoords='axes fraction')
plt.annotate('Diff. Max. Cumm. S/N vs last value: {0:.2f} %'.format(diff_max_last), xy=(0.4, 0.1), xycoords='axes fraction')
time = tsr_not_sorted['TIME'] - tsr_not_sorted['TIME'][0]
plt.subplot(3, 1, 2)
plt.plot( time ,tsr_not_sorted['RATE'], ms=0.5, ls='-')
plt.ylabel('{0}'.format('Source rate'))
plt.subplot(3, 1, 3)
plt.plot( time ,tsr_not_sorted['BACKV'], ms=0.5, ls='-')
plt.axhline( y=backvmax, color='r', ls='--')
plt.xlabel('{0}'.format('TIME (sec)'))
plt.ylabel('{0}'.format('Background rate (BACKV)'))
f.subplots_adjust(hspace=0.4)
plt.annotate('Flaring background filtering\nfor maximum S/N diagnostic plot', xy=(0.5, 0.95), xycoords='figure fraction', horizontalalignment='center', size=12)
plt.annotate('OBS_ID: {0}'.format(obs_id), xy=(0.13, 0.91), xycoords='figure fraction')
plt.annotate('EPIC SRCNUM: {0}'.format(srcnum), xy=(0.50, 0.91), xycoords='figure fraction')
plt.annotate('RA,Dec: {0}'.format(coords_hmsdms), xy=(0.50, 0.89), xycoords='figure fraction')
plt.savefig( figure, format=ext)