def main(): mev2erg = 1.6021765e-6 # MeV => erg input_model = sys.argv[1] models = gammalib.GModels(input_model) print(models) first_model = models[0] m_spect = first_model.spectral() print("TS:", first_model.ts()) emin = gammalib.GEnergy(25, 'GeV') emax = gammalib.GEnergy(150, 'TeV') r = m_spect.flux(emin, emax) er = m_spect.eflux(emin, emax) print('gl Flux: {:.4e} ph/cm²/s'.format(r)) print('fl EFlux: {:.4e} erg/cm²/s'.format(er)) for par in ['Prefactor', 'PivotEnergy', 'Index']: print(par, m_spect[par].value(), m_spect[par].error()) # pref = m_spect['Prefactor'].value() # print('pref', pref) print('my flux: {0:.4e} ph/cm²/s'.format( flux_eval_following_ctools([25 * 1e3, 150 * 1e6]))) my_eflux = eflux_eval_following_ctools( [25 * 1e3, 150 * 1e6]) #, m_spect['Prefactor'].value()) print('my eflux: {0:.4e} MeV/cm²/s => {1:.4e} erg/cm²/s'.format( my_eflux, my_eflux * mev2erg))
def flux_from_gammacat(cat, emin, emax=eup): # calculate integral flux in desired energy range from spectral model fluxes = np.array([]) for source in cat: try: flux = source.spectral_model().integral(emin * u.TeV, emax * u.TeV) fluxes = np.append(fluxes, flux.value) except: # sources without spectral model fluxes = np.append(fluxes, np.nan) # convert to Crab units # conversion consistent with utils for gammalib model containers # simple Crab TeV power law model crab = gammalib.GModelSpectralPlaw(5.7e-16, -2.48, gammalib.GEnergy(0.3, 'TeV')) # calculate crab flux over the desired energy range crab_flux = crab.flux(gammalib.GEnergy(emin, 'TeV'), gammalib.GEnergy(emax, 'TeV')) # remormalize crab flux so that it matches the Meyer model > 1 TeV (consistent with gamma-cat) crab_flux_1TeV = crab.flux(gammalib.GEnergy(1., 'TeV'), gammalib.GEnergy(eup, 'TeV')) # (Meyer model, flux > 1 TeV in ph cm-2 s-1) crab_flux *= 2.0744340476909142e-11 / crab_flux_1TeV fluxes /= crab_flux return fluxes
def generate_background_lookup(): """ Generate background lookup from empty field observations """ # Set filenames obsname = '$HESSDATA/obs/obs_off.xml' filename = 'off_lookup.fits' # Continue only if lookup table does not yet exist if not os.path.isfile(filename): # Initialise lookup table emin = gammalib.GEnergy(0.2, 'TeV') emax = gammalib.GEnergy(50.0, 'TeV') ebds = gammalib.GEbounds(10, emin, emax) lookup = gammalib.GCTAModelSpatialLookup(2.0, 0.2, ebds) # Load empty field observations obs = gammalib.GObservations(obsname) # Fill lookup table lookup.fill(obs) # Save lookup table lookup.save(filename, True) # Return return
def show_events(events, xmlname, duration, emin, emax, ebins=30): """ Show events using matplotlib. """ # Create figure plt.figure(1) plt.title("MC simulated event spectrum (" + str(emin) + '-' + str(emax) + " TeV)") # Setup energy range covered by data ebds = gammalib.GEbounds(ebins, gammalib.GEnergy(emin, "TeV"), gammalib.GEnergy(emax, "TeV")) # Create energy axis energy = [] for i in range(ebds.size()): energy.append(ebds.elogmean(i).TeV()) # Fill histogram counts = [0.0 for i in range(ebds.size())] for event in events: index = ebds.index(event.energy()) counts[index] = counts[index] + 1.0 # Create error bars error = [math.sqrt(c) for c in counts] # Get model values sum = 0.0 models = gammalib.GModels(xmlname) m = models[0] model = [] t = gammalib.GTime() for i in range(ebds.size()): eval = ebds.elogmean(i) ewidth = ebds.emax(i) - ebds.emin(i) f = m.npred(eval, t, obs) * ewidth.MeV() * duration sum += f model.append(f) print(str(sum) + " events expected from spectrum (integration).") # Plot data plt.loglog(energy, counts, 'ro') plt.errorbar(energy, counts, error, fmt=None, ecolor='r') # Plot model plt.plot(energy, model, 'b-') # Set axes plt.xlabel("Energy (TeV)") plt.ylabel("Number of events") # Notify print("PLEASE CLOSE WINDOW TO CONTINUE ...") # Show plot plt.show() # Return return
def compute_fluxes(spectral_model, emin_tev, emax_tev): e_min = gammalib.GEnergy(emin_tev, "TeV") e_max = gammalib.GEnergy(emax_tev, "TeV") ret = { "flux": spectral_model.flux(e_min, e_max), # ph/cm²/s "eflux": spectral_model.eflux(e_min, e_max), # erg/cm²/s } return ret
def add_source_info_spectral(spectral, row): row['spectral_type'] = spectral.type() emin = gammalib.GEnergy(1, 'TeV') emax = gammalib.GEnergy(10, 'TeV') flux = spectral.flux(emin, emax) flux_crab = flux row['int_flux_above_1TeV'] = flux
def compute_total_flux(models): flux_total = 0 for model in models: emin = gammalib.GEnergy(1, 'TeV') emax = gammalib.GEnergy(10, 'TeV') flux = model.spectral().flux(emin, emax) flux_total += flux return flux_total
def plot_spectrum(model, emin=0.01, emax=100.0, enumbins=100, plotfile=''): """ Plot spectral model component Parameters ---------- model : `~gammalib.GModel` Model emin : float, optional Minimum energy (TeV) emax : float, optional Maximum energy (TeV) enumbins : integer, optional Number of energy bins plotfile : str, optional Name of plot file """ # Get spectral component spectrum = model.spectral() # Setup energy axis e_min = gammalib.GEnergy(emin, 'TeV') e_max = gammalib.GEnergy(emax, 'TeV') ebounds = gammalib.GEbounds(enumbins, e_min, e_max) # Setup model plot x = [] y = [] min = 1.0e30 max = 0.0 for i in range(enumbins): energy = ebounds.elogmean(i) value = spectrum.eval(energy) if value > max: max = value if value < min: min = value x.append(energy.TeV()) y.append(value) # Show spectrum plt.figure() plt.title(model.name() + ' (' + spectrum.type() + ')') plt.loglog() plt.grid() plt.loglog(x, y, color='red') plt.xlabel('Energy (TeV)') plt.ylabel(r'dN/dE (ph s$^{-1}$ cm$^{-2}$ MeV$^{-1}$)') #plt.ylim([min,max]) # Show spectrum or save it into file if len(plotfile) > 0: plt.savefig(plotfile) else: plt.show() # Return return
def compute_effective_area_for_energy_interval(emin, emax, nbins=10): log_emin = emin.log10TeV() delta_e = emax.log10TeV() - log_emin log_e_bin = delta_e/nbins print('ene range: {}-{}\nEmin log10Tev: {}; delta: {}; Ebin: {}'.format(emin, emax, log_emin, delta_e, log_e_bin)) ref_min = g.GEnergy() ref_max = g.GEnergy() for n in np.arange(nbins): ref_min.log10(log_emin, 'TeV') ref_max.log10(log_emin+log_e_bin, 'TeV') area = compute_effective_area_at_minimum_and_max_energy(ref_min, ref_max, 10) print('{0} => {1:6.2f}-{2:6.2f} => {3:.2e} cm²'.format(n, ref_min.TeV(), ref_max.TeV(), area)) log_emin = ref_max.log10TeV()
def _get_parameters(self): """ Get user parameters from parfile """ # Set observation if not done before if self.obs().size() == 0: self.obs(self._set_obs(self['emin'].real(), self['emax'].real())) # Set observation statistic self._set_obs_statistic(gammalib.toupper(self['statistic'].string())) # Set models if we have none if self.obs().models().size() == 0: self.obs().models(self['inmodel'].filename()) # Get source name self._srcname = self['srcname'].string() # Read further parameters emin = self['emin'].real() emax = self['emax'].real() bins = self['bins'].integer() # Query parameters for binned if requested enumbins = self['enumbins'].integer() if not enumbins == 0: self['npix'].integer() self['binsz'].real() # Query input parameters self['sigma'].real() self['max_iter'].integer() self['type'].string() self['outfile'].filename() self['edisp'].boolean() self['debug'].boolean() # Derive some parameters self._ebounds = gammalib.GEbounds(bins, gammalib.GEnergy(emin, 'TeV'), gammalib.GEnergy(emax, 'TeV')) # Write input parameters into logger self._log_parameters(gammalib.TERSE) # Set number of processes for multiprocessing self._nthreads = mputils.nthreads(self) # Return return
def _get_parameters(self): """ Get user parameters from parfile. """ # Set observation if not done before if self._obs == None or self._obs.size() == 0: self._obs = self._set_obs() # Set models if we have none if self._obs.models().size() == 0: self._obs.models(self["inmodel"].filename()) # Get source name self._srcname = self["srcname"].string() # Read further parameters self._outfile = self["outfile"].filename() self._emin = self["emin"].real() self._emax = self["emax"].real() self._bins = self["bins"].integer() # Read parameters for binned if requested self._enumbins = self["enumbins"].integer() if not self._enumbins == 0: self._npix = self["npix"].integer() self._binsz = self["binsz"].real() # Read remaining parameters self._edisp = self["edisp"].boolean() self._ts_thres = self["sigma"].real() * self["sigma"].real() self._max_iter = self["max_iter"].integer() self._num_avg = self["num_avg"].integer() self._type = self["type"].string() # Set some fixed parameters self._debug = self["debug"].boolean() # Debugging in client tools # Derive some parameters self._ebounds = gammalib.GEbounds(self._bins, gammalib.GEnergy(self._emin, "TeV"), gammalib.GEnergy(self._emax, "TeV")) # Write input parameters into logger if self._logTerse(): self._log_parameters() self._log("\n") # Return return
def _get_crab_flux(self, emin, emax): """ Return Crab photon flux in a given energy interval Parameters ---------- emin : `~gammalib.GEnergy` Minimum energy emax : `~gammalib.GEnergy` Maximum energy Returns ------- flux : float Crab photon flux in specified energy interval (ph/cm2/s) """ # Set Crab TeV spectral model based on a power law crab = gammalib.GModelSpectralPlaw(5.7e-16, -2.48, gammalib.GEnergy(0.3, 'TeV')) # Determine photon flux flux = crab.flux(emin, emax) # Return photon flux return flux
def print_values_gammalib(): """Print some Gammalib model values that can be used for unit tests. Gammalib uses normalised PDFs, i.e. eval() returns probability / steradian so that the integral is one. """ import numpy as np import gammalib # We need some dummy variables center = gammalib.GSkyDir() center.radec_deg(0, 0) energy = gammalib.GEnergy() time = gammalib.GTime() FWHM_TO_SIGMA = 1. / np.sqrt(8 * np.log(2)) g = gammalib.GModelSpatialRadialGauss( center, PIX_TO_DEG * FWHM_TO_SIGMA * GAUSS_FWHM) d = gammalib.GModelSpatialRadialDisk(center, PIX_TO_DEG * DISK_R0) s = gammalib.GModelSpatialRadialShell(center, PIX_TO_DEG * SHELL_R0, PIX_TO_DEG * SHELL_WIDTH) models = [('g', g), ('d', d), ('s', s)] for name, model in models: for theta in THETAS: theta_radians = np.radians(PIX_TO_DEG * theta) gammalib_value = model.eval(theta_radians, energy, time) sherpa_value = INTEGRAL * gammalib_value * np.radians( PIX_TO_DEG)**2 print name, theta, sherpa_value
def add_background_model(obs): """ Add standard CTA background model to observations container. We use a simple power law here, scaled to Konrad's E configuration performance table. The model needs still to be validated. """ # Recover models from observation models = obs.models() # Define background model bgd_radial = gammalib.GCTAModelRadialGauss(3.0) bgd_spectrum = gammalib.GModelSpectralPlaw(61.8e-6, -1.85, gammalib.GEnergy(1.0, "TeV")) bgd_model = gammalib.GCTAModelRadialAcceptance(bgd_radial, bgd_spectrum) bgd_model.name("Background") bgd_model.instruments("CTA") # Add background model to container models.append(bgd_model) # Put container back in observation container obs.models(models) # Return observation container return obs
def cube_flux(model, emin, emax): # get data filename = model.spatial().filename().file() hdulist = fits.open(filename) cube = hdulist[0].data energies = hdulist[1].data['Energy'] binsize1 = np.abs(hdulist[0].header['CDELT1']) binsize2 = np.abs(hdulist[0].header['CDELT2']) # multiply by solid angle (only works for tangential projection or for reference latitude ~0) cube *= np.deg2rad(binsize1) * np.deg2rad(binsize2) fluxes = np.sum(cube, axis=(1, 2)) # correct by spectral model for s, energy in enumerate(energies): fluxes[s] *= model.spectral().eval( gammalib.GEnergy(np.double(energy), 'MeV')) # select energy range # emin, emax are in TeV and the energy vector in MeV # just select on bins, may be inaccurate close to threshold fluxes = fluxes[(energies >= 1.e6 * emin) & (energies <= 1.e6 * emax)] energies = energies[(energies >= 1.e6 * emin) & (energies <= 1.e6 * emax)] # integrate over energy in piece-wise power law approximation gamma = -(np.log(fluxes[1:]) - np.log(fluxes[:-1])) / ( np.log(energies[1:]) - np.log(energies[:-1])) # integral flux in individual bins between two nodes int = fluxes[:-1] * energies[:-1] / (-gamma + 1) * ( np.power(energies[1:] / energies[:-1], -gamma + 1) - 1) # sum over bins int = np.sum(int) return int
def generate_background_lookup(obslist=None, suffix=''): """ Generate background lookup from empty field observations Parameters ---------- obslist : list of int, optional Indices of observations to use suffix : str, optional Background lookup file suffix """ # Set filenames obsname = '$HESSDATA/obs/obs_off.xml' filename = 'bkg_lookup%s.fits' % suffix # Continue only if lookup table does not yet exist if not os.path.isfile(filename): # Initialise lookup table emin = gammalib.GEnergy(0.2, 'TeV') emax = gammalib.GEnergy(50.0, 'TeV') ebds = gammalib.GEbounds(10, emin, emax) lookup = gammalib.GCTAModelSpatialLookup(2.0, 0.2, ebds) # Load empty field observations obs = gammalib.GObservations(obsname) # If an observation list was specified then exclude observations # in list if obslist != None: newobs = gammalib.GObservations() for i, run in enumerate(obs): if i not in obslist: newobs.append(run) else: print('Exclude %s' % (run.id())) obs = newobs print('%d observations in lookup table' % (len(obs))) # Fill lookup table lookup.fill(obs) # Save lookup table lookup.save(filename, True) # Return return
def createobs(ra=86.171648, dec=-1.4774586, rad=5.0, emin=0.1, emax=100.0, duration=360000.0, deadc=0.95, ): obs = gammalib.GCTAObservation() # Set pointing direction pntdir = gammalib.GSkyDir() pntdir.radec_deg(ra, dec) pnt = gammalib.GCTAPointing() pnt.dir(pntdir) obs.pointing(pnt) # Set ROI roi = gammalib.GCTARoi() instdir = gammalib.GCTAInstDir() instdir.dir(pntdir) roi.centre(instdir) roi.radius(rad) # Set GTI gti = gammalib.GGti() start = gammalib.GTime(0.0) stop = gammalib.GTime(duration) gti.append(start, stop) # Set energy boundaries ebounds = gammalib.GEbounds() e_min = gammalib.GEnergy() e_max = gammalib.GEnergy() e_min.TeV(emin) e_max.TeV(emax) ebounds.append(e_min, e_max) # Allocate event list events = gammalib.GCTAEventList() events.roi(roi) events.gti(gti) events.ebounds(ebounds) obs.events(events) # Set ontime, livetime, and deadtime correction factor obs.ontime(duration) obs.livetime(duration * deadc) obs.deadc(deadc) # Return observation return obs
def bin2gammalib(filename, flux_thresh, outdir): data = open(filename).readlines() # convert phasogram to numpy array phasogram = np.genfromtxt(data[14:]) # only include model if peak in lightcurve is > threshold if np.max(phasogram[:, 2]) > flux_thresh: # final name num = int(data[0].split('#')[-1]) name = 'bin{:03d}'.format(num) # spatial model # read Galactic longitude lon = float(data[1].split(' ')[-1]) # Galactic latitude is random with Gaussian distribution with 95% containment at bmax lat = np.random.normal(0, bmax / 2) src_dir = gammalib.GSkyDir() src_dir.lb_deg(lon, lat) spatial = gammalib.GModelSpatialPointSource(src_dir) # spectral model # average flux in ph/cm2/s f0 = np.average(phasogram[:, 1]) # convert to differential flux at eref in ph/cm2/s/MeV n0 = (gamma - 1) * f0 / eref spectral = gammalib.GModelSpectralPlaw( n0, -gamma, gammalib.GEnergy(np.double(eref), 'MeV')) # orbital phase model # create phasogram file fname = 'phasecurve_' + name + '.fits' phasogram_file(phasogram, outdir + fname, outdir) # period in days per = float(data[4].split(' ')[-1]) # convert to frequency in s per *= 86400 f0 = 1 / per temporal = gammalib.GModelTemporalPhaseCurve( gammalib.GFilename(fname), t0, np.random.random(), # phase at t0 randomly drawn f0, 0., 0., # orbit is stable, no derivatives 1., True) # normalized so that spectral model represents average flux # assemble final model model = gammalib.GModelSky(spatial, spectral, temporal) model.name(name) else: # empty model lat = 0. model = gammalib.GModelSky() return model, lat
def flux_Crab(model, emin, emax): emin = gammalib.GEnergy(emin, 'TeV') emax = gammalib.GEnergy(emax, 'TeV') flux = model.spectral().flux(emin, emax) # convert to Crab units # Set Crab TeV spectral model based on a power law crab = gammalib.GModelSpectralPlaw(5.7e-16, -2.48, gammalib.GEnergy(0.3, 'TeV')) # calculate crab flux over the same energy range crab_flux = crab.flux(emin, emax) # remormalize crab flux so that it matches the Meyer model > 1 TeV (consistent with gamma-cat) crab_flux_1TeV = crab.flux(gammalib.GEnergy(1., 'TeV'), gammalib.GEnergy(1000., 'TeV')) # (Meyer model, flux > 1 TeV in ph cm-2 s-1) crab_flux *= 2.0744340476909142e-11 / crab_flux_1TeV flux /= crab_flux return flux
def dist_from_gammalib(models): #extracts flux, longitude and latitude distribution from gammalib model container fluxes = [] lons = [] lats = [] # energy boundaries for flux calculation emin = gammalib.GEnergy(1., 'TeV') emax = gammalib.GEnergy(1000, 'TeV') for model in models: src_dir = get_model_dir(model) lons.append(src_dir.l_deg()) lats.append(src_dir.b_deg()) flux = model.spectral().flux(emin, emax) # convert to Crab units (Meyer model, flux > 1 TeV in ph cm-2 s-1) flux /= 2.0744340476909142e-11 fluxes.append(flux) return lons, lats, fluxes
def crab_spec(): """ Set Crab spectrum based on MAGIC observations (Albert et al. 2008, ApJ, 674, 1037) """ # Set parameters spectrum = gammalib.GModelSpectralPlaw(5.7e-16, -2.48, gammalib.GEnergy(0.3, "TeV")) # Return spectrum return spectrum
def EnConv(energy, unit): # divide energy # 50.0*GeV ---> 50000.0 , if in MeV listEnergy = [0.0, 0.0] if (unit == "MeV"): listEnergy[0] = gammalib.GEnergy(float(energy.split('*')[0]), energy.split('*')[1]).MeV() listEnergy[1] = "1.0" elif (unit == "GeV"): listEnergy[0] = gammalib.GEnergy(float(energy.split('*')[0]), energy.split('*')[1]).GeV() listEnergy[1] = "1e3" elif (unit == "TeV"): listEnergy[0] = gammalib.GEnergy(float(energy.split('*')[0]), energy.split('*')[1]).TeV() listEnergy[1] = "1e6" else: print("Wrong Energy conversion! CHECK value " + energy) return listEnergy
def _set_obs_ebounds(self, emin, emax): """ Set energy boundaries for observation container. Sets the energy boundaries for all observations in the observation container. Args: emin: Minimum energy emax: Maximum energy """ # Loop over all observations in container for obs in self._obs: # Get observation energy boundaries obs_ebounds = obs.events().ebounds() # Get minimum and maximum energy obs_emin = obs_ebounds.emin() obs_emax = obs_ebounds.emax() # Case A: bin fully contained in observation ebounds if obs_emin <= emin and obs_emax >= emax: ebounds = gammalib.GEbounds(emin, emax) # Case B: bin fully outside of obs ebounds elif emax < obs_emin or emin > obs_emax: # Set zero range (inspired by ctselect) e0 = gammalib.GEnergy(0.0, "TeV") ebounds = gammalib.GEbounds(e0, e0) # Case C: bin partly overlapping with observation ebounds else: # Set energy range as obs ebounds were fully contained inside energy bin set_emin = emin set_emax = emax # Adjust energy bin to respect observation energy boundary if emin < obs_emin: set_emin = obs_emin if emax > obs_emax: set_emax = obs_emax #Set energy boundaries ebounds = gammalib.GEbounds(set_emin, set_emax) # Set energy boundaries obs.events().ebounds(ebounds) # Return return
def flux_Crab(model, Emin, Emax): emin = gammalib.GEnergy(Emin, 'TeV') emax = gammalib.GEnergy(Emax, 'TeV') # deal with special case of cubes if model.spatial().type() == 'DiffuseMapCube': # get cube flux flux = cube_flux(model, Emin, Emax) else: flux = model.spectral().flux(emin, emax) # convert to Crab units # Set Crab TeV spectral model based on a power law crab = gammalib.GModelSpectralPlaw(5.7e-16, -2.48, gammalib.GEnergy(0.3, 'TeV')) # calculate crab flux over the same energy range crab_flux = crab.flux(emin, emax) # remormalize crab flux so that it matches the Meyer model > 1 TeV (consistent with gamma-cat) crab_flux_1TeV = crab.flux(gammalib.GEnergy(1., 'TeV'), gammalib.GEnergy(1000., 'TeV')) # (Meyer model, flux > 1 TeV in ph cm-2 s-1) crab_flux *= 2.0744340476909142e-11 / crab_flux_1TeV flux /= crab_flux return flux
def plot_spectrum(model_file, emin=0.03, emax=150.0, enumbins=100): models = gammalib.GModels(model_file) spectral_model = models["Crab"].spectral() e_min = gammalib.GEnergy(emin, "TeV") e_max = gammalib.GEnergy(emax, "TeV") ebounds = gammalib.GEbounds(enumbins, e_min, e_max) x = [] y = [] for i in range(enumbins): energy = ebounds.elogmean(i) value = spectral_model.eval(energy) x.append(energy.TeV()) y.append(value) plt.figure() plt.title(models["Crab"].name() + " (" + spectral_model.type() + ")") plt.grid() plt.loglog(x, y, color="red") plt.xlabel("Energy (TeV)") plt.ylabel("dN/dE ph/cm²/s/MeV") plt.show()
def compute_fluxes(filename): import gammalib crab_integral_flux_1to10TeV = 2.5520883250253037e-11 models = gammalib.GModels(filename) fluxes = [] fluxes_cu = [] names = [] for model in models: #print(model) #import IPython;IPython.embed(); name = model.name() names.append(name) emin = gammalib.GEnergy(1, 'TeV') emax = gammalib.GEnergy(10, 'TeV') flux = model.spectral().flux(emin, emax) flux_cu = (flux / crab_integral_flux_1to10TeV) * 100 fluxes.append(flux) fluxes_cu.append(flux_cu) print(name, model.spectral(), flux, flux_cu, crab_integral_flux_1to10TeV) return names, fluxes, fluxes_cu
def plot_spectral_model(model, ax, plot_kwargs): energies = Energy.equal_log_spacing(emin=0.02, emax=100, unit='TeV', nbins=40) fluxes = [] for energy in energies: energy_gammalib = gammalib.GEnergy(energy.value, 'TeV') fluxes.append(model.eval(energy_gammalib)) dnde = u.Quantity(fluxes, 'cm-2 s-1 MeV-1') e2dnde = (energies**2 * dnde).to('erg cm-2 s-1') ax.plot(energies.value, e2dnde.value, **plot_kwargs)
def _set_obs_ebounds(self, emin, emax): """ Set energy boundaries for all observations in container Parameters ---------- emin : `~gammalib.GEnergy` Minimum energy emax : `~gammalib.GEnergy` Maximum energy """ # Loop over all observations in container for i, obs in enumerate(self.obs()): # Get energy boundaries of the observation obs_ebounds = self._obs_ebounds[i] # Get minimum and maximum energy of the observation obs_emin = obs_ebounds.emin() obs_emax = obs_ebounds.emax() # If [emin,emax] is fully contained in the observation energy range # the use [emin,emax] as energy boundaries if obs_emin <= emin and obs_emax >= emax: ebounds = gammalib.GEbounds(emin, emax) # ... otherwise, if [emin,emax] is completely outside the # observation energy range then set the energy boundaries to the # zero-width interval [0,0] elif emax < obs_emin or emin > obs_emax: e0 = gammalib.GEnergy(0.0, 'TeV') ebounds = gammalib.GEbounds(e0, e0) # ... otherwise, if [emin,emax] overlaps partially with the # observation energy range then set the energy boundaries to the # overlapping part else: # Set overlapping energy range set_emin = max(emin, obs_emin) set_emax = min(emax, obs_emax) # Set energy boundaries ebounds = gammalib.GEbounds(set_emin, set_emax) # Set the energy boundaries as the boundaries of the observation obs.events().ebounds(ebounds) # Return return
def compute_effective_area_at_minimum_and_max_energy(emin, emax, nbins=10): logE = emin.log10TeV() deltaE = emax.log10TeV() - logE logEbin = deltaE/nbins # print('energy range: {}-{}\nEmin log10Tev: {}; delta: {}; Ebin: {}'.format(emin, emax, logE, deltaE, logEbin)) area = 0 ref = g.GEnergy() for n in np.arange(nbins+1): a_max = aeff.max(logE, 0.0, 0.0) ref.log10TeV(logE) # ref.log10(logE, 'TeV') # print(" {0:2d} en: {1:5.2f} {2:6.2f} TeV, Aeff max: {3:.2e}".format(n, logE, ref.TeV(), a_max)) logE += logEbin if a_max > area: area = a_max return area*2
def _etrue_ebounds(self): """ Set true energy boundaries Returns ------- ebounds : `~gammalib.GEbounds()` True energy boundaries """ # Determine minimum and maximum energies emin = self._ebounds.emin() * 0.5 emax = self._ebounds.emax() * 1.2 if emin.TeV() < self['etruemin'].real(): emin = gammalib.GEnergy(self['etruemin'].real(), 'TeV') if emax.TeV() > self['etruemax'].real(): emax = gammalib.GEnergy(self['etruemax'].real(), 'TeV') # Determine number of energy bins n_decades = (emax.log10TeV() - emin.log10TeV()) n_bins = int(n_decades * float(self['etruebins'].integer()) + 0.5) if n_bins < 1: n_bins = 1 # Set energy boundaries ebounds = gammalib.GEbounds(n_bins, emin, emax) # Write header self._log_header1(gammalib.TERSE, 'True energy binning') # Log true energy bins for i in range(ebounds.size()): value = '%s - %s' % (str(ebounds.emin(i)), str(ebounds.emax(i))) self._log_value(gammalib.TERSE, 'Bin %d' % (i + 1), value) # Return energy boundaries return ebounds