#! /usr/bin/env python # ========================================================================== # Display butterfly generated by ctbutterfly and spectrum generated by csspec # # Copyright (C) 2018-2021 Juergen Knoedlseder # # This program 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. # # This program 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 this program. If not, see . # # ========================================================================== import sys import gammalib import cscripts try: import matplotlib.pyplot as plt plt.figure() plt.close() except (ImportError, RuntimeError): print('This script needs the "matplotlib" module') sys.exit() # =========================== # # Plot spectrum and butterfly # # =========================== # def plot_spectrum_butterfly(specfile, butterfile, fmt='o', color='red'): """ Plot sensitivity data Parameters ---------- specfile : str Name of spectrum FITS file butterfile : str Name of butterfly FITS file fmt : str Symbol format color : str Symbol color """ # Read spectrum file fits = gammalib.GFits(specfile) table = fits.table(1) c_energy = table['e_ref'] c_ed = table['e_min'] c_eu = table['e_max'] c_flux = table['ref_e2dnde'] c_norm = table['norm'] c_eflux = table['norm_err'] c_upper = table['norm_ul'] c_ts = table['ts'] # Read butterfly file csv = gammalib.GCsv(butterfile) # Initialise arrays to be filled energies = [] flux = [] ed_engs = [] eu_engs = [] e_flux = [] ul_energies = [] ul_ed_engs = [] ul_eu_engs = [] ul_flux = [] butterfly_x = [] butterfly_y = [] line_x = [] line_y = [] # Loop over rows of the file nrows = table.nrows() for row in range(nrows): # Get Test Statistic, flux and flux error ts = c_ts.real(row) norm = c_norm.real(row) flx = norm * c_flux.real(row) e_flx = flx * c_eflux.real(row) # If Test Statistic is larger than 9 and flux error is smaller than # flux then append flux plots ... if ts > 9.0 and e_flx < flx: energies.append(c_energy.real(row)) flux.append(flx) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(e_flx) # ... otherwise append upper limit else: ul_energies.append(c_energy.real(row)) ul_flux.append(flx*c_upper.real(row)) ul_ed_engs.append(c_ed.real(row)) ul_eu_engs.append(c_eu.real(row)) # Set upper limit errors yerr = [0.6 * x for x in ul_flux] # Loop over rows of the file nrows = csv.nrows() for row in range(nrows): # Compute upper edge of confidence band butterfly_x.append(csv.real(row,0)/1.0e6) # TeV butterfly_y.append(csv.real(row,2)*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg) # Set line values line_x.append(csv.real(row,0)/1.0e6) # TeV line_y.append(csv.real(row,1)*csv.real(row,0)*csv.real(row,0)*gammalib.MeV2erg) # Loop over the rows backwards to compute the lower edge of the # confidence band for row in range(nrows): index = nrows - 1 - row butterfly_x.append(csv.real(index,0)/1.0e6) low_error = max(csv.real(index,3)*csv.real(index,0)*csv.real(index,0)*gammalib.MeV2erg, 1e-26) butterfly_y.append(low_error) # Plot the spectrum plt.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs], fmt=fmt, color=color, markeredgecolor=color) plt.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs], yerr=yerr, uplims=True, fmt=fmt, color=color, markeredgecolor=color) # Plot the butterfly plt.plot(line_x, line_y, color='black', ls='-') plt.fill(butterfly_x, butterfly_y, color='green', alpha=0.5) # Return return # =========================== # # Show spectrum and butterfly # # =========================== # def show_spectrum_butterfly(): """ Show spectrum and butterfly """ # Create figure plt.figure() plt.loglog() plt.grid() # Set usage string usage = 'show_onoff_spectrum.py [-p plotfile] [-t title] [specfile] [butterfile]' # Set default options options = [{'option': '-p', 'value': ''}, {'option': '-t', 'value': 'Cassiopeia A'}] # Get arguments and options from command line arguments args, options = cscripts.ioutils.get_args_options(options, usage) # Extract script parameters from options plotfile = options[0]['value'] title = options[1]['value'] # Set filenames specfile = 'spectrum.fits' butterfile = 'butterfly.txt' if len(args) > 0: specfile = args[0] if len(args) > 1: butterfile = args[1] # Show spectrum and butterfly plot_spectrum_butterfly(specfile, butterfile, fmt='ro', color='red') # Plot labels plt.xlabel('Energy (TeV)') plt.ylabel(r'E$^2$ $\times$ dN/dE (erg cm$^{-2}$ s$^{-1}$)') # Set title plt.title(title) # Show figure if len(plotfile) > 0: plt.savefig(plotfile) else: plt.show() # Return return # ======================== # # Main routine entry point # # ======================== # if __name__ == '__main__': # Show spectrum and butterfly show_spectrum_butterfly()