.. include:: ../references.txt .. _spectral_fitting: **************** Spectral Fitting **************** .. currentmodule:: gammapy.spectrum In the following you will see how to fit spectral data in OGIP format. The format is described at :ref:`gadf:ogip`. An example dataset is available in the ``$GAMMAPY_DATA`` repo. For a description of the available fit statstics see :ref:`fit-statistics`. Getting Started =============== The following example shows how to fit a power law simultaneously to two simulated crab runs using the `~gammapy.spectrum.SpectrumFit` class. .. code-block:: python from gammapy.spectrum import SpectrumObservation, SpectrumObservationList, SpectrumFit from gammapy.spectrum.models import PowerLaw import matplotlib.pyplot as plt path = "$GAMMAPY_DATA/joint-crab/spectra/hess/" obs1 = SpectrumObservation.read(path + "pha_obs23523.fits") obs2 = SpectrumObservation.read(path + "pha_obs23592.fits") obs_list = SpectrumObservationList([obs1, obs2]) model = PowerLaw( index=2, amplitude='1e-12 cm-2 s-1 TeV-1', reference='1 TeV', ) fit = SpectrumFit(obs_list=obs_list, model=model, stat='wstat') result = fit.run() You can check the fit results by looking at `~gammapy.spectrum.SpectrumFitResult` that is attached to the `~gammapy.spectrum.SpectrumFit` for each observation. .. code-block:: python >>> print(result) FitResult backend : minuit method : minuit success : True nfev : 99 total stat : 63.00 message : Optimization terminated successfully. >>> print(fit.result[0]) Fit result info --------------- Model: PowerLaw Parameters: name value error unit min max --------- --------- --------- --------------- --------- --- index 2.761e+00 1.094e-01 nan nan amplitude 5.118e-11 4.849e-12 1 / (cm2 s TeV) nan nan reference 1.000e+00 0.000e+00 TeV 0.000e+00 nan Covariance: name index amplitude reference --------- ---------------------- ---------------------- --------- index 0.011973084948262436 3.3890114528842897e-13 0.0 amplitude 3.3890114528842897e-13 2.3510477262284227e-23 0.0 reference 0.0 0.0 0.0 Statistic: 21.076 (wstat) Fit Range: [8.79922544e+08 1.00000000e+11] keV Interactive Sherpa Fit ====================== If you want to do something specific that is not handled by the `~gammapy.spectrum.SpectrumFit` class you can always fit the PHA data directly using `Sherpa`_. The following example illustrates how to do this with the example dataset used above. It makes use of the Sherpa `datastack module `_. .. code-block:: python from sherpa.astro import datastack from sherpa.models import PowLaw1D from gammapy.extern.pathlib import Path import os pha1 = str(Path(os.environ["GAMMAPY_DATA"]) / "joint-crab" / "spectra" / "hess" / "pha_obs23592.fits") pha2 = str(Path(os.environ["GAMMAPY_DATA"]) / "joint-crab" / "spectra" / "hess" / "pha_obs23523.fits") phalist = ','.join([pha1, pha2]) ds = datastack.DataStack() ds.load_pha(phalist) model = PowLaw1D('powlaw1d.default') model.ampl = 1 model.ref = 1e9 model.gamma = 2 ds.set_source(model*1e-20) for i in range(1, len(ds.datasets) + 1): datastack.ignore_bad(i) datastack.ignore_bad(i, 1) datastack.set_stat('wstat') ds.fit() datastack.covar() This should give the following output .. code-block:: text Datasets = 1, 2 Method = levmar Statistic = wstat Initial fit statistic = 250.031 Final fit statistic = 63.0023 at function evaluation 25 Data points = 74 Degrees of freedom = 72 Probability [Q-value] = 0.766494 Reduced statistic = 0.875031 Change in statistic = 187.029 powlaw1d.default.gamma 2.76099 +/- 0.118197 powlaw1d.default.ampl 5.11739 +/- 0.491756 Datasets = 1, 2 Confidence Method = covariance Iterative Fit Method = None Fitting Method = levmar Statistic = wstat covariance 1-sigma (68.2689%) bounds: Param Best-Fit Lower Bound Upper Bound ----- -------- ----------- ----------- powlaw1d.default.gamma 2.76099 -0.109432 0.109432 powlaw1d.default.ampl 5.11739 -0.484906 0.484906