def define_flux_crab_above_energy(emin=1 * u.TeV, emax=10 * u.TeV): crab = CrabSpectrum('meyer').model crabMAGIC = LogParabola(amplitude=3.23e-11 * u.Unit('cm-2 s-1 TeV-1'), reference=1 * u.TeV, alpha=2.47, beta=0.24) crab_flux_above_1TeV = crabMAGIC.integral(emin=emin, emax=emax) crab_flux_above_1TeV_model = crab.integral(emin=emin, emax=emax) return crab_flux_above_1TeV, crab_flux_above_1TeV_model
def plot_spectral_models(self): for component in self.get_components(tags=['pwn', 'composite']): fig, ax = plt.subplots() table = component['table'] tag = component['tag'] vals = [] idx = 0 energies = Energy.equal_log_spacing(emin=0.02, emax=100, unit='TeV', nbins=40) for row in table: idx += 1 if (idx < 100): spec = LogParabola( amplitude=row['spec_norm'] * u.Unit('MeV-1 s-1 cm-2'), alpha=row['spec_alpha'], reference=1 * u.TeV, beta=row['spec_beta'], ) fluxes = [] e2dnde = [] for energy in energies: dnde = spec.evaluate( energy=energy, amplitude=row['spec_norm'] * u.Unit('MeV-1 s-1 cm-2'), alpha=row['spec_alpha'], reference=1 * u.TeV, beta=row['spec_beta'], ) fluxes.append(dnde.value) e2dnde.append( ((energy**2 * dnde).to('erg cm-2 s-1')).value) ax.plot(energies.value, e2dnde, color='black', alpha=0.2, lw=2) else: break ax.set_title('{} spectra'.format(component['tag'])) ax.loglog() ax.set_xlabel('Energy (TeV)') ax.set_ylabel('e2dnde (erg cm-2 s-1)') ax.set_ylim(2e-18, 5e-10) fig.tight_layout() filename = 'ctadc_skymodel_gps_sources_spectra_{}.png'.format( component['tag']) log.info('Writing {}'.format(filename)) fig.savefig(filename) plt.close(fig)
def define_flux_crab_above_energy(): emin, emax = [1, 10] * u.TeV # crab = CrabSpectrum('meyer').model crabMAGIC = LogParabola(amplitude=3.23e-11 * u.Unit('cm-2 s-1 TeV-1'), reference=1 * u.TeV, alpha=2.47, beta=-0.24) crab_flux_above_1TeV = crabMAGIC.integral(emin=emin, emax=emax) print(crab_flux_above_1TeV) crab_flux_above_1TeV = crab_flux_above_1TeV.to('cm-2 s-1') return crab_flux_above_1TeV
def get_model_gammapy(config): if config['model']['template'] == 'Shell2D': spatial_model = Shell2D( amplitude=1, x_0=config['model']['ra'], y_0=config['model']['dec'], r_in=config['model']['rin'], width=config['model']['width'], # Note: for now we need spatial models that are normalised # to integrate to 1 or results will be incorrect!!! normed=True, ) if config['model']['template'] == 'Sphere2D': spatial_model = Sphere2D( amplitude=1, x_0=config['model']['ra'], y_0=config['model']['dec'], r_0=config['model']['rad'], # Note: for now we need spatial models that are normalised # to integrate to 1 or results will be incorrect!!! normed=True, ) if config['model']['template'] == 'Gauss2D': spatial_model = Gauss2DPDF( #amplitude=1, #x_0=config['model']['ra'], #y_0=config['model']['dec'], sigma=config['model']['sigma'], # Note: for now we need spatial models that are normalised # to integrate to 1 or results will be incorrect!!! #normed=True, ) if config['model']['spectrum'] == 'pl': spectral_model = PowerLaw( amplitude=config['model']['prefactor'] * u.Unit('cm-2 s-1 TeV-1'), index=config['model']['index'], reference=config['model']['pivot_energy'] * u.Unit('TeV'), ) if config['model']['spectrum'] == 'ecpl': spectral_model = ExponentialCutoffPowerLaw( amplitude=config['model']['prefactor'] * u.Unit('cm-2 s-1 TeV-1'), index=config['model']['index'], reference=config['model']['pivot_energy'] * u.Unit('TeV'), lambda_=config['model']['cutoff'] * u.Unit('TeV-1'), ) if config['model']['spectrum'] == 'LogParabola': spectral_model = LogParabola( amplitude=config['model']['prefactor'] * u.Unit('cm-2 s-1 TeV-1'), alpha=config['model']['alphapar'], beta=config['model']['beta'], reference=config['model']['pivot_energy'] * u.Unit('TeV'), ) return CombinedModel3D( spatial_model=spatial_model, spectral_model=spectral_model, )
def spectral_model(self): """Best fit spectral model (`~gammapy.spectrum.models.SpectralModel`).""" d = self.data spec_type = self.data["SpectrumType"].strip() pars, errs = {}, {} pars["amplitude"] = d["Flux_Density"] errs["amplitude"] = d["Unc_Flux_Density"] pars["reference"] = d["Pivot_Energy"] if spec_type == "PowerLaw": pars["index"] = d["PowerLaw_Index"] errs["index"] = d["Unc_PowerLaw_Index"] model = PowerLaw(**pars) elif spec_type == "LogParabola": pars["alpha"] = d["Spectral_Index"] pars["beta"] = d["beta"] errs["alpha"] = d["Unc_Spectral_Index"] errs["beta"] = d["Unc_beta"] model = LogParabola(**pars) else: raise ValueError("Invalid spec_type: {!r}".format(spec_type)) model.parameters.set_parameter_errors(errs) return model
def flux_amplitude_from_energy_flux(alpha, beta, energy_flux): spec = LogParabola( amplitude=1 * u.Unit('cm-2 s-1 TeV-1'), reference=1 * u.TeV, alpha=alpha, beta=-beta, ) # Assumption before for `energy_flux` was energy band 1 to 10 TeV emin_int = 1 * u.TeV emax_int = 10 * u.TeV pivot_energy = 1 * u.TeV energy_flux_standard_candle = spec.energy_flux(emin=emin_int, emax=emax_int) flux_at_1TeV = energy_flux / energy_flux_standard_candle * u.Unit('cm-2 s-1 TeV-1') # print('std: ', energy_flux_standard_candle, 'energy_flux: ', energy_flux, flux_at_1TeV) flux_at_1TeV = flux_at_1TeV.to('cm-2 s-1 MeV-1') spec2 = LogParabola(amplitude=flux_at_1TeV, reference=pivot_energy, alpha=alpha, beta=beta) energy_flux_above_1TeV = spec2.energy_flux(emin=emin_int, emax=10 * u.TeV) # print('c',energy_flux_above_1TeV.to('TeV cm-2 s-1'),energy_flux_above_1TeV.to('TeV cm-2 s-1')/(flux_at_1TeV.to('cm-2 s-1 TeV-1')/)) ) flux_above_1TeV = spec2.integral(emin=emin_int, emax=10 * u.TeV) flux_above_1TeV = flux_above_1TeV.to('cm-2 s-1') # evaluating Crab flux at and above 1 TeV by using MAGIC Crab spectrum from JHEA 2015 crab_flux_above_1TeV, crab_flux_above_1TeV_model = define_flux_crab_above_energy(emin=1 * u.TeV, emax=10 * u.TeV) crabMAGIC = LogParabola(amplitude=3.23e-11 * u.Unit('cm-2 s-1 TeV-1'), reference=1 * u.TeV, alpha=2.47, beta=0.24) # plt.figure() # min, max = [50*u.GeV,50*u.TeV] # crabMAGIC.plot(min,max) # crab = CrabSpectrum('meyer').model crab_flux_above_1TeV = crab_flux_above_1TeV.to('cm-2 s-1') crab_flux_above_1TeV_model = crab_flux_above_1TeV_model.to('cm-2 s-1') crab_flux_at_1TeV = crabMAGIC(pivot_energy).to('MeV-1 cm-2 s-1') # computing flux at and above 1 TeV in crab units flux_at_1TeV_cu = (flux_at_1TeV / crab_flux_at_1TeV)*100 flux_above_1TeV_cu = (flux_above_1TeV / crab_flux_above_1TeV)*100 # print(crab_flux_above_1TeV, flux_above_1TeV, flux_above_1TeV / crab_flux_above_1TeV, flux_above_1TeV_cu ) flux_above_1TeV_cu_model = (flux_above_1TeV / crab_flux_above_1TeV_model).to('%') return flux_at_1TeV, flux_at_1TeV_cu, flux_above_1TeV, flux_above_1TeV_cu
def spectral_model(self): """Best fit spectral model (`~gammapy.spectrum.models.SpectralModel`).""" spec_type = self.data["SpectrumType"].strip() pars, errs = {}, {} pars["amplitude"] = self.data["Flux_Density"] errs["amplitude"] = self.data["Unc_Flux_Density"] pars["reference"] = self.data["Pivot_Energy"] if spec_type == "PowerLaw": pars["index"] = self.data["Spectral_Index"] errs["index"] = self.data["Unc_Spectral_Index"] model = PowerLaw(**pars) elif spec_type == "PLExpCutoff": pars["index"] = self.data["Spectral_Index"] pars["ecut"] = self.data["Cutoff"] errs["index"] = self.data["Unc_Spectral_Index"] errs["ecut"] = self.data["Unc_Cutoff"] model = ExponentialCutoffPowerLaw3FGL(**pars) elif spec_type == "LogParabola": pars["alpha"] = self.data["Spectral_Index"] pars["beta"] = self.data["beta"] errs["alpha"] = self.data["Unc_Spectral_Index"] errs["beta"] = self.data["Unc_beta"] model = LogParabola(**pars) elif spec_type == "PLSuperExpCutoff": # TODO: why convert to GeV here? Remove? pars["reference"] = pars["reference"].to("GeV") pars["index_1"] = self.data["Spectral_Index"] pars["index_2"] = self.data["Exp_Index"] pars["ecut"] = self.data["Cutoff"].to("GeV") errs["index_1"] = self.data["Unc_Spectral_Index"] errs["index_2"] = self.data["Unc_Exp_Index"] errs["ecut"] = self.data["Unc_Cutoff"].to("GeV") model = PLSuperExpCutoff3FGL(**pars) else: raise ValueError("Invalid spec_type: {!r}".format(spec_type)) model.parameters.set_parameter_errors(errs) return model
def spectral_model(self): """Best fit spectral model (`~gammapy.spectrum.models.SpectralModel`).""" spec_type = self.data["SpectrumType"].strip() pars, errs = {}, {} pars["reference"] = self.data["Pivot_Energy"] if spec_type == "PowerLaw": pars["amplitude"] = self.data["PL_Flux_Density"] pars["index"] = self.data["PL_Index"] errs["amplitude"] = self.data["Unc_PL_Flux_Density"] errs["index"] = self.data["Unc_PL_Index"] model = PowerLaw(**pars) elif spec_type == "LogParabola": pars["amplitude"] = self.data["LP_Flux_Density"] pars["alpha"] = self.data["LP_Index"] pars["beta"] = self.data["LP_beta"] errs["amplitude"] = self.data["Unc_LP_Flux_Density"] errs["alpha"] = self.data["Unc_LP_Index"] errs["beta"] = self.data["Unc_LP_beta"] model = LogParabola(**pars) elif spec_type == "PLSuperExpCutoff": pars["amplitude"] = self.data["PLEC_Flux_Density"] pars["index_1"] = self.data["PLEC_Index"] pars["index_2"] = self.data["PLEC_Exp_Index"] pars["expfactor"] = self.data["PLEC_Expfactor"] / u.MeV**pars[ "index_2"] errs["amplitude"] = self.data["Unc_PLEC_Flux_Density"] errs["index_1"] = self.data["Unc_PLEC_Index"] errs["index_2"] = np.nan_to_num(self.data["Unc_PLEC_Exp_Index"]) errs["expfactor"] = (self.data["Unc_PLEC_Expfactor"] / u.MeV**pars["index_2"]) model = PLSuperExpCutoff4FGL(**pars) else: raise ValueError("Invalid spec_type: {!r}".format(spec_type)) model.parameters.set_parameter_errors(errs) return model
ax = flux_points.plot(energy_power=2) result_ecpl.model.plot(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) result_ecpl.model.plot_error(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) ax.set_ylim(1e-13, 1e-11) # ## Log-Parabola Fit # # Finally we try to fit a [log-parabola](https://docs.gammapy.org/0.10/api/gammapy.spectrum.models.LogParabola.html#gammapy.spectrum.models.LogParabola) model: # In[ ]: log_parabola = LogParabola(alpha=2, amplitude="1e-12 cm-2 s-1 TeV-1", reference="1 TeV", beta=0.1) # In[ ]: fitter = FluxPointFit(log_parabola, flux_points, stat="chi2assym") result_log_parabola = fitter.run() print(result_log_parabola.model) # In[ ]: ax = flux_points.plot(energy_power=2) result_log_parabola.model.plot(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) result_log_parabola.model.plot_error(energy_range=[1e-4, 1e2] * u.TeV,
def plot_fit_results(tool): """plot the SEDs result of the gammapy / sherpa fit for comparison with the literature we choose only the Mayer spectrum Here we plot the butterfly as a result of the multivariate sampling with the 68% containment in flux """ fig, ax = plt.subplots() model_meyer_ref = CrabSpectrum("meyer").model model_meyer_ref.plot( [10 * u.GeV, 100 * u.TeV], energy_power=2, flux_unit="erg-1 cm-2 s-1", ls=":", lw=2.2, color="#555555", label="Meyer et al. (2010)", ) # where to take the results, configurations for the individual butterflies instruments = ["fermi", "magic", "veritas", "fact", "hess", "joint"] labels = ["Fermi-LAT", "MAGIC", "VERITAS", "FACT", "H.E.S.S.", "joint fit"] lss = ["--", "--", "--", "--", "--", "-"] colors = COLORS # with one loop we realize all the butterfly plots for instrument, label, color, ls in zip(instruments, labels, colors, lss): path = ( config.repo_path / f"results/fit/{tool}/{instrument}/fit_results_logparabola.yaml") if not path.exists(): log.warning(f"Missing: {path} . Skipping.") continue results = load_yaml(path) parameters = results["parameters"] model_lp = LogParabola.from_log10( amplitude=parameters[0]["value"] * u.Unit(parameters[0]["unit"]), reference=parameters[1]["value"] * u.Unit(parameters[1]["unit"]), alpha=parameters[2]["value"] * u.Unit(parameters[2]["unit"]), beta=parameters[3]["value"] * u.Unit(parameters[3]["unit"]), ) # energy range for the plot dataset = config.get_dataset(instrument) energy_range = dataset.energy_range # just in case of the joint fit put a thicker line and a less transparent butterfly if instrument == "joint": model_lp.plot( energy_range, energy_power=2, flux_unit="erg-1 cm-2 s-1", ls=ls, lw=3, color=color, label=label, ) else: model_lp.plot( energy_range, energy_power=2, flux_unit="erg-1 cm-2 s-1", ls=ls, lw=2.2, color=color, label=label, ) # read the butterfly from the multivariate sampling results table_path = Path( f"{config.repo_path}/results/figures/stat_err/{instrument}_flux_errorband.dat" ) log.info(f"reading butterfly values from {table_path}") t = Table.read(table_path, format="ascii.ecsv") energies = t["energies"].data * t["energies"].unit flux_lo = t["flux_lo"].data * t["flux_lo"].unit flux_hi = t["flux_hi"].data * t["flux_hi"].unit if instrument == "joint": alpha = 0.38 else: alpha = 0.28 plt.fill_between( energies.to("TeV"), (energies**2 * flux_lo).to("erg cm-2 s-1"), (energies**2 * flux_hi).to("erg cm-2 s-1"), color=color, alpha=alpha, label="", ) ax.legend(fontsize=FONTSIZE) ax.set_ylim([1e-12, 2e-10]) ax.set_xlabel(E_UNIT_LABEL, size=FONTSIZE) ax.set_ylabel(SED_UNIT_LABEL, size=FONTSIZE) # make axis thicker for axis in ["top", "bottom", "left", "right"]: ax.spines[axis].set_linewidth(1.6) ax.tick_params("both", length=7, width=1.6, which="major", labelsize=FONTSIZE) ax.tick_params("both", length=4, width=1.6, which="minor", labelsize=FONTSIZE) plt.tight_layout() filename = f"results/figures/crab_sed_{tool}_fit.png" filename_pdf = f"results/figures/crab_sed_{tool}_fit.pdf" log.info(f"Writing {filename}") fig.savefig(filename) fig.savefig(filename_pdf)
amplitude=flare_amplitude, reference=flare_reference, lambda_=lambda_flare) #flare_model = PowerLaw(index=flare_index, amplitude=flare_amplitude, reference=flare_reference) ####################################################################### # Model if spectype == 'PowerLaw': neb_model = PowerLaw(index=index, amplitude=amplitude, reference=reference) ### HEGRA elif spectype == 'LogParabola': neb_model = LogParabola(amplitude=amplitude, reference=reference, alpha=alphapar, beta=beta) ###MAGIC HESSII elif spectype == 'ExponentialCutoffPowerLaw': neb_model = ExponentialCutoffPowerLaw(index=index, amplitude=amplitude, reference=reference, lambda_=lambda_) ####HESS else: raise ValueError( 'Spectra Model must be either "LogParabola", "PowerLaw", or "ExponentialCutoffPowerLaw"' ) energy_array = np.linspace(emin.value, emax.value, 300) * u.TeV flare_plus_neb_model = np.zeros(len(energy_array)) * u.Unit('cm-2 s-1 TeV-1')
ecpl.plot(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) # assign covariance for plotting ecpl.parameters.covariance = result_ecpl.parameters.covariance ecpl.plot_error(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) ax.set_ylim(1e-13, 1e-11) # ## Log-Parabola Fit # # Finally we try to fit a [log-parabola](https://docs.gammapy.org/0.11/api/gammapy.spectrum.models.LogParabola.html#gammapy.spectrum.models.LogParabola) model: # In[ ]: log_parabola = LogParabola(alpha=2, amplitude="1e-12 cm-2 s-1 TeV-1", reference="1 TeV", beta=0.1) # In[ ]: dataset_log_parabola = FluxPointsDataset(log_parabola, flux_points, likelihood="chi2assym") fitter = Fit(dataset_log_parabola) result_log_parabola = fitter.run() print(log_parabola) # In[ ]: ax = flux_points.plot(energy_power=2) log_parabola.plot(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2)
obs_ids = data_store.obs_table["OBS_ID"][mask].data observations = data_store.obs_list(obs_ids) print(obs_ids) # ## Configure the analysis # # Now we'll define the input for the spectrum analysis. It will be done the python way, i.e. by creating a config dict containing python objects. We plan to add also the convenience to configure the analysis using a plain text config file. # In[ ]: crab_pos = SkyCoord.from_name("crab") on_region = CircleSkyRegion(crab_pos, 0.15 * u.deg) model = LogParabola( alpha=2.3, beta=0.01, amplitude=1e-11 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV, ) flux_point_binning = EnergyBounds.equal_log_spacing(0.7, 30, 5, u.TeV) # In[ ]: exclusion_mask = Map.create(skydir=crab_pos, width=(10, 10), binsz=0.02) gammacat = SourceCatalogGammaCat() regions = [] for source in gammacat: if not exclusion_mask.geom.contains(source.position): continue
emin = 0.03 * u.TeV emax = 5 * u.TeV obs_param = ObservationParameters(alpha=alpha, livetime=livetime, emin=emin, emax=emax) # Target, PKS 2155-304 from 3FHL name = "2155" # model parameters alpha = 1.88 * u.Unit('') beta = 0.15 * u.Unit('') reference = 18.3 * u.GeV amplitude = 7.7e-11 * u.Unit('cm-2 s-1 GeV-1') model = LogParabola(alpha=alpha, beta=beta, reference=reference, amplitude=amplitude) # redshift redshift = 0.116 # EBL model ebl_model_name = 'dominguez' target = Target(name=name, model=model, redshift=redshift, ebl_model_name=ebl_model_name) # Performance filename = '$GAMMAPY_EXTRA/datasets/cta/perf_prod2/point_like_non_smoothed/South_5h.fits.gz' cta_perf = CTAPerf.read(filename) # Simulation
beta= 0.104 * u.Unit('') ### MAGIC: 0.24/np.log(10) HESSII: 0.24 ### Needed for: 'LogParabola' ####################################################################### ######## Define Flare model flare_index = 3.161 * u.Unit('') flare_amplitude = 3.320e-11 * u.Unit('cm-2 s-1 TeV-1') flare_reference = 1.25 * u.TeV lambda_flare = 0.0 * u.Unit('TeV-1') flare_model = ExponentialCutoffPowerLaw(index=flare_index, amplitude=flare_amplitude, reference=flare_reference,lambda_ = lambda_flare) if spectype == 'LogParabola': neb_model = LogParabola(amplitude=amplitude, reference=reference, alpha=alphapar, beta=beta) ###MAGIC HESSII elif spectype == 'ExponentialCutoffPowerLaw': neb_model = ExponentialCutoffPowerLaw(index=index, amplitude=amplitude, reference=reference, lambda_=lambda_) ## HESS elif spectype == 'PowerLaw': neb_model = PowerLaw(index=index, amplitude=amplitude, reference=reference) ### HEGRA else: raise ValueError('Spectra Model must be either "LogParabola", "PowerLaw", or "ExponentialCutoffPowerLaw"') energy_array = np.linspace(emin.value, emax.value, 300) * u.TeV flare_plus_neb_model = np.zeros(len(energy_array)) * u.Unit('cm-2 s-1 TeV-1') for i in range(len(energy_array)): flare_plus_neb_model.value[i] = (neb_model.evaluate(energy_array[i], amplitude=amplitude, reference=reference, alpha=alphapar, beta=beta).value + flare_model.evaluate(energy_array[i], index = flare_index, amplitude = flare_amplitude, reference = flare_reference,lambda_ = lambda_flare).value) * 1e11
ax = flux_points.plot(energy_power=2) result_ecpl['best-fit-model'].plot(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) result_ecpl['best-fit-model'].plot_error(energy_range=[1e-4, 1e2] * u.TeV, ax=ax, energy_power=2) ax.set_ylim(1e-13, 1e-11) # ## Log-Parabola Fit # # Finally we try to fit a [log-parabola](http://docs.gammapy.org/dev/api/gammapy.spectrum.models.LogParabola.html#gammapy.spectrum.models.LogParabola) model: # In[18]: log_parabola = LogParabola( alpha=2. * u.Unit(''), amplitude=1e-12 * u.Unit('cm-2 s-1 TeV-1'), reference=1. * u.TeV, beta=0. * u.Unit('') ) # In[19]: result_log_parabola = fitter.run(flux_points, log_parabola) print(result_log_parabola['best-fit-model']) # In[20]: print(result_log_parabola['statval/dof'])
def main(): #Low energy of spectral fitting range. lo_fit_energ = 0.1 * u.Unit('TeV') hi_fit_energ = 10 * u.Unit('TeV') #If you want an internal estimation of a high energy limit for the fitting range: est_hi_lim = 'yes'. If 'no' the hi_fit_energ will be used. est_hi_lim = 'yes' # Read ON and OFF cubes filename_on = 'non_cube.fits.gz' # non_cube_convolved.fits cube_on = SkyCube.read(filename_on) ann_filename_off = 'noff_withpuls_cube.fits.gz' ann_cube_off = SkyCube.read(ann_filename_off) circ_filename_off = 'noff_withneb_cube.fits.gz' circ_cube_off = SkyCube.read(circ_filename_off) # Read config and IRFs config = read_config('config.yaml') irfs = get_irfs(config) offset = Angle(config['selection']['offset_fov'] * u.deg) livetime = u.Quantity(config['pointing']['livetime']).to('second') alpha_obs = 1. binsz = config['binning']['binsz'] aeff = irfs['aeff'].to_effective_area_table(offset = offset, energy = cube_on.energies('edges')) edisp = irfs['edisp'].to_energy_dispersion(offset = offset, e_true = aeff.energy.bins, e_reco = cube_on.energies('edges') ) # Define circular on/off Regions parameters on_pos = SkyCoord(83.6333 * u.deg, 22.0144 * u.deg, frame='icrs') on_sizes = np.ones(20) * binsz * u.deg off_pos = SkyCoord(83.6333 * u.deg, 22.0144 * u.deg, frame='icrs') off_sizes = on_sizes * np.sqrt(1./alpha_obs) # Make Annular region on_rad_sizes = np.ones(len(on_sizes)) * 0.1 * binsz * u.deg off_rad_sizes = on_rad_sizes * np.sqrt(1./alpha_obs) widths = np.ones(len(on_sizes)) * 22 * binsz * u.deg out_rad_sizes = on_rad_sizes + widths ann_on_data, ann_off_data, ann_stats = make_annular_spectrum(on_pos, off_pos, on_rad_sizes, off_rad_sizes, out_rad_sizes, cube_on, ann_cube_off, alpha_obs) # Make circular region circ_on_data, circ_off_data, circ_stats = make_circular_spectrum(on_pos, off_pos, on_sizes, off_sizes, cube_on, circ_cube_off, alpha_obs) # Undo "holes" in circ/ann_stats if np.max(np.where(circ_stats == 1)) + 1 != circ_stats.sum(): circ_stats[0:np.max(np.where(circ_stats == 1)) + 1][circ_stats[0:np.max(np.where(circ_stats == 1)) + 1] == 0] = 1. if np.max(np.where(ann_stats == 1)) + 1 != ann_stats.sum(): ann_stats[0:np.max(np.where(ann_stats == 1)) + 1][ann_stats[0:np.max(np.where(ann_stats == 1)) + 1] == 0] = 1. # Make on/off vector ann_on_vector = PHACountsSpectrum(energy_lo = cube_on.energies('edges')[:-1], energy_hi= cube_on.energies('edges')[1:], data= ann_on_data['value'].data * ann_stats * u.ct, backscal = on_sizes[0].value, meta={'EXPOSURE' : livetime.value}) circ_on_vector = PHACountsSpectrum(energy_lo = cube_on.energies('edges')[:-1], energy_hi= cube_on.energies('edges')[1:], data= circ_on_data['value'].data * circ_stats * u.ct, backscal = on_sizes[0].value, meta={'EXPOSURE' : livetime.value}) ann_off_vector = PHACountsSpectrum(energy_lo = ann_cube_off.energies('edges')[:-1], energy_hi= ann_cube_off.energies('edges')[1:], data= ann_off_data['value'].data * ann_stats * u.ct, backscal = off_sizes[0].value, meta={'EXPOSURE' : livetime.value, 'OFFSET' : 0.3 * u.deg}) circ_off_vector = PHACountsSpectrum(energy_lo = circ_cube_off.energies('edges')[:-1], energy_hi= circ_cube_off.energies('edges')[1:], data= circ_off_data['value'].data * circ_stats * u.ct, backscal = off_sizes[0].value, meta={'EXPOSURE' : livetime.value, 'OFFSET' : 0.3 * u.deg}) # Make SpectrumObservation ann_sed_table = SpectrumObservation(on_vector = ann_on_vector, off_vector = ann_off_vector, aeff = aeff, edisp = edisp) circ_sed_table = SpectrumObservation(on_vector = circ_on_vector, off_vector = circ_off_vector, aeff = aeff, edisp = edisp) ##Debug #print(ann_stats) #print(circ_stats) # Define Spectral Model model2fit1 = LogParabola(amplitude=1e-11 * u.Unit('cm-2 s-1 TeV-1'), reference=1 * u.TeV, alpha=2.5 * u.Unit(''), beta=0.1 * u.Unit('')) model2fit2 = ExponentialCutoffPowerLaw(index = 1. * u.Unit(''), amplitude = 1e-11 * u.Unit('cm-2 s-1 TeV-1'), reference= 1 * u.TeV, lambda_= 0. * u.Unit('TeV-1')) model2fit3 = PowerLaw(index= 2.5 * u.Unit(''), amplitude= 5e-11 * u.Unit('cm-2 s-1 TeV-1'), reference= 0.15 * u.TeV) model2fit3.parameters['amplitude'].parmin = 1e-12 model2fit3.parameters['amplitude'].parmax = 1e-10 model2fit3.parameters['index'].parmin = 2.0 model2fit3.parameters['index'].parmax = 4.0 #Models to fit the circular and annular observations models_ann_fit = [model2fit1, model2fit2, model2fit3] models_circ_fit = [model2fit1, model2fit2, model2fit3] # Fit if est_hi_lim = 'yes': hi_fit_energ = cube_on.energies('edges')[int(np.sum(ann_stats))]
def counts_histogram(predicted=False): """function to plot the excesses per dataset and compare them with the predicted counts if predicted == True will shwo the predicted counts from the results of the fit (for debug purpose) """ log.info("loading the results from the joint fit to predict the counts") results = load_yaml( f"{config.repo_path}/results/fit/gammapy/joint/fit_results_logparabola.yaml" ) parameters = results["parameters"] model_lp = LogParabola.from_log10( amplitude=parameters[0]["value"] * u.Unit(parameters[0]["unit"]), reference=parameters[1]["value"] * u.Unit(parameters[1]["unit"]), alpha=parameters[2]["value"] * u.Unit(parameters[2]["unit"]), beta=parameters[3]["value"] * u.Unit(parameters[3]["unit"]), ) # defining the figure dict_color = { "fermi": COLORS[0], "magic": COLORS[1], "veritas": COLORS[2], "fact": COLORS[3], "hess": COLORS[4], } fig, ax = plt.subplots() for which in config.all_datasets: log.info(f"predicting counts for {which} dataset") dataset = config.get_dataset(which) obs = dataset.get_SpectrumObservationList().stack() cts_pred = CountsPredictor(model=model_lp, aeff=obs.aeff, edisp=obs.edisp, livetime=obs.livetime) cts_pred.run() e_max = dataset.energy_range[1].to("TeV").value e_min = dataset.energy_range[0].to("TeV").value kwargs_mdl = dict(ls=":", range=(e_min, e_max), lw=2.2, color=dict_color[which]) kwargs_data = dict(ls="-", range=(e_min, e_max), lw=2.2, color=dict_color[which]) # CountsSpectrum with observed and predicted excesses ex_pred = cts_pred.npred ex_obs = obs.excess_vector # if it is an IACT rebin the counts before plotting if which != "fermi": ex_pred = ex_pred.rebin(2) ex_obs = ex_obs.rebin(2) if predicted: # if you want to display the predicted counts ex_pred.plot_hist(ax, **kwargs_mdl) ex_obs.plot_hist(ax, **kwargs_data) # custom legend legend_observed = mlines.Line2D([], [], color="gray", marker="", ls="-", lw=2, label="observed") legend_expected = mlines.Line2D([], [], color="gray", marker="", ls=":", lw=2, label="expected") legend_fermi = mlines.Line2D([], [], color=COLORS[0], marker="", ls="-", lw=2, label="Fermi-LAT") legend_magic = mlines.Line2D([], [], color=COLORS[1], marker="", ls="-", lw=2, label="MAGIC") legend_veritas = mlines.Line2D([], [], color=COLORS[2], marker="", ls="-", lw=2, label="VERITAS") legend_fact = mlines.Line2D([], [], color=COLORS[3], marker="", ls="-", lw=2, label="FACT") legend_hess = mlines.Line2D([], [], color=COLORS[4], marker="", ls="-", lw=2, label="H.E.S.S.") legend_handles = [ legend_fermi, legend_magic, legend_veritas, legend_fact, legend_hess, ] if predicted: # if you want to display the predicted counts legend_handles = [legend_observed, legend_expected] + legend_handles ax.legend(handles=legend_handles, fontsize=FONTSIZE) ax.set_xscale("log") ax.set_ylabel("Excess counts", size=FONTSIZE) ax.set_xlabel(E_UNIT_LABEL, size=FONTSIZE) # make axis thicker for axis in ["top", "bottom", "left", "right"]: ax.spines[axis].set_linewidth(1.6) ax.tick_params("both", length=7, width=1.6, which="major", labelsize=FONTSIZE) ax.tick_params("both", length=4, width=1.6, which="minor", labelsize=FONTSIZE) plt.tight_layout() filename = f"{config.repo_path}/results/figures/counts_spectra.png" filename_pdf = f"{config.repo_path}/results/figures/counts_spectra.pdf" log.info(f"saving figure in {filename}") fig.savefig(filename) fig.savefig(filename_pdf)
model=PLSuperExpCutoff4FGL( index_1=1.5, index_2=2, amplitude=1 / u.cm ** 2 / u.s / u.TeV, reference=1 * u.TeV, expfactor=1e-2 / u.TeV ** 2, ), val_at_2TeV=u.Quantity(0.3431043087721737, "cm-2 s-1 TeV-1"), integral_1_10TeV=u.Quantity(1.2125247, "cm-2 s-1"), eflux_1_10TeV=u.Quantity(3.38072082, "TeV cm-2 s-1"), ), dict( name="logpar", model=LogParabola( alpha=2.3 * u.Unit(""), amplitude=4 / u.cm ** 2 / u.s / u.TeV, reference=1 * u.TeV, beta=0.5 * u.Unit(""), ), val_at_2TeV=u.Quantity(0.6387956571420305, "cm-2 s-1 TeV-1"), integral_1_10TeV=u.Quantity(2.255689748270628, "cm-2 s-1"), eflux_1_10TeV=u.Quantity(3.9586515834989267, "TeV cm-2 s-1"), e_peak=0.74082 * u.TeV, ), dict( name="logpar10", model=LogParabola.from_log10( alpha=2.3 * u.Unit(""), amplitude=4 / u.cm ** 2 / u.s / u.TeV, reference=1 * u.TeV, beta=1.151292546497023 * u.Unit(""), ),