# In[ ]: # Flux points are computed on stacked observation stacked_obs = Datasets(extract.spectrum_observations).stack_reduce() print(stacked_obs) # In[ ]: e_edges = np.logspace(0, 1.5, 5) * u.TeV stacked_obs.model = model fpe = FluxPointsEstimator(datasets=[dataset], e_edges=e_edges) flux_points = fpe.run() flux_points.table_formatted # ### Plot # # Let's plot the spectral model and points. You could do it directly, but there is a helper class. # Note that a spectral uncertainty band, a "butterfly" is drawn, but it is very thin, i.e. barely visible. # In[ ]: model.parameters.covariance = result.parameters.covariance
plt.figure(figsize=(8, 6)) flux_points_dataset.peek() # ## Stack observations # # And alternative approach to fitting the spectrum is stacking all observations first and the fitting a model. For this we first stack the individual datasets: # In[ ]: dataset_stacked = Datasets(datasets_joint).stack_reduce() # Again we set the model on the dataset we would like to fit (in this case it's only a singel one) and pass it to the `Fit` object: # In[ ]: dataset_stacked.model = model stacked_fit = Fit([dataset_stacked]) result_stacked = stacked_fit.run() # make a copy to compare later model_best_stacked = model.copy() model_best_stacked.parameters.covariance = result_stacked.parameters.covariance # In[ ]: print(result_stacked) # In[ ]: model_best_joint.parameters.to_table()
# ### Spectral points # # Finally, let's compute spectral points. The method used is to first choose an energy binning, and then to do a 1-dim likelihood fit / profile to compute the flux and flux error. # In[ ]: # Flux points are computed on stacked observation stacked_dataset = Datasets(datasets).stack_reduce() print(stacked_dataset) # In[ ]: e_edges = np.logspace(0, 1.5, 5) * u.TeV stacked_dataset.model = model fpe = FluxPointsEstimator(datasets=[stacked_dataset], e_edges=e_edges) flux_points = fpe.run() flux_points.table_formatted # ### Plot # # Let's plot the spectral model and points. You could do it directly, but there is a helper class. # Note that a spectral uncertainty band, a "butterfly" is drawn, but it is very thin, i.e. barely visible. # In[ ]: model.spectral_model.parameters.covariance = result.parameters.covariance flux_points_dataset = FluxPointsDataset(data=flux_points, models=model)
model.spectral_model.parameters.covariance = joint_result.parameters.covariance print(joint_result) # Now you might want to do the stacking here even if in our case there is only one observation which makes it superfluous. # We can compute flux points by fitting the norm of the global model in energy bands. # In[ ]: e_edges = np.logspace(np.log10(0.04), np.log10(0.4), 7) * u.TeV dataset = Datasets(datasets).stack_reduce() dataset.model = model fpe = FluxPointsEstimator(datasets=[dataset], e_edges=e_edges) flux_points = fpe.run() flux_points.table["is_ul"] = flux_points.table["ts"] < 1 amplitude_ref = 0.57 * 19.4e-14 * u.Unit("1 / (cm2 s MeV)") spec_model_true = PowerLawSpectralModel( index=4.5, amplitude=amplitude_ref, reference="20 GeV" ) flux_points_dataset = FluxPointsDataset(data=flux_points, models=model) # Now we can plot.