def get_hess_lightcurve(filename='pks-hess-data.csv'): """ Get HESS lightcurve Parameters ---------- filename : str, optional Light curve data file name Returns ------- x, y, y_err : tuple of floats Energy, flux and flux error """ # Open data file file1 = gammalib.GFilename('$CTAGITROOT/analysis/hess_dr1/%s' % filename) file2 = gammalib.GFilename('%s' % filename) if file1.exists(): csv = gammalib.GCsv(file1,'\t') else: csv = gammalib.GCsv(file2,'\t') # Initialise arrays x = [] y = [] y_err = [] # Loop over data for row in range(csv.nrows()): x.append(float(csv[row,0])+1.0/(24.0*60.0)) y.append(float(csv[row,1])*1.0e-9) y_err.append((float(csv[row,2])-float(csv[row,1]))*1.0e-9) # Return return x,y,y_err
def __init__(self, *argv): """ Constructor. Parameters ---------- argv : list of str List of IRAF command line parameter strings of the form ``parameter=3``. """ # Set name and version self._name = 'csobsdef' self._version = '1.1.0' # Initialise class members self._obs = gammalib.GObservations() self._pntdef = gammalib.GCsv() self._tmin = 0.0 # Initialise application by calling the appropriate class # constructor. self._init_cscript(argv) # Return return
def plot_butterfly(filename, ax, color, label): csv = gammalib.GCsv(filename) # Initialise arrays to be filled butterfly_x = [] butterfly_y = [] line_x = [] line_y = [] # Loop over rows of the file nrows = csv.nrows() for row in range(nrows): # Get conversion coefficient conv = csv.real(row, 0) * csv.real(row, 0) * gammalib.MeV2erg # Compute upper edge of confidence band butterfly_x.append(csv.real(row, 0) / 1.0e6) # TeV butterfly_y.append(csv.real(row, 2) * conv) # Set line values line_x.append(csv.real(row, 0) / 1.0e6) # TeV line_y.append(csv.real(row, 1) * conv) # Loop over the rows backwards to compute the lower edge of the # confidence band for row in range(nrows): index = nrows - 1 - row conv = csv.real(index, 0) * csv.real(index, 0) * gammalib.MeV2erg butterfly_x.append(csv.real(index, 0) / 1.0e6) low_error = max(csv.real(index, 3) * conv, 1e-26) butterfly_y.append(low_error) ax.plot(line_x, line_y, color=color, ls='-', label=label) ax.fill(butterfly_x, butterfly_y, color=color, alpha=0.4)
def _check_runlist(self, filename, runs=1): """ Check run list file Parameters ---------- filename : str Run list file name runs : int, optional Expected number of runs in runlist file """ # Open run list file as CSV file runlist = gammalib.GCsv(filename) # Check dimensions self.test_value(runlist.nrows(), runs, 'Check for number of runs in runlist file') if runs > 0: self.test_value(runlist.ncols(), 1, 'Check for single column in runlist file') self.test_value(runlist[0, 0], '15000', 'Check for run ID in runlist file') # Return return
def read_sensitivity(filename): """ Read sensitivity information from CSV file Parameters ---------- filename : str Name of CSV file Returns ------- sensitivity : dict Dictionary with sensitivity information """ # Read filename csv = gammalib.GCsv(filename, ',') # Create dictionnary sensitivity = {} for column in range(csv.ncols()): name = csv[0, column].rstrip('\r') values = [] for row in range(csv.nrows() - 1): values.append(float(csv[row + 1, column])) sensitivity[name] = values # Check where file contains differential or integral sensitivity mode = 'Integral' if sensitivity.has_key('emax'): emax_ref = -1.0 for value in sensitivity['emax']: if emax_ref < 0.0: emax_ref = value elif emax_ref != value: mode = 'Differential' break # Add mode sensitivity['mode'] = mode # Add linear energy values if mode == 'Differential': if sensitivity.has_key('loge'): name = 'energy' values = [] for value in sensitivity['loge']: values.append(math.pow(10.0, value)) sensitivity[name] = values else: if sensitivity.has_key('emin'): name = 'energy' values = [] for value in sensitivity['emin']: values.append(value) sensitivity[name] = values # Return return sensitivity
def get_pointings(filename): """ Extract pointings from CSV file Parameters ---------- filename : str File name of observation definition CSV file Returns ------- pnt : list of dict Pointings """ # Initialise pointings pnt = [] # Open CSV file csv = gammalib.GCsv(filename, ',') # Loop over rows for i in range(csv.nrows()): # Skip header if i == 0: continue # Extract information id = csv[i, 1] lon = float(csv[i, 2]) lat = float(csv[i, 3]) tstart = float(csv[i, 5]) duration = float(csv[i, 6]) irf = csv[i, 8] zenith = float(csv[i, 11]) # Convert direction dir = gammalib.GSkyDir() dir.lb_deg(lon, lat) # Derive attributes south = 'South' in irf # Create entry entry = {'id': id, 'l': lon, 'b': lat, 'ra': dir.ra_deg(), 'dec': dir.dec_deg(), 'time': tstart, 'duration': duration, \ 'zenith': zenith, 'south': south} # Append pointing pnt.append(entry) # Return pointings return pnt
def _check_pull_file(self, filename): """ Check pull file """ # Open pull file as CSV file pulls = gammalib.GCsv(filename) # Check dimensions self.test_value(pulls.nrows(), 4, 'Check for 4 rows in pull file') # Return return
def _check_result_file(self, filename): """ Check result file """ # Open result file as CSV file results = gammalib.GCsv(filename, ',') # Check dimensions self.test_value(results.nrows(), 2, 'Check for 2 rows in TS file') self.test_value(results.ncols(), 14, 'Check for 14 columns in TS file') # Return return
def _create_tbounds(self): """ Creates phase bins Returns ------- phbins : `[]` List of phase bins """ # Initialise Good Time Intervals phbins = [] # Get algorithm to use for defining the time intervals. Possible # values are "FILE" or "LIN". This is enforced at # parameter file level, hence no checking is needed. algorithm = self['phbinalg'].string() # If the algorithm is "FILE" then handle a FITS or an ASCII file for # the time bin definition if algorithm == 'FILE': # Get the filename filename = self['phbinfile'].filename() # Load ASCII file as CSV file and construct # the GTIs from the rows of the CSV file. It is expected that the # CSV file has two columns containing the "START" and "STOP" # values of the phase bins. No header row is expected. csv = gammalib.GCsv(filename) for i in range(csv.nrows()): phmin = csv.real(i, 0) phmax = csv.real(i, 1) phbins.append([phmin, phmax]) # If the algorithm is "LIN" then use a linear time binning, defined by # the "phbins" user parameters elif algorithm == 'LIN': # Get start and stop time and number of time bins nbins = self['phbins'].integer() # Compute time step and setup the GTIs ph_step = 1.0 / float(nbins) for i in range(nbins): phmin = i * ph_step phmax = (i + 1) * ph_step phbins.append([phmin, phmax]) # Return Good Time Intervals return phbins
def _check_result_file(self, filename): """ Check result file """ # Open result file as CSV file results = gammalib.GCsv(filename) # Check dimensions self.test_value(results.nrows(), 100, 'Check for 100 rows in butterfly file') self.test_value(results.ncols(), 4, 'Check for 4 columns in butterfly file') # Return return
def _check_result_file(self, filename, nrows=2): """ Check result file """ # Open result file as CSV file results = gammalib.GCsv(filename, ',') # Check dimensions self.test_value(results.nrows(), nrows, 'Check number of rows in sensitivity file') self.test_value(results.ncols(), 10, 'Check number of columns in sensitivity file') # Return return
def _check_runlist(self, filename): """ Check run list file. """ # Open run list file as CSV file runlist = gammalib.GCsv(filename) # Check dimensions self.test_value(runlist.ncols(), 1, 'Check for single column in runlist file') self.test_value(runlist.nrows(), 1, 'Check for single row in runlist file') self.test_assert(runlist[0,0] == '0', 'Check for value "0" in runlist file') # Return return
def __init__(self, *argv): """ Constructor Parameters ---------- argv : list of str List of IRAF command line parameter strings of the form ``parameter=3``. """ # Initialise application by calling the base class constructor self._init_cscript(self.__class__.__name__, ctools.__version__, argv) # Initialise class members self._obs = gammalib.GObservations() self._pntdef = gammalib.GCsv() self._tmin = 0.0 # Return return
def _check_result_file(self, filename, nrows=3, ncols=9): """ Check result file Parameters ---------- filename : str Name of result file nrows : int, optional Required number of rows ncols : int, optional Required number of columns """ # Open result file as CSV file results = gammalib.GCsv(filename, ',') # Check dimensions self.test_value(results.nrows(), nrows, 'Check rows in TS file') self.test_value(results.ncols(), ncols, 'Check columns in TS file') # Return return
def plot_butterfly(filename, plotfile): """ Plot butterfly diagram Parameters ---------- filename : str Butterfly CSV file plotfile : str Plot filename """ # Read butterfly file csv = gammalib.GCsv(filename) # Initialise arrays to be filled butterfly_x = [] butterfly_y = [] line_x = [] line_y = [] # Loop over rows of the file nrows = csv.nrows() for row in range(nrows): # Get conversion coefficient conv = csv.real(row, 0) * csv.real(row, 0) * gammalib.MeV2erg # Compute upper edge of confidence band butterfly_x.append(csv.real(row, 0) / 1.0e6) # TeV butterfly_y.append(csv.real(row, 2) * conv) # Set line values line_x.append(csv.real(row, 0) / 1.0e6) # TeV line_y.append(csv.real(row, 1) * conv) # Loop over the rows backwards to compute the lower edge of the # confidence band for row in range(nrows): index = nrows - 1 - row conv = csv.real(index, 0) * csv.real(index, 0) * gammalib.MeV2erg butterfly_x.append(csv.real(index, 0) / 1.0e6) low_error = max(csv.real(index, 3) * conv, 1e-26) butterfly_y.append(low_error) # Plot the butterfly and spectral line plt.figure() plt.loglog() plt.grid() plt.plot(line_x, line_y, color='black', ls='-') plt.fill(butterfly_x, butterfly_y, color='green', alpha=0.5) plt.xlabel('Energy (TeV)') plt.ylabel(r'E$^2$ $\times$ dN/dE (erg cm$^{-2}$ s$^{-1}$)') # Show spectrum or save it into file if len(plotfile) > 0: plt.savefig(plotfile) else: plt.show() # Return return
def _test_python(self): """ Test csphasecrv from Python """ # Set-up unbinned csphasecrv pcrv = cscripts.csphasecrv() pcrv['inobs'] = self._phased_events pcrv['inmodel'] = self._model pcrv['srcname'] = 'Crab' pcrv['caldb'] = self._caldb pcrv['irf'] = self._irf pcrv['phbinalg'] = 'LIN' pcrv['phbins'] = 2 pcrv['method'] = '3D' pcrv['enumbins'] = 0 pcrv['emin'] = 1.0 pcrv['emax'] = 100.0 pcrv['outfile'] = 'csphasecrv_py1.fits' pcrv['logfile'] = 'csphasecrv_py1.log' pcrv['chatter'] = 2 pcrv['publish'] = True # Run csphasecrv script and save phase curve pcrv.logFileOpen() # Make sure we get a log file pcrv.run() pcrv.save() # Check phase curve self._check_phase_curve('csphasecrv_py1.fits', 2) # Now use FILE as time bin algorithm. For this we need first to # create an ASCII file. We use now 2 phase bins. The ASCII file # is saved into the file "csphasecrv_py2.dat". csv = gammalib.GCsv(2, 2) phmin = 0.0 phdelta = 1.0 / float(csv.nrows()) for i in range(csv.nrows()): csv[i, 0] = '%.5f' % (phmin + i * phdelta) csv[i, 1] = '%.5f' % (phmin + (i + 1) * phdelta) csv.save('csphasecrv_py2.dat', ' ', True) # Set-up unbinned csphasecrv pcrv = cscripts.csphasecrv() pcrv['inobs'] = self._phased_events pcrv['inmodel'] = self._model pcrv['srcname'] = 'Crab' pcrv['caldb'] = self._caldb pcrv['irf'] = self._irf pcrv['phbinalg'] = 'FILE' pcrv['phbinfile'] = 'csphasecrv_py2.dat' pcrv['method'] = '3D' pcrv['enumbins'] = 0 pcrv['emin'] = 1.0 pcrv['emax'] = 100.0 pcrv['outfile'] = 'csphasecrv_py2.fits' pcrv['logfile'] = 'csphasecrv_py2.log' pcrv['chatter'] = 3 # Execute csphasecrv script pcrv.logFileOpen() # Make sure we get a log file pcrv.execute() # Check phase curve self._check_phase_curve('csphasecrv_py2.fits', csv.nrows()) # Now we setup an observation container on input. We attached the # model to the observation container so that csphasecrv should # no longer query for the parameter. cta = gammalib.GCTAObservation(self._phased_events) obs = gammalib.GObservations() obs.append(cta) obs.models(self._model) # Set-up unbinned csphasecrv from observation container. Now use # the GTI algorithm so that we test all timing algorithms. pcrv = cscripts.csphasecrv(obs) pcrv['srcname'] = 'Crab' pcrv['caldb'] = self._caldb pcrv['irf'] = self._irf pcrv['phbinalg'] = 'LIN' pcrv['phbins'] = 2 pcrv['method'] = '3D' pcrv['enumbins'] = 0 pcrv['emin'] = 1.0 pcrv['emax'] = 100.0 pcrv['outfile'] = 'csphasecrv_py3.fits' pcrv['logfile'] = 'csphasecrv_py3.log' pcrv['chatter'] = 4 # Execute csphasecrv script pcrv.logFileOpen() # Make sure we get a log file pcrv.execute() # Check phase curve self._check_phase_curve('csphasecrv_py3.fits', 2) # Binned csphasecrv pcrv = cscripts.csphasecrv() pcrv['inobs'] = self._phased_events pcrv['inmodel'] = self._model pcrv['srcname'] = 'Crab' pcrv['caldb'] = self._caldb pcrv['irf'] = self._irf pcrv['phbinalg'] = 'LIN' pcrv['phbins'] = 2 pcrv['method'] = '3D' pcrv['emin'] = 1.0 pcrv['emax'] = 100.0 pcrv['enumbins'] = 2 pcrv['coordsys'] = 'CEL' pcrv['proj'] = 'TAN' pcrv['xref'] = 83.63 pcrv['yref'] = 22.01 pcrv['nxpix'] = 10 pcrv['nypix'] = 10 pcrv['binsz'] = 0.04 pcrv['outfile'] = 'csphasecrv_py4.fits' pcrv['logfile'] = 'csphasecrv_py4.log' pcrv['chatter'] = 4 # Execute csphasecrv script pcrv.logFileOpen() # Make sure we get a log file pcrv.execute() # Check phase curve self._check_phase_curve('csphasecrv_py4.fits', 2) # On/Off csphasecrv pcrv = cscripts.csphasecrv() pcrv['inobs'] = self._offaxis_events pcrv['inmodel'] = self._model_onoff pcrv['srcname'] = 'Crab' pcrv['caldb'] = self._caldb pcrv['irf'] = self._irf pcrv['phbinalg'] = 'LIN' pcrv['phbins'] = 2 pcrv['method'] = 'ONOFF' pcrv['statistic'] = 'WSTAT' pcrv['emin'] = 1.0 pcrv['emax'] = 100.0 pcrv['enumbins'] = 2 pcrv['coordsys'] = 'CEL' pcrv['xref'] = 83.63 pcrv['yref'] = 22.01 pcrv['rad'] = 0.2 pcrv['etruemin'] = 1.0 pcrv['etruemax'] = 100.0 pcrv['etruebins'] = 5 pcrv['outfile'] = 'csphasecrv_py5.fits' pcrv['logfile'] = 'csphasecrv_py5.log' pcrv['chatter'] = 4 # Execute csphasecrv script pcrv.logFileOpen() # Make sure we get a log file pcrv.execute() # Check phase curve self._check_phase_curve('csphasecrv_py5.fits', 2) # Set-up csphasecrv without multiprocessing pcrv = cscripts.csphasecrv() pcrv['inobs'] = self._phased_events pcrv['inmodel'] = self._model pcrv['srcname'] = 'Crab' pcrv['caldb'] = self._caldb pcrv['irf'] = self._irf pcrv['phbinalg'] = 'LIN' pcrv['phbins'] = 2 pcrv['method'] = '3D' pcrv['enumbins'] = 0 pcrv['emin'] = 1.0 pcrv['emax'] = 100.0 pcrv['outfile'] = 'csphasecrv_py6.fits' pcrv['logfile'] = 'csphasecrv_py6.log' pcrv['chatter'] = 2 pcrv['publish'] = True pcrv['nthreads'] = 1 # Run csphasecrv script and save phase curve pcrv.logFileOpen() # Make sure we get a log file pcrv.run() pcrv.save() # Check phase curve self._check_phase_curve('csphasecrv_py6.fits', 2) # Return return
def run(self): """ Run the script. Raises ------ RuntimeError Invalid pointing definition file format. """ # Switch screen logging on in debug mode if self._logDebug(): self._log.cout(True) # Get parameters self._get_parameters() # Write header into logger if self._logTerse(): self._log('\n') self._log.header1('Creating observation definition XML file') # Load pointing definition file if it is not already set if self._pntdef.size() == 0: self._pntdef = gammalib.GCsv(self['inpnt'].filename(), ',') ncols = self._pntdef.ncols() npnt = self._pntdef.nrows()-1 # Throw an exception is there is no header information if self._pntdef.nrows() < 1: raise RuntimeError('No header found in pointing definition file.') # Clear observation container self._obs.clear() identifier = 1 # Extract header from pointing definition file header = [] for col in range(ncols): header.append(self._pntdef[0,col]) # Loop over all pointings for pnt in range(npnt): # Set row index row = pnt + 1 # Create CTA observation obs = gammalib.GCTAObservation() # Set observation name if 'name' in header: name = self._pntdef[row, header.index('name')] else: name = 'None' obs.name(name) # Set identifier if 'id' in header: id_ = self._pntdef[row, header.index('id')] else: id_ = '%6.6d' % identifier identifier += 1 obs.id(id_) # Set pointing if 'ra' in header and 'dec' in header: ra = float(self._pntdef[row, header.index('ra')]) dec = float(self._pntdef[row, header.index('dec')]) pntdir = gammalib.GSkyDir() pntdir.radec_deg(ra,dec) elif 'lon' in header and 'lat' in header: lon = float(self._pntdef[row, header.index('lon')]) lat = float(self._pntdef[row, header.index('lat')]) pntdir = gammalib.GSkyDir() pntdir.lb_deg(lon,lat) else: raise RuntimeError('No (ra,dec) or (lon,lat) columns ' 'found in pointing definition file.') obs.pointing(gammalib.GCTAPointing(pntdir)) # Set response function if 'caldb' in header: caldb = self._pntdef[row, header.index('caldb')] else: caldb = self['caldb'].string() if 'irf' in header: irf = self._pntdef[row, header.index('irf')] else: irf = self['irf'].string() if caldb != '' and irf != '': obs = self._set_response(obs, caldb, irf) # Set deadtime correction factor if 'deadc' in header: deadc = float(self._pntdef[row, header.index('deadc')]) else: deadc = self['deadc'].real() obs.deadc(deadc) # Set Good Time Interval if 'duration' in header: duration = float(self._pntdef[row, header.index('duration')]) else: duration = self['duration'].real() tmin = self._tmin tmax = self._tmin + duration gti = gammalib.GGti(self._time_reference()) tstart = gammalib.GTime(tmin, self._time_reference()) tstop = gammalib.GTime(tmax, self._time_reference()) self._tmin = tmax gti.append(tstart, tstop) obs.ontime(gti.ontime()) obs.livetime(gti.ontime()*deadc) # Set Energy Boundaries has_emin = False has_emax = False if 'emin' in header: emin = float(self._pntdef[row, header.index('emin')]) has_emin = True else: if self['emin'].is_valid(): emin = self['emin'].real() has_emin = True if 'emax' in header: emax = float(self._pntdef[row, header.index('emax')]) has_emax = True else: if self['emax'].is_valid(): emax = self['emax'].real() has_emax = True has_ebounds = has_emin and has_emax if has_ebounds: ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, 'TeV'), gammalib.GEnergy(emax, 'TeV')) # Set ROI has_roi = False if 'rad' in header: rad = float(self._pntdef[row, header.index('rad')]) has_roi = True else: if self['rad'].is_valid(): rad = self['rad'].real() has_roi = True if has_roi: roi = gammalib.GCTARoi(gammalib.GCTAInstDir(pntdir), rad) # Create an empty event list list_ = gammalib.GCTAEventList() list_.gti(gti) # Set optional information if has_ebounds: list_.ebounds(ebounds) if has_roi: list_.roi(roi) # Attach event list to CTA observation obs.events(list_) # Write observation into logger if self._logExplicit(): self._log(str(obs)) self._log('\n') elif self._logTerse(): self._log(gammalib.parformat(obs.instrument()+' observation')) self._log('Name="'+obs.name()+'" ') self._log('ID="'+obs.id()+'"\n') # Append observation self._obs.append(obs) # Return return
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['Energy'] c_ed = table['ed_Energy'] c_eu = table['eu_Energy'] c_flux = table['Flux'] c_eflux = table['e_Flux'] c_ts = table['TS'] c_upper = table['UpperLimit'] # 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) flx = c_flux.real(row) e_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(c_flux.real(row)) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(c_eflux.real(row)) # ... otherwise append upper limit else: ul_energies.append(c_energy.real(row)) ul_flux.append(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
def _test_python(self): """ Test csobsdef from Python """ # Set-up csobsdef obsdef = cscripts.csobsdef() obsdef['inpnt'] = self._pntdef obsdef['outobs'] = 'csobsdef_py1.xml' obsdef['caldb'] = self._caldb obsdef['irf'] = self._irf obsdef['emin'] = 0.1 obsdef['emax'] = 100.0 obsdef['duration'] = 1800.0 obsdef['rad'] = 5.0 obsdef['logfile'] = 'csobsdef_py1.log' obsdef['chatter'] = 2 # Run csobsdef script and save XML file obsdef.logFileOpen() # Make sure we get a log file obsdef.run() obsdef.save() # Check model file self._check_obsdef_file('csobsdef_py1.xml') # Set-up csobsdef obsdef = cscripts.csobsdef() obsdef['inpnt'] = self._pntdef obsdef['outobs'] = 'csobsdef_py2.xml' obsdef['caldb'] = self._caldb obsdef['irf'] = self._irf obsdef['emin'] = 0.1 obsdef['emax'] = 100.0 obsdef['duration'] = 1800.0 obsdef['rad'] = 5.0 obsdef['logfile'] = 'csobsdef_py2.log' obsdef['chatter'] = 3 # Execute csobsdef script obsdef.execute() # Check model file self._check_obsdef_file('csobsdef_py2.xml') # Load CSV table csv = gammalib.GCsv(self._pntdef, ',') # Set-up csobsdef obsdef = cscripts.csobsdef() obsdef.pntdef(csv) obsdef['outobs'] = 'csobsdef_py3.xml' obsdef['caldb'] = self._caldb obsdef['irf'] = self._irf obsdef['emin'] = 0.1 obsdef['emax'] = 100.0 obsdef['duration'] = 1800.0 obsdef['rad'] = 5.0 obsdef['logfile'] = 'csobsdef_py3.log' obsdef['chatter'] = 4 # Execute csobsdef script obsdef.execute() # Check model file self._check_obsdef_file('csobsdef_py3.xml') # Return return
def showSpectrum(cfg, spectrum, show_butterfly=True): """ Generate spectrum (points + butterfly) """ outputdir = cfg.getValue('general', 'outputdir') if has_matplotlib == False: Utilities.warning('No matplotlib module ==> EXIT!!!') return ################################################################# ### Taken from $CTOOLS/share/examples/python/make_spectrum.py ### ################################################################# # Read spectrum file table = spectrum.table(1) c_energy = table["Energy"] c_ed = table["ed_Energy"] c_eu = table["eu_Energy"] c_flux = table["Flux"] c_eflux = table["e_Flux"] c_ts = table["TS"] c_upper = table["UpperLimit"] # Initialise arrays to be filled energies = [] flux = [] ed_engs = [] eu_engs = [] e_flux = [] ul_energies = [] ul_ed_engs = [] ul_eu_engs = [] ul_flux = [] # Loop over rows of the file nrows = table.nrows() for row in range(nrows): # Get TS ts = c_ts.real(row) flx = c_flux.real(row) e_flx = c_eflux.real(row) # Switch if ts > 9.0 and e_flx < flx: # Add information energies.append(c_energy.real(row)) flux.append(c_flux.real(row)) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(c_eflux.real(row)) # else: # Add information ul_energies.append(c_energy.real(row)) ul_flux.append(c_upper.real(row)) ul_ed_engs.append(c_ed.real(row)) ul_eu_engs.append(c_eu.real(row)) # Create figure plt.figure() plt.title("Crab spectrum") # Plot the spectrum plt.loglog() plt.grid() plt.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs], fmt='ro') if len(ul_energies) > 0: plt.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs], yerr=1.0e-11, uplims=True, fmt='ro') plt.xlabel("Energy (TeV)") plt.ylabel(r"dN/dE (erg cm$^{-2}$ s$^{-1}$)") if show_butterfly is True: ################################################################## ### Taken from $CTOOLS/share/examples/python/show_butterfly.py ### ################################################################## # Read given butterfly file filename = outputdir + '/' + cfg.getValue('ctbutterfly', 'output') csv = gammalib.GCsv(filename) # Initialise arrays to be filled butterfly_x = [] butterfly_y = [] line_x = [] line_y = [] # 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.e-6) # JLK MeV -> TeV # butterfly_y.append(csv.real(row,2)*1.e6) ## JLK MeV -> TeV scale = csv.real(row, 0) * csv.real(row, 0) * 1.e-6 * 1.6 # JLK MeV -> TeV -> erg butterfly_y.append(csv.real(row, 2) * scale) # Set line values line_x.append(csv.real(row, 0) * 1.e-6) # JLK MeV -> TeV line_y.append(csv.real(row, 1) * scale) # JLK MeV -> TeV -> erg # 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.e-6) # JLK MeV -> TeV scale = csv.real(index, 0) * csv.real(index, 0) * 1.e-6 * 1.6 low_error = csv.real(index, 3) * scale # JLK MeV -> TeV -> erg if low_error < 1e-26: low_error = 1e-26 butterfly_y.append(low_error) plt.fill(butterfly_x, butterfly_y, color='green', alpha=0.5) plt.plot(line_x, line_y, color='black', ls='-') plt.autoscale(tight=True) outputdir = cfg.getValue('general', 'outputdir') plt.savefig(outputdir + '/' + cfg.getValue('plots', 'spec_outfile'))
def plot_spectrum(specfile, butterfile1, butterfile2, ax, fmt='ro'): """ Plot sensitivity data Parameters ---------- specfile : str Name of spectrum FITS file butterfile1 : str Name of first butterfly text file butterfile2 : str Name of second butterfly text file ax : pyplot Subplot fmt : str Format string """ # Read spectrum file fits = gammalib.GFits(specfile) table = fits.table(1) c_energy = table['Energy'] c_ed = table['ed_Energy'] c_eu = table['eu_Energy'] c_flux = table['Flux'] c_eflux = table['e_Flux'] c_ts = table['TS'] c_upper = table['UpperLimit'] # Read butterfly files csv1 = gammalib.GCsv(butterfile1) csv2 = gammalib.GCsv(butterfile2) # Initialise arrays to be filled energies = [] flux = [] ed_engs = [] eu_engs = [] e_flux = [] ul_energies = [] ul_ed_engs = [] ul_eu_engs = [] ul_flux = [] butterfly1_x = [] butterfly1_y = [] butterfly2_x = [] butterfly2_y = [] line1_x = [] line1_y = [] line2_x = [] line2_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) flx = c_flux.real(row) e_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 > -99999.0 and e_flx < flx and e_flx > 0.0: energies.append(c_energy.real(row)) flux.append(c_flux.real(row)) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(c_eflux.real(row)) # ... otherwise append upper limit else: ul_energies.append(c_energy.real(row)) ul_flux.append(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 first butterfly file nrows = csv1.nrows() for row in range(nrows): # Limit values to positive value = csv1.real(row, 2) if value < 1e-40: value = 1e-40 # Compute upper edge of confidence band butterfly1_x.append(csv1.real(row, 0) / 1.0e6) # TeV butterfly1_y.append(value * csv1.real(row, 0) * csv1.real(row, 0) * gammalib.MeV2erg) # Set line values line1_x.append(csv1.real(row, 0) / 1.0e6) # TeV line1_y.append( csv1.real(row, 1) * csv1.real(row, 0) * csv1.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 butterfly1_x.append(csv1.real(index, 0) / 1.0e6) low_error = max( csv1.real(index, 3) * csv1.real(index, 0) * csv1.real(index, 0) * gammalib.MeV2erg, 1e-26) butterfly1_y.append(low_error) # Loop over rows of the second butterfly file nrows = csv2.nrows() for row in range(nrows): # Limit values to positive value = csv2.real(row, 2) if value < 1e-40: value = 1e-40 # Compute upper edge of confidence band butterfly2_x.append(csv2.real(row, 0) / 1.0e6) # TeV butterfly2_y.append(value * csv2.real(row, 0) * csv2.real(row, 0) * gammalib.MeV2erg) # Set line values line2_x.append(csv2.real(row, 0) / 1.0e6) # TeV line2_y.append( csv2.real(row, 1) * csv2.real(row, 0) * csv2.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 butterfly2_x.append(csv2.real(index, 0) / 1.0e6) low_error = max( csv2.real(index, 3) * csv2.real(index, 0) * csv2.real(index, 0) * gammalib.MeV2erg, 1e-26) butterfly2_y.append(low_error) # Plot the spectrum ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs], fmt=fmt, label='ctools') ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs], yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_') # Plot MSH 15-52 SED engs, ebins, flux, e_flux = msh_sed() ax.errorbar(engs, flux, yerr=e_flux, fmt='bo', label='Aharonian et al. (2005)') # Plot MSH 15-52 spectrum from Dubois (2009) dubois_x = [i * 0.1 + 0.2 for i in range(1000)] dubois_y = [] for x in dubois_x: y = 7.13e-12 * math.pow(x, -2.06) * math.exp(-x / 11.9) dubois_y.append(y * x * x * gammalib.MeV2erg * 1.0e6) ax.plot(dubois_x, dubois_y, color='blue', ls='-', label='Dubois (2009)') # Plot MSH 15-52 spectrum from HGPS #hgps_x = [i*0.1+0.2 for i in range(1000)] #hgps_y = [] #for x in hgps_x: # y = 6.859766e-12 * math.pow(x, -2.0507) * math.exp(-x/19.2) # hgps_y.append(y*x*x*gammalib.MeV2erg*1.0e6) #ax.plot(hgps_x, hgps_y, color='blue', ls='-', label='HGPS') # Plot the first butterfly ax.plot(line1_x, line1_y, color='red', ls='--') ax.fill(butterfly1_x, butterfly1_y, color='lightsalmon', alpha=0.5) # Plot the second butterfly ax.plot(line2_x, line2_y, color='red', ls='-') ax.fill(butterfly2_x, butterfly2_y, color='salmon', alpha=0.5) # Resort labels handles, labels = ax.get_legend_handles_labels() order = [1, 2, 0] # Add legend ax.legend([handles[idx] for idx in order], [labels[idx] for idx in order]) # Return return
def _test_python(self): """ Test cslightcrv from Python """ # Set-up unbinned cslightcrv lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'LIN' lcrv['tmin'] = 51544.50 lcrv['tmax'] = 51544.53 lcrv['tbins'] = 3 lcrv['enumbins'] = 0 lcrv['emin'] = 0.1 lcrv['emax'] = 100.0 lcrv['outfile'] = 'cslightcrv_py1.fits' lcrv['logfile'] = 'cslightcrv_py1.log' lcrv['chatter'] = 2 # Run cslightcrv script and save light curve lcrv.logFileOpen() # Make sure we get a log file lcrv.run() lcrv.save() # Check light curve self._check_light_curve('cslightcrv_py1.fits', 3) # Now use FILE as time bin algorithm. For this we need first to # create an ASCII file. We use now 6 time bins. The ASCII file # is saved into the file "lightcurve_py2.dat". csv = gammalib.GCsv(2, 2) tmin = 51544.50 tdelta = 0.01 for i in range(csv.nrows()): csv[i, 0] = '%.5f' % (tmin + i * tdelta) csv[i, 1] = '%.5f' % (tmin + (i + 1) * tdelta) csv.save('cslightcrv_py2.dat', ' ', True) # Set-up unbinned cslightcrv lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'FILE' lcrv['tbinfile'] = 'cslightcrv_py2.dat' lcrv['enumbins'] = 0 lcrv['emin'] = 0.1 lcrv['emax'] = 100.0 lcrv['fix_bkg'] = True lcrv['outfile'] = 'cslightcrv_py2.fits' lcrv['logfile'] = 'cslightcrv_py2.log' lcrv['chatter'] = 3 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py2.fits', 2) # Now we setup an observation container on input. We attached the # model to the observation container so that cslightcrv should # no longer query for the parameter. cta = gammalib.GCTAObservation(self._events) obs = gammalib.GObservations() obs.append(cta) obs.models(self._model) # Set-up unbinned cslightcrv from observation container. Now use # the GTI algorithm so that we test all timing algorithms. lcrv = cscripts.cslightcrv(obs) lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'GTI' lcrv['enumbins'] = 0 lcrv['emin'] = 0.1 lcrv['emax'] = 100.0 lcrv['outfile'] = 'cslightcrv_py3.fits' lcrv['logfile'] = 'cslightcrv_py3.log' lcrv['chatter'] = 4 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py3.fits', 1) # Finally we set-up a binned cslightcrv lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'LIN' lcrv['tmin'] = 51544.50 lcrv['tmax'] = 51544.53 lcrv['tbins'] = 2 lcrv['emin'] = 0.1 lcrv['emax'] = 100.0 lcrv['enumbins'] = 10 lcrv['coordsys'] = 'CEL' lcrv['proj'] = 'TAN' lcrv['xref'] = 83.63 lcrv['yref'] = 22.01 lcrv['nxpix'] = 20 lcrv['nypix'] = 20 lcrv['binsz'] = 0.02 lcrv['outfile'] = 'cslightcrv_py4.fits' lcrv['logfile'] = 'cslightcrv_py4.log' lcrv['chatter'] = 4 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py4.fits', 2) # Return return
# Script entry # # ============ # if __name__ == '__main__': # Check for given butterfly file if len(sys.argv) < 2: sys.exit('Usage: show_butterfly.py butterfly.txt [file]') # Check if plotting in file is requested plotfile = '' if len(sys.argv) == 3: plotfile = sys.argv[2] # Read given butterfly file filename = sys.argv[1] csv = gammalib.GCsv(filename) # Initialise arrays to be filled butterfly_x = [] butterfly_y = [] line_x = [] line_y = [] # 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)) butterfly_y.append(csv.real(row, 2))
def plot_spectrum(specfile, butterfile, ax, fmt='ro'): """ Plot sensitivity data Parameters ---------- specfile : str Name of spectrum FITS file butterfile : str Name of butterfly FITS file ax : plt Frame fmt : str, optional Format for ctools points """ # Read spectrum file fits = gammalib.GFits(specfile) table = fits.table(1) c_energy = table['Energy'] c_ed = table['ed_Energy'] c_eu = table['eu_Energy'] c_flux = table['Flux'] c_eflux = table['e_Flux'] c_ts = table['TS'] c_upper = table['UpperLimit'] # 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) flx = c_flux.real(row) e_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 > -99999.0 and e_flx < flx and e_flx > 0.0: energies.append(c_energy.real(row)) flux.append(c_flux.real(row)) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(c_eflux.real(row)) # ... otherwise append upper limit else: ul_energies.append(c_energy.real(row)) ul_flux.append(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): # Limit values to positive value = csv.real(row,2) if value < 1e-40: value = 1e-40 # Compute upper edge of confidence band butterfly_x.append(csv.real(row,0)/1.0e6) # TeV butterfly_y.append(value*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 PKS 2155-304 SED engs, pks, e_pks = pks_sed() ax.errorbar(engs, pks, yerr=e_pks, fmt='bo', label='Aharonian et al. (2009)') ax.errorbar([6.90492], [9.76439e-12], yerr=0.6*9.76439e-12, uplims=True, fmt='bo', label='_nolegend_') # Plot the spectrum ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs], fmt=fmt, label='ctools') ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs], yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_') # Plot the butterfly ax.plot(line_x, line_y, color='red',ls='-') ax.fill(butterfly_x, butterfly_y, color='salmon', alpha=0.5) # Resort labels handles, labels = ax.get_legend_handles_labels() order = [1,0] # Add legend ax.legend([handles[idx] for idx in order],[labels[idx] for idx in order], loc='upper right') # Return return
def _create_tbounds(self): """ Creates light curve time bins. The method reads the following user parameters: tbinalg: Time binning algorithm tbinfile: Time binning file (FITS or ASCII) tmin: Start time (MJD) tmax: Stop time (MJD) tbins: Number of time bins Returns: Light curve bins in form of a GTI. """ # Initialise Good Time Intervals gti = gammalib.GGti() # Get algorithm to use for defining the time intervals algorithm = self["tbinalg"].string() # Handle a FITS or a ASCII file for time bin definition if algorithm == "FILE": # Get the filename filename = self["tbinfile"].filename() # If the file a FITS file then load GTIs if filename.is_fits(): gti.load(filename) # ... otherwise load file as CSV ASCII file csv = gammalib.GCsv(filename) for i in range(csv.nrows()): tmin = gammalib.GTime() tmax = gammalib.GTime() tmin.mjd(csv.real(i, 0)) tmax.mjd(csv.real(i, 1)) gti.append(tmin, tmax) # Handle linear time binning elif algorithm == "LIN": # Get start and stop time and number of time bins time_min = self["tmin"].real() time_max = self["tmax"].real() nbins = self["tbins"].integer() # Compute time step and setup time intervals time_step = (time_max - time_min) / float(nbins) for i in range(nbins): tmin = gammalib.GTime() tmax = gammalib.GTime() tmin.mjd(time_min + i * time_step) tmax.mjd(time_min + (i + 1) * time_step) gti.append(tmin, tmax) # Handle usage of observation GTIs elif algorithm == "GTI": # Append the GTIs of all observations for obs in self._obs: for i in range(obs.events().gti().size()): gti.append(obs.events().gti().tstart(i), obs.events().gti().tstop(i)) # ... otherwise raise an exception (this should never occur) else: raise AttributeError('Paramter tbinalg="' + algorithm + '" unknown. ' 'Must be one of "FILE", "LIN" or "GTI".') # Return Good Time Intervals return gti
def run(self): """ Run the script Raises ------ RuntimeError Invalid pointing definition file format """ # Switch screen logging on in debug mode if self._logDebug(): self._log.cout(True) # Get parameters self._get_parameters() # Write header into logger self._log_header1(gammalib.TERSE, 'Creating observation definition XML file') # Load pointing definition file if it is not already set. Extract # the number of columns and pointings if self._pntdef.size() == 0: self._pntdef = gammalib.GCsv(self['inpnt'].filename(), ',') ncols = self._pntdef.ncols() npnt = self._pntdef.nrows() - 1 # Raise an exception if there is no header information if self._pntdef.nrows() < 1: raise RuntimeError('No header found in pointing definition file.') # Clear observation container self._obs.clear() # Initialise observation identifier counter identifier = 1 # Extract header columns from pointing definition file and put them # into a list header = [] for col in range(ncols): header.append(self._pntdef[0, col]) # Loop over all pointings for pnt in range(npnt): # Set pointing definition CSV file row index row = pnt + 1 # Create empty CTA observation obs = gammalib.GCTAObservation() # Set observation name. If no observation name was given then # use "None". if 'name' in header: name = self._pntdef[row, header.index('name')] else: name = self['name'].string() obs.name(name) # Set observation identifier. If no observation identified was # given the use the internal counter. if 'id' in header: obsid = self._pntdef[row, header.index('id')] else: obsid = '%6.6d' % identifier identifier += 1 obs.id(obsid) # Set pointing. Either use "ra" and "dec" or "lon" and "lat". # If none of these pairs are given then raise an exception. if 'ra' in header and 'dec' in header: ra = float(self._pntdef[row, header.index('ra')]) dec = float(self._pntdef[row, header.index('dec')]) pntdir = gammalib.GSkyDir() pntdir.radec_deg(ra, dec) elif 'lon' in header and 'lat' in header: lon = float(self._pntdef[row, header.index('lon')]) lat = float(self._pntdef[row, header.index('lat')]) pntdir = gammalib.GSkyDir() pntdir.lb_deg(lon, lat) else: raise RuntimeError('No (ra,dec) or (lon,lat) columns ' 'found in pointing definition file.') obs.pointing(gammalib.GCTAPointing(pntdir)) # Set response function. If no "caldb" or "irf" information is # provided then use the user parameter values. if 'caldb' in header: caldb = self._pntdef[row, header.index('caldb')] else: caldb = self['caldb'].string() if 'irf' in header: irf = self._pntdef[row, header.index('irf')] else: irf = self['irf'].string() if caldb != '' and irf != '': obs = self._set_irf(obs, caldb, irf) # Set deadtime correction factor. If no information is provided # then use the user parameter value "deadc". if 'deadc' in header: deadc = float(self._pntdef[row, header.index('deadc')]) else: deadc = self['deadc'].real() obs.deadc(deadc) # Set Good Time Interval. If no information is provided then use # the user parameter values "tmin" and "duration". if 'tmin' in header: self._tmin = float(self._pntdef[row, header.index('tmin')]) if 'duration' in header: duration = float(self._pntdef[row, header.index('duration')]) else: duration = self['duration'].real() tref = gammalib.GTimeReference(self['mjdref'].real(), 's') tmin = self._tmin tmax = self._tmin + duration gti = gammalib.GGti(tref) tstart = gammalib.GTime(tmin, tref) tstop = gammalib.GTime(tmax, tref) self._tmin = tmax gti.append(tstart, tstop) obs.ontime(gti.ontime()) obs.livetime(gti.ontime() * deadc) # Set Energy Boundaries. If no "emin" or "emax" information is # provided then use the user parameter values in case they are # valid. has_emin = False has_emax = False if 'emin' in header: emin = float(self._pntdef[row, header.index('emin')]) has_emin = True else: if self['emin'].is_valid(): emin = self['emin'].real() has_emin = True if 'emax' in header: emax = float(self._pntdef[row, header.index('emax')]) has_emax = True else: if self['emax'].is_valid(): emax = self['emax'].real() has_emax = True has_ebounds = has_emin and has_emax if has_ebounds: ebounds = gammalib.GEbounds(gammalib.GEnergy(emin, 'TeV'), gammalib.GEnergy(emax, 'TeV')) # Set ROI. If no ROI radius is provided then use the user # parameters "rad". has_roi = False if 'rad' in header: rad = float(self._pntdef[row, header.index('rad')]) has_roi = True else: if self['rad'].is_valid(): rad = self['rad'].real() has_roi = True if has_roi: roi = gammalib.GCTARoi(gammalib.GCTAInstDir(pntdir), rad) # Create an empty event list event_list = gammalib.GCTAEventList() event_list.gti(gti) # If available, set the energy boundaries and the ROI if has_ebounds: event_list.ebounds(ebounds) if has_roi: event_list.roi(roi) # Attach event list to CTA observation obs.events(event_list) # Write observation into logger name = obs.instrument() + ' observation' value = 'Name="%s" ID="%s"' % (obs.name(), obs.id()) self._log_value(gammalib.NORMAL, name, value) self._log_string(gammalib.EXPLICIT, str(obs) + '\n') # Append observation self._obs.append(obs) # Return return
def _create_tbounds(self): """ Creates light curve time bins Returns ------- gti : `~gammalib.GGti` Light curve bins in form of Good Time Intervals """ # Initialise Good Time Intervals gti = gammalib.GGti() # Get algorithm to use for defining the time intervals. Possible # values are "FILE", "LIN" and "GTI". This is enforced at # parameter file level, hence no checking is needed. algorithm = self['tbinalg'].string() # If the algorithm is "FILE" then handle a FITS or an ASCII file for # the time bin definition if algorithm == 'FILE': # Get the filename filename = self['tbinfile'].filename() # If the file a FITS file then load GTIs directly if filename.is_fits(): gti.load(filename) # ... otherwise load file the ASCII file as CSV file and construct # the GTIs from the rows of the CSV file. It is expected that the # CSV file has two columns containing the "START" and "STOP" # values of the time bins. No header row is expected. csv = gammalib.GCsv(filename) for i in range(csv.nrows()): tmin = gammalib.GTime() tmax = gammalib.GTime() tmin.mjd(csv.real(i, 0)) tmax.mjd(csv.real(i, 1)) gti.append(tmin, tmax) # If the algorithm is "LIN" then use a linear time binning, defined by # the "tmin", "tmax" and "tbins" user parameters elif algorithm == 'LIN': # Get start and stop time and number of time bins time_min = self['tmin'].time(ctools.time_reference) time_max = self['tmax'].time(ctools.time_reference) nbins = self['tbins'].integer() # Compute time step in seconds and setup the GTIs time_step = (time_max - time_min) / float(nbins) for i in range(nbins): tmin = time_min + i * time_step tmax = time_min + (i + 1) * time_step gti.append(tmin, tmax) # If the algorithm is "GTI" then extract the GTIs from the observations # in the container and use them for the light curve time binning elif algorithm == 'GTI': # Append the GTIs of all observations for obs in self.obs(): for i in range(obs.events().gti().size()): gti.append(obs.events().gti().tstart(i), obs.events().gti().tstop(i)) # Return Good Time Intervals return gti
def _test_python(self): """ Test cslightcrv from Python """ # Set-up unbinned cslightcrv lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'LIN' lcrv['tmin'] = '2020-01-01T00:00:00' lcrv['tmax'] = '2020-01-01T00:05:00' lcrv['tbins'] = 2 lcrv['method'] = '3D' lcrv['enumbins'] = 0 lcrv['emin'] = 1.0 lcrv['emax'] = 100.0 lcrv['outfile'] = 'cslightcrv_py1.fits' lcrv['logfile'] = 'cslightcrv_py1.log' lcrv['chatter'] = 2 lcrv['publish'] = True # Run cslightcrv script and save light curve lcrv.logFileOpen() # Make sure we get a log file lcrv.run() lcrv.save() # Check light curve self._check_light_curve('cslightcrv_py1.fits', 2) # Now use FILE as time bin algorithm. For this we need first to # create an ASCII file. We use now 2 time bins. The ASCII file # is saved into the file "lightcurve_py2.dat". csv = gammalib.GCsv(2, 2) tmin = 58849.00 tdelta = 0.0017361 for i in range(csv.nrows()): csv[i, 0] = '%.5f' % (tmin + i * tdelta) csv[i, 1] = '%.5f' % (tmin + (i + 1) * tdelta) csv.save('cslightcrv_py2.dat', ' ', True) # Set-up unbinned cslightcrv lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'FILE' lcrv['tbinfile'] = 'cslightcrv_py2.dat' lcrv['method'] = '3D' lcrv['enumbins'] = 0 lcrv['emin'] = 1.0 lcrv['emax'] = 100.0 lcrv['fix_bkg'] = True lcrv['outfile'] = 'cslightcrv_py2.fits' lcrv['logfile'] = 'cslightcrv_py2.log' lcrv['chatter'] = 3 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py2.fits', 2) # Now we setup an observation container on input. We attached the # model to the observation container so that cslightcrv should # no longer query for the parameter. cta = gammalib.GCTAObservation(self._events) obs = gammalib.GObservations() obs.append(cta) obs.models(self._model) # Set-up unbinned cslightcrv from observation container. Now use # the GTI algorithm so that we test all timing algorithms. lcrv = cscripts.cslightcrv(obs) lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'GTI' lcrv['method'] = '3D' lcrv['enumbins'] = 0 lcrv['emin'] = 1.0 lcrv['emax'] = 100.0 lcrv['outfile'] = 'cslightcrv_py3.fits' lcrv['logfile'] = 'cslightcrv_py3.log' lcrv['chatter'] = 4 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py3.fits', 1) # Binned cslightcrv lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'LIN' lcrv['tmin'] = '2020-01-01T00:00:00' lcrv['tmax'] = '2020-01-01T00:05:00' lcrv['tbins'] = 2 lcrv['method'] = '3D' lcrv['emin'] = 1.0 lcrv['emax'] = 100.0 lcrv['enumbins'] = 3 lcrv['coordsys'] = 'CEL' lcrv['proj'] = 'TAN' lcrv['xref'] = 83.63 lcrv['yref'] = 22.01 lcrv['nxpix'] = 10 lcrv['nypix'] = 10 lcrv['binsz'] = 0.04 lcrv['outfile'] = 'cslightcrv_py4.fits' lcrv['logfile'] = 'cslightcrv_py4.log' lcrv['chatter'] = 4 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py4.fits', 2) # cslightcrv with classical analysis lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._offaxis_events lcrv['inmodel'] = self._model_onoff lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'LIN' lcrv['tmin'] = '2020-01-01T00:00:00' lcrv['tmax'] = '2020-01-01T00:05:00' lcrv['tbins'] = 2 lcrv['method'] = 'ONOFF' lcrv['use_model_bkg'] = False # Needed even if WSTAT lcrv['emin'] = 1.0 lcrv['emax'] = 100.0 lcrv['enumbins'] = 2 lcrv['coordsys'] = 'CEL' lcrv['xref'] = 83.63 lcrv['yref'] = 22.01 lcrv['rad'] = 0.2 lcrv['etruemin'] = 1.0 lcrv['etruemax'] = 100.0 lcrv['etruebins'] = 5 lcrv['statistic'] = 'WSTAT' lcrv['outfile'] = 'cslightcrv_py5.fits' lcrv['logfile'] = 'cslightcrv_py5.log' lcrv['chatter'] = 4 # Execute cslightcrv script lcrv.execute() # Check light curve self._check_light_curve('cslightcrv_py5.fits', 2) # Set-up cslightcrv without multiprocessing lcrv = cscripts.cslightcrv() lcrv['inobs'] = self._events lcrv['inmodel'] = self._model lcrv['srcname'] = 'Crab' lcrv['caldb'] = self._caldb lcrv['irf'] = self._irf lcrv['tbinalg'] = 'LIN' lcrv['tmin'] = '2020-01-01T00:00:00' lcrv['tmax'] = '2020-01-01T00:05:00' lcrv['tbins'] = 2 lcrv['method'] = '3D' lcrv['enumbins'] = 0 lcrv['emin'] = 1.0 lcrv['emax'] = 100.0 lcrv['outfile'] = 'cslightcrv_py6.fits' lcrv['logfile'] = 'cslightcrv_py6.log' lcrv['chatter'] = 2 lcrv['publish'] = True lcrv['nthreads'] = 1 # Run cslightcrv script and save light curve lcrv.logFileOpen() # Make sure we get a log file lcrv.run() lcrv.save() # Check light curve self._check_light_curve('cslightcrv_py6.fits', 2) # Return return
def plot_spectrum(specfile, butterfile, ax, fmt='ro', color='green'): """ Plot sensitivity data Parameters ---------- specfile : str Name of spectrum FITS file butterfile : str Name of butterfly FITS file ax : pyplot Subplot fmt : str Format string color : str Color string """ # Read spectrum file fits = gammalib.GFits(specfile) table = fits.table(1) c_energy = table['Energy'] c_ed = table['ed_Energy'] c_eu = table['eu_Energy'] c_flux = table['Flux'] c_eflux = table['e_Flux'] c_ts = table['TS'] c_upper = table['UpperLimit'] # 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) flx = c_flux.real(row) e_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 > -99999.0 and e_flx < flx and e_flx > 0.0: energies.append(c_energy.real(row)) flux.append(c_flux.real(row)) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(c_eflux.real(row)) # ... otherwise append upper limit else: ul_energies.append(c_energy.real(row)) ul_flux.append(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): # Limit values to positive value = csv.real(row,2) if value < 1e-40: value = 1e-40 # Compute upper edge of confidence band butterfly_x.append(csv.real(row,0)/1.0e6) # TeV butterfly_y.append(value*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-20) butterfly_y.append(low_error) # Plot the spectrum ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs], fmt=fmt, label='ctools') ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs], yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_') # Plot Crab SED from Aharonian et al. (2006a) hess_x = [i*0.1+0.4 for i in range(400)] hess_y = [] for x in hess_x: y = 3.84e-11 * math.pow(x, -2.41) * math.exp(-x/15.1) hess_y.append(y*x*x*gammalib.MeV2erg*1.0e6) ax.plot(hess_x, hess_y, color='blue', ls='-', label='Aharonian et al. (2006a)') # Plot Crab SED from Nigro et al. (2019) nigro_x = [i*0.1+0.4 for i in range(400)] nigro_y = [] for x in nigro_x: y = 4.47e-11 * math.pow(x, -2.39 - 0.16 * math.log(x)) nigro_y.append(y*x*x*gammalib.MeV2erg*1.0e6) ax.plot(nigro_x, nigro_y, color='green', ls='-', label='Nigro et al. (2019)') # Plot the butterfly ax.plot(line_x, line_y, color='red', ls='-') ax.fill(butterfly_x, butterfly_y, color='salmon', alpha=0.5) # Resort labels handles, labels = ax.get_legend_handles_labels() order = [2,0,1] # Add legend ax.legend([handles[idx] for idx in order],[labels[idx] for idx in order]) # Return return
def plot_spectrum(specfile, butterfile, ax, fmt='ro', fermi=False): """ Plot sensitivity data Parameters ---------- specfile : str Name of spectrum FITS file butterfile : str Name of butterfly FITS file ax : pyplot Subplot fmt : str Format string """ # Read spectrum file fits = gammalib.GFits(specfile) table = fits.table(1) c_energy = table['Energy'] c_ed = table['ed_Energy'] c_eu = table['eu_Energy'] c_flux = table['Flux'] c_eflux = table['e_Flux'] c_ts = table['TS'] c_upper = table['UpperLimit'] # 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) flx = c_flux.real(row) e_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 > -99999.0 and e_flx < flx and e_flx > 0.0: energies.append(c_energy.real(row)) flux.append(c_flux.real(row)) ed_engs.append(c_ed.real(row)) eu_engs.append(c_eu.real(row)) e_flux.append(c_eflux.real(row)) # ... otherwise append upper limit else: ul_energies.append(c_energy.real(row)) ul_flux.append(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): # Limit values to positive value = csv.real(row,2) if value < 1e-40: value = 1e-40 # Compute upper edge of confidence band butterfly_x.append(csv.real(row,0)/1.0e6) # TeV butterfly_y.append(value*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 ax.errorbar(energies, flux, yerr=e_flux, xerr=[ed_engs, eu_engs], fmt=fmt, label='ctools') ax.errorbar(ul_energies, ul_flux, xerr=[ul_ed_engs, ul_eu_engs], yerr=yerr, uplims=True, fmt=fmt, label='_nolegend_') # Plot RX J1713 SED #engs, ergs, yerrs = rx_sed_2006() #engs, ergs, yerrs = rx_sed_2011() engs, ergs, yerrs = rx_sed_2018() ax.errorbar(engs, ergs, yerr=yerrs, fmt='bo', label='H.E.S.S. collaboration et al. (2018)') # Plot RX J1713 Fermi-LAT SED if fermi: engs, ergs, xerrs, yerrs = rx_fermi_sed_2018() ax.errorbar(engs, ergs, xerr=xerrs, yerr=yerrs, fmt='go', label='Fermi-LAT') # Plot spectral law from publication if fermi: abdalla_x = [i*0.001+0.001 for i in range(40000)] else: abdalla_x = [i*0.1+0.2 for i in range(400)] abdalla_y = [] for x in abdalla_x: y = 2.3e-11 * math.pow(x, -2.06) * math.exp(-x/12.9) abdalla_y.append(y*x*x*gammalib.MeV2erg*1.0e6) ax.plot(abdalla_x, abdalla_y, color='b', ls='-', label='_nolegend_') # Plot the butterfly ax.plot(line_x, line_y, color='red', ls='-') ax.fill(butterfly_x, butterfly_y, color='salmon', alpha=0.5) # Add legend ax.legend() # Return return