def setUp(self): self._old_logger_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) from sherpa.astro.io import read_pha from sherpa.astro import xspec # Ensure we have a known set of XSPEC settings. # At present this is just the abundance and cross-section, # since the cosmology settings do not affect any of the # models used here. # self._xspec_settings = { 'abund': xspec.get_xsabund(), 'xsect': xspec.get_xsxsect() } xspec.set_xsabund('angr') xspec.set_xsxsect('bcmc') pha_fname = self.make_path("9774.pi") self.data = read_pha(pha_fname) self.data.notice(0.5, 7.0) bkg_fname = self.make_path("9774_bg.pi") self.bkg = read_pha(bkg_fname) abs1 = xspec.XSphabs('abs1') p1 = PowLaw1D('p1') self.model = abs1 + p1 self.model_mult = abs1 * p1 pi2278 = self.make_path("pi2278.fits") pi2286 = self.make_path("pi2286.fits") self.data_pi2278 = read_pha(pi2278) self.data_pi2286 = read_pha(pi2286)
def setup(): data = Data1D('fake', _x, _y, _err) g1 = Gauss1D('g1') g1.fwhm.set(1.0, _tiny, _max, frozen=False) g1.pos.set(1.0, -_max, _max, frozen=False) g1.ampl.set(1.0, -_max, _max, frozen=False) p1 = PowLaw1D('p1') p1.gamma.set(1.0, -10, 10, frozen=False) p1.ampl.set(1.0, 0.0, _max, frozen=False) p1.ref.set(1.0, -_max, _max, frozen=True) model = p1 + g1 method = LevMar() method.config['maxfev'] = 10000 method.config['ftol'] = float(_eps) method.config['epsfcn'] = float(_eps) method.config['gtol'] = float(_eps) method.config['xtol'] = float(_eps) method.config['factor'] = float(100) fit = Fit(data, model, Chi2DataVar(), method, Covariance()) results = fit.fit() for key in ["succeeded", "numpoints", "nfev"]: assert _fit_results_bench[key] == int(getattr(results, key)) for key in ["rstat", "qval", "statval", "dof"]: # used rel and abs tol of 1e-7 with numpy allclose assert float(getattr(results, key)) == pytest.approx(_fit_results_bench[key]) for key in ["parvals"]: try: # used rel and abs tol of 1e-4 with numpy allclose assert getattr(results, key) == pytest.approx(_fit_results_bench[key]) except AssertionError: print('parvals bench: ', _fit_results_bench[key]) print('parvals fit: ', getattr(results, key)) print('results', results) raise fields = [ 'data', 'model', 'method', 'fit', 'results', 'covresults', 'dof', 'mu', 'num' ] out = namedtuple('Results', fields) out.data = data out.model = model out.method = method out.fit = fit out.results = results out.covresults = fit.est_errors() out.dof = results.dof out.mu = numpy.array(results.parvals) out.cov = numpy.array(out.covresults.extra_output) out.num = 10 return out
def setup_two(make_data_path): from sherpa.astro.io import read_pha, read_arf, read_rmf from sherpa.astro import xspec abs1 = xspec.XSphabs('abs1') p1 = PowLaw1D('p1') model = abs1 * p1 * 1e-4 pi2278 = make_data_path("pi2278.fits") pi2286 = make_data_path("pi2286.fits") data_pi2278 = read_pha(pi2278) data_pi2286 = read_pha(pi2286) data_pi2278.set_rmf(read_rmf(make_data_path('rmf2278.fits'))) data_pi2278.set_arf(read_arf(make_data_path('arf2278.fits'))) data_pi2286.set_rmf(read_rmf(make_data_path('rmf2286.fits'))) data_pi2286.set_arf(read_arf(make_data_path('arf2286.fits'))) rsp_pi2278 = Response1D(data_pi2278) rsp_pi2286 = Response1D(data_pi2286) return { 'data_pi2278': data_pi2278, 'data_pi2286': data_pi2286, 'model_pi2278': rsp_pi2278(model), 'model_pi2286': rsp_pi2286(model) }
def test_sherpa_fit(self, tmpdir): # this is to make sure that the written PHA files work with sherpa import sherpa.astro.ui as sau from sherpa.models import PowLaw1D # TODO: this works a little bit, but some info and warnings # from Sherpa remain. Not sure what to do, OK as-is for now. import logging logging.getLogger("sherpa").setLevel("ERROR") for obs in self.obs_list: obs.to_ogip_files(str(tmpdir), use_sherpa=True) filename = tmpdir / "pha_obs23523.fits" sau.load_pha(str(filename)) sau.set_stat("wstat") model = PowLaw1D("powlaw1d.default") model.ref = 1e9 model.ampl = 1 model.gamma = 2 sau.set_model(model * 1e-20) sau.fit() assert_allclose(model.pars[0].val, 2.732, rtol=1e-3) assert_allclose(model.pars[2].val, 4.647, rtol=1e-3)
def setup_bkg(make_data_path): from sherpa.astro.io import read_pha, read_arf, read_rmf from sherpa.astro import xspec infile = make_data_path("9774_bg.pi") bkg = read_pha(infile) bkg.exposure = 1 arf = read_arf(make_data_path('9774.arf')) rmf = read_rmf(make_data_path('9774.rmf')) bkg.set_arf(arf) bkg.set_rmf(rmf) bkg.set_analysis('energy') bkg.notice(0.5, 7.0) # We stay with a linear scale for the absorption model # here as the values don't seem to go below 0.1. # abs1 = xspec.XSwabs('abs1') p1 = PowLaw1D('p1') model = abs1 * p1 p1.ampl = 1e-4 rsp = Response1D(bkg) return {'bkg': bkg, 'model': rsp(model)}
def test_warning(self): ui.load_ascii_with_errors(1, self.gro_fname) data = ui.get_data(1) powlaw1d = PowLaw1D('p1') ui.set_model(powlaw1d) fit = Fit(data, powlaw1d) results = fit.fit() with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") ui.resample_data(1, 3) assert len(w) == 0
def test_warning(make_data_path): infile = make_data_path('gro.txt') ui.load_ascii_with_errors(1, infile) powlaw1d = PowLaw1D('p1') ui.set_model(powlaw1d) ui.fit() with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") ui.resample_data(1, 3) assert len(w) == 0
def setUp(self): data = Data1D('fake', self._x, self._y, self._err) g1 = Gauss1D('g1') g1.fwhm.set(1.0, _tiny, _max, frozen=False) g1.pos.set(1.0, -_max, _max, frozen=False) g1.ampl.set(1.0, -_max, _max, frozen=False) p1 = PowLaw1D('p1') p1.gamma.set(1.0, -10, 10, frozen=False) p1.ampl.set(1.0, 0.0, _max, frozen=False) p1.ref.set(1.0, -_max, _max, frozen=True) model = p1 + g1 method = LevMar() method.config['maxfev'] = 10000 method.config['ftol'] = float(_eps) method.config['epsfcn'] = float(_eps) method.config['gtol'] = float(_eps) method.config['xtol'] = float(_eps) method.config['factor'] = float(100) self.fit = Fit(data, model, Chi2DataVar(), method, Covariance()) results = self.fit.fit() for key in ["succeeded", "numpoints", "nfev"]: assert self._fit_results_bench[key] == int(getattr(results, key)) for key in ["rstat", "qval", "statval", "dof"]: assert numpy.allclose(float(self._fit_results_bench[key]), float(getattr(results, key)), 1.e-7, 1.e-7) for key in ["parvals"]: try: assert numpy.allclose(self._fit_results_bench[key], getattr(results, key), 1.e-4, 1.e-4) except AssertionError: print('parvals bench: ', self._fit_results_bench[key]) print('parvals fit: ', getattr(results, key)) print('results', results) raise covresults = self.fit.est_errors() self.dof = results.dof self.mu = numpy.array(results.parvals) self.cov = numpy.array(covresults.extra_output) self.num = 10
def test_sherpa_fit(tmpdir): # this is to make sure that the written PHA files work with sherpa pha1 = gammapy_extra.filename("datasets/hess-crab4_pha/pha_obs23592.fits") import sherpa.astro.ui as sau from sherpa.models import PowLaw1D sau.load_pha(pha1) sau.set_stat('wstat') model = PowLaw1D('powlaw1d.default') model.ref = 1e9 model.ampl = 1 model.gamma = 2 sau.set_model(model * 1e-20) sau.fit() assert_allclose(model.pars[0].val, 2.0281484215403616, atol=1e-4) assert_allclose(model.pars[2].val, 2.3528406790143097, atol=1e-4)
def setUp(self): self._old_logger_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) from sherpa.astro.xspec import XSphabs from sherpa.astro.io import read_pha pha_fname = self.make_path("9774.pi") self.data = read_pha(pha_fname) self.data.notice(0.5, 7.0) bkg_fname = self.make_path("9774_bg.pi") self.bkg = read_pha(bkg_fname) abs1 = XSphabs('abs1') p1 = PowLaw1D('p1') self.model = abs1 + p1
def setUp(self): try: from sherpa.astro.xspec import XSphabs, XSpowerlaw from sherpa.astro.io import read_pha except: return pha_fname = self.make_path("stats/9774.pi") self.data = read_pha(pha_fname) self.data.notice(0.5, 7.0) bkg_fname = self.make_path("stats/9774_bg.pi") self.bkg = read_pha(bkg_fname) abs1 = XSphabs('abs1') p1 = PowLaw1D('p1') self.model = abs1 + p1
def test_sherpa_fit(tmpdir): # this is to make sure that the written PHA files work with sherpa import sherpa.astro.ui as sau from sherpa.models import PowLaw1D filename = gammapy_extra.filename( "datasets/hess-crab4_pha/pha_obs23592.fits") sau.load_pha(filename) sau.set_stat('wstat') model = PowLaw1D('powlaw1d.default') model.ref = 1e9 model.ampl = 1 model.gamma = 2 sau.set_model(model * 1e-20) sau.fit() assert_allclose(model.pars[0].val, 2.0033101181778026) assert_allclose(model.pars[2].val, 2.2991681244938498)
def test_sherpa_fit(self, tmpdir): # this is to make sure that the written PHA files work with sherpa import sherpa.astro.ui as sau from sherpa.models import PowLaw1D self.obs_list.write(tmpdir, use_sherpa=True) filename = tmpdir / 'pha_obs23523.fits' sau.load_pha(str(filename)) sau.set_stat('wstat') model = PowLaw1D('powlaw1d.default') model.ref = 1e9 model.ampl = 1 model.gamma = 2 sau.set_model(model * 1e-20) sau.fit() assert_allclose(model.pars[0].val, 2.0881699, rtol=1e-3) assert_allclose(model.pars[2].val, 1.6234222, rtol=1e-3)
def test_sherpa_crab_fit(): from sherpa.models import NormGauss2D, PowLaw1D, TableModel, Const2D from sherpa.stats import Chi2ConstVar from sherpa.optmethods import LevMar from sherpa.fit import Fit from ..sherpa_ import CombinedModel3D filename = gammapy_extra.filename( 'experiments/sherpa_cube_analysis/counts.fits.gz') # Note: The cube is stored in incorrect format counts = SkyCube.read(filename, format='fermi-counts') cube = counts.to_sherpa_data3d() # Set up exposure table model filename = gammapy_extra.filename( 'experiments/sherpa_cube_analysis/exposure.fits.gz') exposure_data = fits.getdata(filename) exposure = TableModel('exposure') exposure.load(None, exposure_data.ravel()) # Freeze exposure amplitude exposure.ampl.freeze() # Setup combined spatial and spectral model spatial_model = NormGauss2D('spatial-model') spectral_model = PowLaw1D('spectral-model') source_model = CombinedModel3D(spatial_model=spatial_model, spectral_model=spectral_model) # Set starting values source_model.gamma = 2.2 source_model.xpos = 83.6 source_model.ypos = 22.01 source_model.fwhm = 0.12 source_model.ampl = 0.05 model = 1E-9 * exposure * source_model # 1E-9 flux factor # Fit fit = Fit(data=cube, model=model, stat=Chi2ConstVar(), method=LevMar()) result = fit.fit() reference = [0.121556, 83.625627, 22.015564, 0.096903, 2.240989] assert_allclose(result.parvals, reference, rtol=1E-5)
def test_sherpa_crab_fit(): from sherpa.models import NormGauss2D, PowLaw1D, TableModel, Const2D from sherpa.stats import Chi2ConstVar from sherpa.optmethods import LevMar from sherpa.fit import Fit from ..sherpa_ import Data3D, CombinedModel3D filename = gammapy_extra.filename( 'experiments/sherpa_cube_analysis/counts.fits.gz') counts = SkyCube.read(filename) cube = counts.to_sherpa_data3d() # Set up exposure table model filename = gammapy_extra.filename( 'experiments/sherpa_cube_analysis/exposure.fits.gz') exposure_data = fits.getdata(filename) exposure = TableModel('exposure') exposure.load(None, exposure_data.ravel()) # Freeze exposure amplitude exposure.ampl.freeze() # Setup combined spatial and spectral model spatial_model = NormGauss2D('spatial-model') spectral_model = PowLaw1D('spectral-model') source_model = CombinedModel3D(spatial_model=spatial_model, spectral_model=spectral_model) # Set starting values source_model.gamma = 2.2 source_model.xpos = 83.6 source_model.ypos = 22.01 source_model.fwhm = 0.12 source_model.ampl = 0.05 model = 1E-9 * exposure * (source_model) # 1E-9 flux factor # Fit fit = Fit(data=cube, model=model, stat=Chi2ConstVar(), method=LevMar()) result = fit.fit() reference = (0.11925401159500593, 83.640630749333056, 22.020525848447541, 0.036353759774770608, 1.1900312815970555) assert_allclose(result.parvals, reference, rtol=1E-8)
def setup(make_data_path): from sherpa.astro.io import read_pha from sherpa.astro import xspec infile = make_data_path("9774.pi") data = read_pha(infile) data.notice(0.3, 7.0) # Change the exposure time to make the fitted amplitude # > 1 # data.exposure = 1 # Use the wabs model because it is unlikely to change # (as scientifically it is no-longer useful). The problem # with using something like the phabs model is that # changes to that model in XSPEC could change the results # here. # # We fit the log of the nH since this makes the numbers # a bit closer to O(1), and so checking should be easier. # abs1 = xspec.XSwabs('abs1') p1 = PowLaw1D('p1') factor = Const1D('factor') factor.integrate = False model = abs1 * p1 + 0 * factor factor.c0 = 0 abs1.nh = 10**factor.c0 # Ensure the nh limits are honoured by factor (upper limit only). # If you don't do this then the fit can fail because a value # outside the abs1.nh but within factor.c0 can be picked. # factor.c0.max = numpy.log10(abs1.nh.max) rsp = Response1D(data) return {'data': data, 'model': rsp(model)}
background bkg_3d bkg = TableModel('bkg') bkg.load(None, background.data.value.ravel()) bkg.ampl = 1 bkg.ampl.freeze() i_nan = np.where(np.isnan(exposure.data)) exposure.data[i_nan] = 0 # In order to have the exposure in cm2 s exposure.data = exposure.data * u.Unit('m2 / cm2').to('') psf_3d = mean_psf_cube # Define a 2D gaussian for the spatial model spatial_model = NormGauss2DInt('spatial-model') # Define a power law for the spectral model spectral_model = PowLaw1D('spectral-model') # Combine spectral and spatial model coord = counts_3d.sky_image_ref.coordinates(mode="edges") energies = counts_3d.energies(mode='edges').to("TeV") # Here the source model will be convolve by the psf: # PSF * (source_model * exposure) source_model = CombinedModel3DInt( coord=coord, energies=energies, use_psf=True, exposure=exposure_3d, psf=psf_3d, spatial_model=spatial_model, spectral_model=spectral_model, )
bkg_3D = SkyCube.read(outdir_data + "/bkg_cube.fits").cutout( center, extraction_size) exposure_3D = SkyCube.read(outdir_data + "/exposure_cube.fits").cutout( center, extraction_size) i_nan = np.where(np.isnan(exposure_3D.data)) exposure_3D.data[i_nan] = 0 exposure_3D.data = exposure_3D.data * 1e4 psf_SgrA = SkyCube.read(outdir_data + "/mean_psf_cube_GC.fits", format="fermi-counts").cutout(center, extraction_size) psf_G0p9 = SkyCube.read(outdir_data + "/mean_psf_cube_G0.9.fits", format="fermi-counts").cutout(center, extraction_size) rmf = EnergyDispersion.read(outdir_data + "/mean_rmf.fits") # Setup combined spatial and spectral model spatial_model_SgrA = NormGauss2DInt('spatial-model_SgrA') spectral_model_SgrA = PowLaw1D('spectral-model_SgrA') #spectral_model_SgrA = MyPLExpCutoff('spectral-model_SgrA') source_model_SgrA = CombinedModel3DIntConvolveEdisp( coord=coord, energies=energies, use_psf=True, exposure=exposure_3D, psf=psf_SgrA, spatial_model=spatial_model_SgrA, spectral_model=spectral_model_SgrA, edisp=rmf.data.data, select_region=True, index_selected_region=index_region_selected_3d) # Set starting values SgrA
def fit_asymmetric_err(self, bench, data): model = PowLaw1D('p1') fit = Fit(data, model, self.stat, self.method, self.est) results = fit.fit() self.cmp(bench, results) return model
def assign_model(model_name, i): """Dedicated set up for the most common models.""" if model_name == 'powlaw1d': from sherpa.models import PowLaw1D p1 = PowLaw1D('PowLaw' + str(i)) p1.gamma = 2.6 p1.ampl = 1e-20 p1.ref = 1e9 sau.freeze(p1.ref) elif model_name == 'logparabola': p1 = logparabola('LogPar' + str(i)) p1.ampl = 1e-20 p1.c1 = 2. p1.c2 = 1. p1.ref = 1e9 sau.freeze(p1.ref) elif model_name == 'plexpcutoff': # all parameters in TeV here from .models.plexpcutoff import MyPLExpCutoff p1 = MyPLExpCutoff('PLexpCutoff' + str(i)) p1.gamma = 2. p1.No = 1e-11 p1.beta = 1e-1 # 1/Ecutoff p1.Eo = 1 sau.freeze(p1.Eo) elif model_name == 'Finke': # EBL model from Finke et al. 2010 # enable_table_model() from ..datasets import gammapy_extra filename = gammapy_extra.filename('datasets/ebl/frd_abs.fits.gz') sau.load_table_model('p1', filename) elif model_name == 'Franceschini': # EBL model from Franceschini et al. 2012 # enable_table_model() from ..datasets import gammapy_extra filename = gammapy_extra.filename( 'datasets/ebl/ebl_franceschini.fits.gz') sau.load_table_model('p1', filename) elif model_name == 'synchro': # print('Synchrotron model not available yet, sorry.') # quit() # Stops with an error: ValueError: slice step cannot be zero from naima.sherpamod import Synchrotron p1 = Synchrotron('Synchro' + str(i)) p1.index = 2. p1.ampl = 1. elif model_name == 'ic': # Inverse Compton peak # Weird, it returns the fit results twice (actually, it seems to do everything twice) # Returns error except if --noplot: TypeError: calc() takes exactly 4 arguments (3 given) from naima.sherpamod import InverseCompton p1 = InverseCompton('IC' + str(i)) p1.index = 2. p1.ampl = 1e-7 # Not sure if the units are OK elif model_name == 'pion': # Pion-decay gamma-ray spectrum # Veeery slow convergence # also doubled operations and problems for plotting, like in ic. from naima.sherpamod import PionDecay p1 = PionDecay('Pion' + str(i)) p1.index = 2. p1.ampl = 10. else: # set initial parameter values manually # (user-defined models and models that need some extra import will not work) p1 = globals()[model_name](model_name + str(i)) set_manual_model(p1) return p1
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)
def fit_asymmetric_err(bench, data): model = PowLaw1D('p1') fit = Fit(data, model, Chi2Gehrels(), LevMar()) results = fit.fit() compare(bench, results) return model
def testCombinedModel3DIntConvolveEdisp(): from sherpa.models import PowLaw1D, TableModel from sherpa.estmethods import Covariance from sherpa.optmethods import NelderMead from sherpa.stats import Cash from sherpa.fit import Fit from ..sherpa_ import CombinedModel3DIntConvolveEdisp, NormGauss2DInt # Set the counts filename = gammapy_extra.filename('test_datasets/cube/counts_cube.fits') counts_3d = SkyCube.read(filename) cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt') # Set the bkg filename = gammapy_extra.filename('test_datasets/cube/bkg_cube.fits') bkg_3d = SkyCube.read(filename) bkg = TableModel('bkg') bkg.load(None, bkg_3d.data.value.ravel()) bkg.ampl = 1 bkg.ampl.freeze() # Set the exposure filename = gammapy_extra.filename( 'test_datasets/cube/exposure_cube_etrue.fits') exposure_3d = SkyCube.read(filename) i_nan = np.where(np.isnan(exposure_3d.data)) exposure_3d.data[i_nan] = 0 # In order to have the exposure in cm2 s exposure_3d.data = exposure_3d.data * 1e4 # Set the mean psf model filename = gammapy_extra.filename('test_datasets/cube/psf_cube_etrue.fits') psf_3d = SkyCube.read(filename) # Set the mean rmf filename = gammapy_extra.filename('test_datasets/cube/rmf.fits') rmf = EnergyDispersion.read(filename) # Setup combined spatial and spectral model spatial_model = NormGauss2DInt('spatial-model') spectral_model = PowLaw1D('spectral-model') # dimensions = [exposure_3d.data.shape[1], exposure_3d.data.shape[2], rmf.data.data.shape[1], # exposure_3d.data.shape[0]] coord = counts_3d.sky_image_ref.coordinates(mode="edges") energies = counts_3d.energies(mode='edges').to("TeV") source_model = CombinedModel3DIntConvolveEdisp( coord=coord, energies=energies, use_psf=True, exposure=exposure_3d, psf=psf_3d, spatial_model=spatial_model, spectral_model=spectral_model, edisp=rmf.data.data) # Set starting values center = SkyCoord(83.633083, 22.0145, unit="deg").galactic source_model.gamma = 2.2 source_model.xpos = center.l.value source_model.ypos = center.b.value source_model.fwhm = 0.12 source_model.ampl = 1.0 # Fit model = bkg + 1E-11 * (source_model) fit = Fit(data=cube, model=model, stat=Cash(), method=NelderMead(), estmethod=Covariance()) result = fit.fit() # TODO: The fact that it doesn't converge to the right Crab postion, flux and source size is due to the dummy psf reference = [ 184.19189525423425, -6.1758238877562386, 6.2283155506945755, 0.071013932890499717, 2.2685809241308674 ] assert_allclose(result.parvals, reference, rtol=1E-5) # Add a region to exclude in the fit: Here we will exclude some events from the Crab since there is no region to # exclude in the FOV for this example. It's just an example to show how it works and how to proceed in the fit. # Read the mask for the exclude region filename_mask = gammapy_extra.filename('test_datasets/cube/mask.fits') cube_mask = SkyCube.read(filename_mask) index_region_selected_3d = np.where(cube_mask.data.value == 1) # Set the counts and create a gammapy Data3DInt object on which we apply a mask for the region we don't want to use in the fit cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt') cube.mask = cube_mask.data.value.ravel() # Set the bkg and select only the data points of the selected region bkg = TableModel('bkg') bkg.load(None, bkg_3d.data.value[index_region_selected_3d].ravel()) bkg.ampl = 1 bkg.ampl.freeze() # The model is evaluated on all the points then it is compared with the data only on the selected_region source_model = CombinedModel3DIntConvolveEdisp( coord=coord, energies=energies, use_psf=True, exposure=exposure_3d, psf=psf_3d, spatial_model=spatial_model, spectral_model=spectral_model, edisp=rmf.data.data, select_region=True, index_selected_region=index_region_selected_3d) # Set starting values source_model.gamma = 2.2 source_model.xpos = center.l.value source_model.ypos = center.b.value source_model.fwhm = 0.12 source_model.ampl = 1.0 # Fit model = bkg + 1E-11 * (source_model) fit = Fit(data=cube, model=model, stat=Cash(), method=NelderMead(), estmethod=Covariance()) result2 = fit.fit() # TODO: The fact that it doesn't converge to the right Crab postion is due to the dummy psf reference2 = [ 184.1919580251583, -6.1692775561065769, 5.4976586957354581, 0.074821281329729109, 2.2504892463464699 ] assert_allclose(result2.parvals, reference2, rtol=1E-5)
def testCombinedModel3DInt(): from sherpa.models import PowLaw1D, TableModel from sherpa.estmethods import Covariance from sherpa.optmethods import NelderMead from sherpa.stats import Cash from sherpa.fit import Fit from ..sherpa_ import CombinedModel3DInt, NormGauss2DInt # Set the counts filename = gammapy_extra.filename('test_datasets/cube/counts_cube.fits') counts_3d = SkyCube.read(filename) cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt') # Set the bkg filename = gammapy_extra.filename('test_datasets/cube/bkg_cube.fits') bkg_3d = SkyCube.read(filename) bkg = TableModel('bkg') bkg.load(None, bkg_3d.data.value.ravel()) bkg.ampl = 1 bkg.ampl.freeze() # Set the exposure filename = gammapy_extra.filename('test_datasets/cube/exposure_cube.fits') exposure_3d = SkyCube.read(filename) i_nan = np.where(np.isnan(exposure_3d.data)) exposure_3d.data[i_nan] = 0 # In order to have the exposure in cm2 s exposure_3d.data = exposure_3d.data * 1e4 # Set the mean psf model filename = gammapy_extra.filename('test_datasets/cube/psf_cube.fits') psf_3d = SkyCube.read(filename) # Setup combined spatial and spectral model spatial_model = NormGauss2DInt('spatial-model') spectral_model = PowLaw1D('spectral-model') coord = counts_3d.sky_image_ref.coordinates(mode="edges") energies = counts_3d.energies(mode='edges').to("TeV") source_model = CombinedModel3DInt(coord=coord, energies=energies, use_psf=True, exposure=exposure_3d, psf=psf_3d, spatial_model=spatial_model, spectral_model=spectral_model) # Set starting values center = SkyCoord(83.633083, 22.0145, unit="deg").galactic source_model.gamma = 2.2 source_model.xpos = center.l.value source_model.ypos = center.b.value source_model.fwhm = 0.12 source_model.ampl = 1.0 # Fit model = bkg + 1E-11 * (source_model) fit = Fit(data=cube, model=model, stat=Cash(), method=NelderMead(), estmethod=Covariance()) result = fit.fit() # TODO: The fact that it doesn't converge to the right Crab postion is due to the dummy psf reference = [ 184.19524957441664, -6.1693008203971562, 6.1666646581766011, 0.076340497278248376, 2.305912037549 ] assert_allclose(result.parvals, reference, rtol=1E-5) # Add a region to exclude in the fit: Here we will exclude some events from the Crab since there is no region to # exclude in the FOV for this example. It's just an example to show how it works and how to proceed in the fit. # Read the mask for the exclude region filename_mask = gammapy_extra.filename('test_datasets/cube/mask.fits') cube_mask = SkyCube.read(filename_mask) index_region_selected_3d = np.where(cube_mask.data.value == 1) # Set the counts and create a gammapy Data3DInt object on which we apply a mask for the region we don't want to use in the fit cube = counts_3d.to_sherpa_data3d(dstype='Data3DInt') cube.mask = cube_mask.data.value.ravel() # Set the bkg and select only the data points of the selected region bkg = TableModel('bkg') bkg.load(None, bkg_3d.data.value[index_region_selected_3d].ravel()) bkg.ampl = 1 bkg.ampl.freeze() # The model is evaluated on all the points then it is compared with the data only on the selected_region source_model = CombinedModel3DInt( coord=coord, energies=energies, use_psf=True, exposure=exposure_3d, psf=psf_3d, spatial_model=spatial_model, spectral_model=spectral_model, select_region=True, index_selected_region=index_region_selected_3d) # Set starting values source_model.gamma = 2.2 source_model.xpos = center.l.value source_model.ypos = center.b.value source_model.fwhm = 0.12 source_model.ampl = 1.0 # Fit model = bkg + 1E-11 * (source_model) fit = Fit(data=cube, model=model, stat=Cash(), method=NelderMead(), estmethod=Covariance()) result2 = fit.fit() # TODO: The fact that it doesn't converge to the right Crab postion is due to the dummy psf reference2 = [ 184.20146538191321, -6.1600047997645975, 5.4193056837212374, 0.08635929788659219, 2.2979723660330 ] assert_allclose(result2.parvals, reference2, rtol=1E-5)