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 __init__(self, likelihoodModel): self.likelihoodModel = likelihoodModel self.table_model = TableModel("table.source") # fetch energies self.e_lo = np.array(datastack.get_arf(1).energ_lo) self.e_hi = np.array(datastack.get_arf(1).energ_hi) # TODO figure out what to do if the binning is different across the datastack self.table_model._TableModel__x = self.e_lo # according to Sherpa TableModel specs, TBV # determine which sources are inside the ON region self.onPtSrc = [] # list of point sources in the ON region nPtsrc = self.likelihoodModel.getNumberOfPointSources() for ipt in range(nPtsrc): # TODO check if source is in the ON region? self.onPtSrc.append(ipt) self.onExtSrc = [] # list of extended sources in the ON region nExtsrc = self.likelihoodModel.getNumberOfExtendedSources() if nExtsrc > 0: raise NotImplemented("Cannot support extended sources yet")
def setUp(self): self.num = 4 self.ncoords = 100 self.ntemplates = 2**self.num self.x = numpy.linspace(0.1, 5, 50) g1 = Gauss1D('g1') # create a 4-dimensional grid from 0 to 1 inclusive, shape = (16,4) grid = numpy.mgrid[[slice(0, 2, 1) for ii in range(self.num)]] grid = numpy.asarray(list(map(numpy.ravel, grid))).T coords = numpy.linspace(0.01, 6, 100) names = ["p%i" % i for i in range(self.num)] templates = [] for ii in range(self.ntemplates): t = TableModel() g1.fwhm = numpy.random.uniform(0.5, 2.0) g1.pos = numpy.random.uniform(1.0, 4.5) g1.ampl = numpy.random.uniform(1.0, 50.) t.load(coords, g1(coords)) templates.append(t) self.model = create_template_model("mdl", names, grid, templates)
from sherpa.optmethods import NelderMead from sherpa.stats import Cash from sherpa.fit import Fit import sherpa import os cube_dir = Path(os.getcwd()) counts_3d = SkyCube.read(cube_dir / 'counts_cube.fits') cube cube = counts.to_sherpa_data3d(dstype='Data3DInt') background bkg_3d = SkyCube.read(cube_dir / 'bkg_cube.fits') cube_dir = Path('$GAMMAPY_EXTRA/test_datasets/cube') bkg_3d = SkyCube.read(cube_dir / 'bkg_cube.fits') 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
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)
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)
unit="deg").galactic else: source_center_SgrA = SkyCoord.from_name( input_param["param_SgrA"]["sourde_name_skycoord"]).galactic #center=SkyCoord.from_name("Crab").galactic source_model_SgrA.gamma = 2.2 source_model_SgrA.xpos = source_center_SgrA.l.value source_model_SgrA.ypos = source_center_SgrA.b.value source_model_SgrA.xpos.freeze() source_model_SgrA.ypos.freeze() source_model_SgrA.fwhm = 0.12 source_model_SgrA.fwhm.freeze() source_model_SgrA.ampl = 1.0 bkg = TableModel('bkg') bkg.load(None, bkg_3D.data[index_region_selected_3d].value.ravel()) # Freeze bkg amplitude bkg.ampl = 1 bkg.ampl.freeze() model = bkg + 1E-11 * (source_model_SgrA) # Fit # For now only Chi2 statistics seems to work, using Cash, the optimizer doesn't run at all, # maybe because of missing background model? fit = Fit(data=cube, model=model, stat=Cash(), method=NelderMead(), estmethod=Covariance()) result = fit.fit()
def main(): config = read_config('config.yaml') # ref_cube = make_ref_cube(config) # target_position = SkyCoord(config['model']['ra1'], config['model']['dec1'], unit="deg").galactic cubes = load_cubes(config) print('which available cubes:', cubes) # converting data SkyCube to sherpa-format cube counts = cubes['counts'].to_sherpa_data3d() #dstype='Data3DInt') print('counts: ', counts) # 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') coord = cubes['counts'].sky_image_ref.coordinates(mode="edges") energies = cubes['counts'].energies(mode='edges').to("TeV") print('my energy bins: ', energies) # import IPython; IPython.embed(); # Set up exposure table model exposure = TableModel('exposure') exposure.load(None, cubes['exposure'].data.ravel()) exposure.ampl.freeze() use_psf = config['model']['use_psf'] model_gammapy = get_model_gammapy(config) spectral_model_sherpa = model_gammapy.spectral_model.to_sherpa() spectral_model_sherpa.ampl.thaw() spatial_model_sherpa = model_gammapy.spatial_model.to_sherpa() spatial_model_sherpa.xpos.freeze() spatial_model_sherpa.ypos.freeze() spatial_model_sherpa.r0.freeze() spatial_model_sherpa.width.freeze() source_model = CombinedModel3D( spatial_model=spatial_model_sherpa, spectral_model=spectral_model_sherpa, ) # source_model = CombinedModel3DInt( # spatial_model=spatial_model_sherpa, # spectral_model=spectral_model_sherpa, # exposure=exposure, # coord=coord, # energies=energies, # use_psf=use_psf, # psf=None, # ) print(source_model) # source_model_cube = source_model.evaluate_cube(ref_cube) # model = source_model # + background_model # source_model2 = CombinedModel3DInt( # coord=coord, # energies=energies, # use_psf=False, # exposure=cubes['exposure'], # psf=None, # spatial_model=spatial_model, # spectral_model=spectral_model, # ) model = 1e-9 * exposure * source_model # 1e-9 flux factor fit = Fit( data=counts, model=model, stat=Chi2ConstVar(), method=LevMar(), # estmethod=Covariance(), ) fit_results = fit.fit() print(fit_results.format()) print('------------------------------------ end fitting')