def fit_point(self, model, energy_group, energy_ref): from gammapy.spectrum import SpectrumFit sherpa_model = model.to_sherpa() sherpa_model.gamma.freeze() fit = SpectrumFit(self.obs, sherpa_model) erange = energy_group.energy_range # TODO: Notice channels contained in energy_group fit.fit_range = erange.min, 0.9999 * erange.max log.debug("Calling Sherpa fit for flux point " " in energy range:\n{}".format(fit)) fit.fit() res = fit.global_result energy_err_hi = energy_group.energy_range.max - energy_ref energy_err_lo = energy_ref - energy_group.energy_range.min diff_flux = res.model(energy_ref).to("m-2 s-1 TeV-1") err = res.model_with_uncertainties(energy_ref.to("TeV").value) diff_flux_err = err.s * u.Unit("m-2 s-1 TeV-1") return OrderedDict( energy=energy_ref, energy_err_hi=energy_err_hi, energy_err_lo=energy_err_lo, diff_flux=diff_flux, diff_flux_err_hi=diff_flux_err, diff_flux_err_lo=diff_flux_err, )
def fit_point(self, model, energy_group, energy_ref): from gammapy.spectrum import SpectrumFit fit = SpectrumFit(self.obs, model) erange = energy_group.energy_range # TODO: Notice channels contained in energy_group fit.fit_range = erange.min, erange.max log.debug('Calling Sherpa fit for flux point ' ' in energy range:\n{}'.format(fit)) fit.fit() fit.est_errors() # First result contain correct model res = fit.result[0] e_max = energy_group.energy_range.max e_min = energy_group.energy_range.min diff_flux, diff_flux_err = res.model.evaluate_error(energy_ref) return OrderedDict( e_ref=energy_ref, e_min=e_min, e_max=e_max, dnde=diff_flux.to('m-2 s-1 TeV-1'), dnde_err=diff_flux_err.to('m-2 s-1 TeV-1'), )
def fit_point(self, model, energy_group, energy_ref): from gammapy.spectrum import SpectrumFit sherpa_model = model.to_sherpa() sherpa_model.gamma.freeze() fit = SpectrumFit(self.obs, sherpa_model) erange = energy_group.energy_range # TODO: Notice channels contained in energy_group fit.fit_range = erange.min, 0.9999 * erange.max log.debug( 'Calling Sherpa fit for flux point ' ' in energy range:\n{}'.format(fit) ) fit.fit() res = fit.global_result energy_err_hi = energy_group.energy_range.max - energy_ref energy_err_lo = energy_ref - energy_group.energy_range.min diff_flux = res.model(energy_ref).to('m-2 s-1 TeV-1') err = res.model_with_uncertainties(energy_ref.to('TeV').value) diff_flux_err = err.s * Unit('m-2 s-1 TeV-1') return OrderedDict( energy=energy_ref, energy_err_hi=energy_err_hi, energy_err_lo=energy_err_lo, diff_flux=diff_flux, diff_flux_err_hi=diff_flux_err, diff_flux_err_lo=diff_flux_err, )
def fit_point(self, model, energy_group, energy_ref): from gammapy.spectrum import SpectrumFit # TODO: The code below won't work because SpectrumFit only accepts # gammapy models. Add Parameter class to freeze index # sherpa_model = model.to_sherpa() # sherpa_model.gamma.freeze() #fit = SpectrumFit(self.obs, sherpa_model) fit = SpectrumFit(self.obs, model) erange = energy_group.energy_range # TODO: Notice channels contained in energy_group fit.fit_range = erange.min, 0.9999 * erange.max log.debug('Calling Sherpa fit for flux point ' ' in energy range:\n{}'.format(fit)) fit.fit() fit.est_errors() # First result contain correct model res = fit.result[0] e_max = energy_group.energy_range.max e_min = energy_group.energy_range.min diff_flux, diff_flux_err = res.model.evaluate_error(energy_ref) return OrderedDict( e_ref=energy_ref, e_min=e_min, e_max=e_max, dnde=diff_flux.to('m-2 s-1 TeV-1'), dnde_err=diff_flux_err.to('m-2 s-1 TeV-1'), )
print(pwl) # In[ ]: livetime = 2 * u.h sim = SpectrumSimulation(aeff=aeff, edisp=edisp, source_model=pwl, livetime=livetime) sim.simulate_obs(seed=2309, obs_id=1) print(sim.obs) # In[ ]: fit = SpectrumFit(obs_list=sim.obs, model=pwl.copy(), stat="cash") fit.fit_range = [1, 10] * u.TeV fit.run() print(fit.result[0]) # ## Include background # # In this section we will include a background component. Furthermore, we will also simulate more than one observation and fit each one individuallt in order to get average fit results. # In[ ]: bkg_model = PowerLaw(index=2.5, amplitude=1e-11 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV) # In[ ]:
# Fix index fit.model.gamma.freeze() # Fit norm in bands diff_flux = list() diff_flux_err = list() e_err_hi = list() e_err_lo = list() energy = list() for ii in range(len(binning) - 1): energ = np.sqrt(binning[ii] * binning[ii + 1]) energy.append(energ) e_err_hi.append(binning[ii + 1]) e_err_lo.append(binning[ii]) fit.fit_range = binning[[ii, ii + 1]] fit.run() res = fit.result[0].fit diff_flux.append(res.model(energ).to('cm-2 s-1 TeV-1')) err = res.model_with_uncertainties(energ.to('keV').value) diff_flux_err.append(err.s * u.Unit('cm-2 s-1 keV-1')) table = Table() table['e_ref'] = energy table['e_min'] = e_err_lo table['e_max'] = e_err_hi table['dnde'] = diff_flux table['dnde_err'] = diff_flux_err points = FluxPoints(table) result = SpectrumResult(fit=best_fit, points=points)
# Fix index fit.model.gamma.freeze() # Fit norm in bands diff_flux = list() diff_flux_err = list() e_err_hi = list() e_err_lo = list() energy = list() for ii in range(len(binning)-1): energ= np.sqrt(binning[ii] * binning[ii+1]) energy.append(energ) e_err_hi.append(binning[ii+1] - energ) e_err_lo.append(energ - binning[ii]) fit.fit_range = binning[[ii,ii+1]] fit.run() res = fit.result[0].fit diff_flux.append(res.model(energ).to('cm-2 s-1 TeV-1')) err = res.model_with_uncertainties(energ.to('keV').value) diff_flux_err.append(err.s * u.Unit('cm-2 s-1 keV-1')) points = DifferentialFluxPoints.from_arrays(energy=energy, diff_flux=diff_flux, diff_flux_err_hi=diff_flux_err, diff_flux_err_lo=diff_flux_err, energy_err_hi = e_err_hi, energy_err_lo = e_err_lo) result = SpectrumResult(fit=best_fit, points=points) result.plot_spectrum() plt.savefig('fluxpoints.png')
def compute(cls, model, obs_list, binning): """Compute differential fluxpoints The norm of the global model is fit to the `~gammapy.spectrum.SpectrumObservationList` in the provided energy binning and the differential flux is evaluated at the log bin center. TODO : Add upper limit calculation Parameters ---------- model : `~gammapy.spectrum.models.SpectralModel` Global model obs_list : `~gammapy.spectrum.SpectrumObservationList` Observations binning : `~astropy.units.Quantity` Energy binning, see :func:`~gammapy.spectrum.utils.calculate_flux_point_binning` for a method to get flux points with a minimum significance. """ from gammapy.spectrum import SpectrumFit binning = EnergyBounds(binning) low_bins = binning.lower_bounds high_bins = binning.upper_bounds diff_flux = list() diff_flux_err = list() e_err_hi = list() e_err_lo = list() energy = list() from ..spectrum import models, powerlaw from sherpa.models import PowLaw1D if isinstance(model, models.PowerLaw): temp = model.to_sherpa() temp.gamma.freeze() sherpa_models = [temp] * binning.nbins else: sherpa_models = [None] * binning.nbins for low, high, sherpa_model in zip(low_bins, high_bins, sherpa_models): log.info('Computing flux points in bin [{}, {}]'.format(low, high)) # Make PowerLaw approximation for higher order models if sherpa_model is None: flux_low = model(low) flux_high = model(high) index = powerlaw.power_law_g_from_points(e1=low, e2=high, f1=flux_low, f2=flux_high) log.debug('Approximated power law index: {}'.format(index)) sherpa_model = PowLaw1D('powlaw1d.default') sherpa_model.gamma = index sherpa_model.gamma.freeze() sherpa_model.ref = model.parameters.reference.to('keV') sherpa_model.ampl = 1e-20 fit = SpectrumFit(obs_list, sherpa_model) # If 'low' or 'high' fall onto a bin edge of the # SpectrumObservation binning, numerical fluctuations can lead to # the inclusion of unwanted bins correction = 1e-5 fit.fit_range = ((1 + correction) * low, (1 - correction) * high) fit.fit() res = fit.global_result bin_center = np.sqrt(low * high) energy.append(bin_center) e_err_hi.append(high - bin_center) e_err_lo.append(bin_center - low) diff_flux.append(res.model(bin_center).to('m-2 s-1 TeV-1')) err = res.model_with_uncertainties(bin_center.to('TeV').value) diff_flux_err.append(err.s * Unit('m-2 s-1 TeV-1')) return cls.from_arrays(energy=energy, diff_flux=diff_flux, diff_flux_err_hi=diff_flux_err, diff_flux_err_lo=diff_flux_err, energy_err_hi=e_err_hi, energy_err_lo=e_err_lo)