Example to use the Sherpa plugin with the sherpa interface#

import jetset
print('tested with ',jetset.__version__)
tested with  1.4.0rc0

In this tutorial we show how to import a jetset model into Sherpa, and finally we perform a model fitting with Sherpa. To run this plugin you have to install Sherpa: https://sherpa.readthedocs.io/en/latest/install.html

import warnings
warnings.filterwarnings('ignore')

import matplotlib.pylab as plt
import jetset
from jetset.test_data_helper import  test_SEDs
from jetset.data_loader import ObsData,Data
from jetset.plot_sedfit import PlotSED
from jetset.test_data_helper import  test_SEDs
from jetset.test_data_helper import test_SEDs
test_SEDs
['/Users/orion/miniforge3/envs/jetset/lib/python3.12/site-packages/jetset/test_data/SEDs_data/SED_3C345.ecsv',
 '/Users/orion/miniforge3/envs/jetset/lib/python3.12/site-packages/jetset/test_data/SEDs_data/SED_MW_Mrk421_EBL_DEABS.ecsv',
 '/Users/orion/miniforge3/envs/jetset/lib/python3.12/site-packages/jetset/test_data/SEDs_data/SED_MW_Mrk501_EBL_ABS.ecsv',
 '/Users/orion/miniforge3/envs/jetset/lib/python3.12/site-packages/jetset/test_data/SEDs_data/SED_MW_Mrk501_EBL_DEABS.ecsv']

Loading data#

see the Data format and SED data user guide for further information about loading data

print(test_SEDs[2])
data=Data.from_file(test_SEDs[2])
/Users/orion/miniforge3/envs/jetset/lib/python3.12/site-packages/jetset/test_data/SEDs_data/SED_MW_Mrk501_EBL_ABS.ecsv
%matplotlib inline
sed_data=ObsData(data_table=data)
sed_data.group_data(bin_width=0.2)

sed_data.add_systematics(0.1,[10.**6,10.**29])
p=sed_data.plot_sed()
================================================================================

*  binning data  *
---> N bins= 88
---> bin_width= 0.2
================================================================================
../../../../_images/sherpa-plugin-sherpa-interface_10_1.png
sed_data.save('Mrk_501.pkl')

phenomenological model constraining#

see the Phenomenological model constraining: application user guide for further information about phenomenological constraining

spectral indices#

from jetset.sed_shaper import  SEDShape
my_shape=SEDShape(sed_data)
my_shape.eval_indices(minimizer='lsb',silent=True)
p=my_shape.plot_indices()
p.setlim(y_min=1E-15,y_max=1E-6)
================================================================================

* evaluating spectral indices for data *
================================================================================
../../../../_images/sherpa-plugin-sherpa-interface_15_1.png

sed shaper#

mm,best_fit=my_shape.sync_fit(check_host_gal_template=True,
                  Ep_start=None,
                  minimizer='lsb',
                  silent=True,
                  fit_range=[10.,21.])
================================================================================

* Log-Polynomial fitting of the synchrotron component *
---> first blind fit run,  fit range: [10.0, 21.0]
---> class:  HSP

---> class:  HSP
Table length=6
model namenamevalbestfit valerr +err -start valfit range minfit range maxfrozen
LogCubicb-5.589204e-02-5.589204e-026.234447e-03---5.237376e-02-1.000000e+010.000000e+00False
LogCubicc-3.292704e-04-3.292704e-048.967926e-04--7.639964e-03-1.000000e+011.000000e+01False
LogCubicEp1.698160e+011.698160e+018.582826e-02--1.556163e+010.000000e+003.000000e+01False
LogCubicSp-1.030620e+01-1.030620e+011.607947e-02---1.019011e+01-3.000000e+010.000000e+00False
host_galaxynuFnu_p_host-9.972939e+00-9.972939e+003.177493e-02---1.019011e+01-1.219011e+01-8.190114e+00False
host_galaxynu_scale-2.290459e-03-2.290459e-031.811351e-03--0.000000e+00-2.908697e-032.908697e-03False
---> sync       nu_p=+1.698160e+01 (err=+8.582826e-02)  nuFnu_p=-1.030620e+01 (err=+1.607947e-02) curv.=-5.589204e-02 (err=+6.234447e-03)
================================================================================
my_shape.IC_fit(fit_range=[23.,29.],minimizer='minuit',silent=True)
p=my_shape.plot_shape_fit()
p.setlim(y_min=1E-15)
================================================================================

* Log-Polynomial fitting of the IC component *
---> fit range: [23.0, 29.0]
---> LogCubic fit
Table length=4
model namenamevalbestfit valerr +err -start valfit range minfit range maxfrozen
LogCubicb-1.627265e-01-1.627265e-012.483991e-02---1.000000e+00-1.000000e+010.000000e+00False
LogCubicc-4.569970e-02-4.569970e-021.984551e-02---1.000000e+00-1.000000e+011.000000e+01False
LogCubicEp2.526444e+012.526444e+011.736457e-01--2.531190e+010.000000e+003.000000e+01False
LogCubicSp-1.057790e+01-1.057790e+014.914805e-02---1.000000e+01-3.000000e+010.000000e+00False
---> IC         nu_p=+2.526444e+01 (err=+1.736457e-01)  nuFnu_p=-1.057790e+01 (err=+4.914805e-02) curv.=-1.627265e-01 (err=+2.483991e-02)
================================================================================
../../../../_images/sherpa-plugin-sherpa-interface_18_3.png

Model constraining#

In this step we are not fitting the model, we are just obtaining the phenomenological pre_fit model, that will be fitted in using minuit ore least-square bound, as shown below

from jetset.obs_constrain import ObsConstrain
from jetset.model_manager import  FitModel
sed_obspar=ObsConstrain(beaming=25,
                        B_range=[0.001,0.1],
                        distr_e='lppl',
                        t_var_sec=3*86400,
                        nu_cut_IR=1E12,
                        SEDShape=my_shape)


prefit_jet=sed_obspar.constrain_SSC_model(electron_distribution_log_values=False,silent=True)
prefit_jet.save_model('prefit_jet.pkl')
================================================================================

*  constrains parameters from observable *
/Users/orion/miniforge3/envs/jetset/lib/python3.12/site-packages/jetset/obs_constrain.py:1514: RankWarning: Polyfit may be poorly conditioned
  p=polyfit(nu_p_IC_model_log,B_grid_log,2)
Table length=12
model namenamepar typeunitsvalphys. bound. minphys. bound. maxlogfrozen
jet_leptonicRregion_sizecm1.216622e+161.000000e+031.000000e+30FalseFalse
jet_leptonicR_Hregion_positioncm1.000000e+170.000000e+00--FalseTrue
jet_leptonicBmagnetic_fieldgauss5.050000e-020.000000e+00--FalseFalse
jet_leptonicNH_cold_to_rel_ecold_p_to_rel_e_ratio1.000000e+000.000000e+00--FalseTrue
jet_leptonicbeam_objbeaming2.500000e+011.000000e-04--FalseFalse
jet_leptonicz_cosmredshift3.360000e-020.000000e+00--FalseFalse
jet_leptonicgminlow-energy-cut-offlorentz-factor*4.703917e+021.000000e+001.000000e+09FalseFalse
jet_leptonicgmaxhigh-energy-cut-offlorentz-factor*2.121873e+061.000000e+001.000000e+15FalseFalse
jet_leptonicNemitters_density1 / cm35.583988e+000.000000e+00--FalseFalse
jet_leptonicgamma0_log_parabturn-over-energylorentz-factor*6.673207e+031.000000e+001.000000e+09FalseFalse
jet_leptonicsLE_spectral_slope2.251647e+00-1.000000e+011.000000e+01FalseFalse
jet_leptonicrspectral_curvature2.794602e-01-1.500000e+011.500000e+01FalseFalse
================================================================================
pl=prefit_jet.plot_model(sed_data=sed_data)
pl.add_model_residual_plot(prefit_jet,sed_data)
pl.setlim(y_min=1E-15,x_min=1E7,x_max=1E29)
../../../../_images/sherpa-plugin-sherpa-interface_22_0.png

Model fitting with using a Sherpa model#

we show now, how to import a jetset model into a Sherpa model

from jetset.sherpa_plugin import JetsetSherpaModel
from jetset.sherpa_plugin import sherpa_model_to_table
from jetset.template_2Dmodel import EBLAbsorptionTemplate
ebl_franceschini=EBLAbsorptionTemplate.from_name('Franceschini_2008')
from jetset.jet_model import Jet
prefit_jet=Jet.load_model('prefit_jet.pkl')

We remove the paramter NH_cold_to_rel_e, not used in the fit, because of problem encountered with the IntervalProjection Sherpa method

p=prefit_jet.parameters.get_par_by_name('NH_cold_to_rel_e')
prefit_jet.parameters.del_par(p)

The following instructions create a Sherpa model for each of the existing jetset models.

sherpa_model_jet=JetsetSherpaModel(prefit_jet)
sherpa_model_gal=JetsetSherpaModel(my_shape.host_gal)
sherpa_model_ebl=JetsetSherpaModel(ebl_franceschini)
jetset model name R renamed to  R_sh due to sherpa internal naming convention
sherpa_model=(sherpa_model_jet+sherpa_model_gal)*sherpa_model_ebl
sherpa_model
<BinaryOpModel model instance '(jet_leptonic + host_galaxy) * Franceschini_2008'>
sherpa_model_to_table(sherpa_model)
Table length=15
model namenamevalminmaxfrozenunitslinkedlinked parlinked model
str17str16float64float64float64boolobjectboolstr1str1
jet_leptonicgmin470.391748556435971.01000000000.0Falselorentz-factor*False
jet_leptonicgmax2121872.52211587551.01000000000000000.0Falselorentz-factor*False
jet_leptonicN5.58398842724368550.03.4028234663852886e+38False1 / cm3False
jet_leptonicgamma0_log_parab6673.2073944654411.01000000000.0Falselorentz-factor*False
jet_leptonics2.251646579731128-10.010.0FalseFalse
jet_leptonicr0.27946018220142366-15.015.0FalseFalse
jet_leptonicR_sh1.2166221781101818e+161000.01e+30FalsecmFalse
jet_leptonicR_H1e+170.03.4028234663852886e+38TruecmFalse
jet_leptonicB0.05050.03.4028234663852886e+38FalsegaussFalse
jet_leptonicbeam_obj25.00.00013.4028234663852886e+38FalseFalse
jet_leptonicz_cosm0.03360.03.4028234663852886e+38FalseFalse
host_galaxynuFnu_p_host-9.972939096864089-12.190114433380414-8.190114433380414Falseerg / (s cm2)False
host_galaxynu_scale-0.0022904594810536465-0.00290869660717404770.0029086966071740477FalseHzFalse
Franceschini_2008scale_factor1.00.03.4028234663852886e+38TrueFalse
Franceschini_2008z_cosm1.00.03.4028234663852886e+38TrueFalse
sherpa_model_ebl.z_cosm  = sherpa_model_jet.z_cosm
sherpa_model
<BinaryOpModel model instance '(jet_leptonic + host_galaxy) * Franceschini_2008'>
sherpa_model_to_table(sherpa_model)
Table length=15
model namenamevalminmaxfrozenunitslinkedlinked parlinked model
str17str16float64float64float64boolobjectboolstr6str12
jet_leptonicgmin470.391748556435971.01000000000.0Falselorentz-factor*False
jet_leptonicgmax2121872.52211587551.01000000000000000.0Falselorentz-factor*False
jet_leptonicN5.58398842724368550.03.4028234663852886e+38False1 / cm3False
jet_leptonicgamma0_log_parab6673.2073944654411.01000000000.0Falselorentz-factor*False
jet_leptonics2.251646579731128-10.010.0FalseFalse
jet_leptonicr0.27946018220142366-15.015.0FalseFalse
jet_leptonicR_sh1.2166221781101818e+161000.01e+30FalsecmFalse
jet_leptonicR_H1e+170.03.4028234663852886e+38TruecmFalse
jet_leptonicB0.05050.03.4028234663852886e+38FalsegaussFalse
jet_leptonicbeam_obj25.00.00013.4028234663852886e+38FalseFalse
jet_leptonicz_cosm0.03360.03.4028234663852886e+38FalseFalse
host_galaxynuFnu_p_host-9.972939096864089-12.190114433380414-8.190114433380414Falseerg / (s cm2)False
host_galaxynu_scale-0.0022904594810536465-0.00290869660717404770.0029086966071740477FalseHzFalse
Franceschini_2008scale_factor1.00.03.4028234663852886e+38TrueFalse
Franceschini_2008z_cosm0.03360.03.4028234663852886e+38TrueTruez_cosmjet_leptonic

Note

as you can notice the JetSet frozen state of the parameters has been inherited in sherpa, the line below shows how to freeze parameters in the sherpa model once the sherpa model has already been created

sherpa_model_jet.R_H.freeze()
sherpa_model_jet.z_cosm.freeze()
sherpa_model_gal.nu_scale.freeze()
sherpa_model_ebl.scale_factor.freeze()
sherpa_model_jet.beam_obj.min = 5
sherpa_model_jet.beam_obj.max = 50.

sherpa_model_jet.R_sh.min = 10**15.
sherpa_model_jet.R_sh.max = 10**17.5

sherpa_model_jet.gmax.min = 1E5
sherpa_model_jet.gmax.max = 1E7

sherpa_model_jet.gmin.min = 2
sherpa_model_jet.gmin.max = 1E3

sherpa_model_jet.s.min = 1.5
sherpa_model_jet.s.max = 3


sherpa_model_jet.r.min = 0.1
sherpa_model_jet.r.max = 2
sherpa_model
<BinaryOpModel model instance '(jet_leptonic + host_galaxy) * Franceschini_2008'>
sherpa_model_to_table(sherpa_model)
Table length=15
model namenamevalminmaxfrozenunitslinkedlinked parlinked model
str17str16float64float64float64boolobjectboolstr6str12
jet_leptonicgmin470.391748556435972.01000.0Falselorentz-factor*False
jet_leptonicgmax2121872.5221158755100000.010000000.0Falselorentz-factor*False
jet_leptonicN5.58398842724368550.03.4028234663852886e+38False1 / cm3False
jet_leptonicgamma0_log_parab6673.2073944654411.01000000000.0Falselorentz-factor*False
jet_leptonics2.2516465797311281.53.0FalseFalse
jet_leptonicr0.279460182201423660.12.0FalseFalse
jet_leptonicR_sh1.2166221781101818e+161000000000000000.03.1622776601683795e+17FalsecmFalse
jet_leptonicR_H1e+170.03.4028234663852886e+38TruecmFalse
jet_leptonicB0.05050.03.4028234663852886e+38FalsegaussFalse
jet_leptonicbeam_obj25.05.050.0FalseFalse
jet_leptonicz_cosm0.03360.03.4028234663852886e+38TrueFalse
host_galaxynuFnu_p_host-9.972939096864089-12.190114433380414-8.190114433380414Falseerg / (s cm2)False
host_galaxynu_scale-0.0022904594810536465-0.00290869660717404770.0029086966071740477TrueHzFalse
Franceschini_2008scale_factor1.00.03.4028234663852886e+38TrueFalse
Franceschini_2008z_cosm0.03360.03.4028234663852886e+38TrueTruez_cosmjet_leptonic
from sherpa import data
from sherpa.fit import Fit
from sherpa.stats import Chi2
from sherpa.optmethods import LevMar, NelderMead
sherpa_data=data.Data1D("sed", sed_data.table['nu_data'], sed_data.table['nuFnu_data'], staterror=sed_data.table['dnuFnu_data'])
fitter = Fit(sherpa_data, sherpa_model, stat=Chi2(), method=LevMar())
fit_range=[1e11,1e29]

sherpa_data.notice(fit_range[0], fit_range[1])
results = fitter.fit()
print("fit succeeded", results.succeeded)
fit succeeded True
results
<Fit results instance>
print(results)
datasets       = None
itermethodname = none
methodname     = levmar
statname       = chi2
succeeded      = True
parnames       = ('jet_leptonic.gmin', 'jet_leptonic.gmax', 'jet_leptonic.N', 'jet_leptonic.gamma0_log_parab', 'jet_leptonic.s', 'jet_leptonic.r', 'jet_leptonic.R_sh', 'jet_leptonic.B', 'jet_leptonic.beam_obj', 'host_galaxy.nuFnu_p_host')
parvals        = (282.88625455729, 1929468.7195682812, 6.222485756131704, 2627.670944162405, 2.1968609128619963, 0.17773127895038787, 1.6661000241195552e+16, 0.011725010326451955, 43.37906579397914, -9.967371696830856)
statval        = 13.998098958800451
istatval       = 147.73930624101467
dstatval       = 133.74120728221422
numpoints      = 31
dof            = 21
qval           = 0.8696809139492879
rstat          = 0.6665761408952596
message        = successful termination
nfev           = 391
sherpa_model
<BinaryOpModel model instance '(jet_leptonic + host_galaxy) * Franceschini_2008'>
sherpa_model_to_table(sherpa_model)
Table length=15
model namenamevalminmaxfrozenunitslinkedlinked parlinked model
str17str16float64float64float64boolobjectboolstr6str12
jet_leptonicgmin282.886254557292.01000.0Falselorentz-factor*False
jet_leptonicgmax1929468.7195682812100000.010000000.0Falselorentz-factor*False
jet_leptonicN6.2224857561317040.03.4028234663852886e+38False1 / cm3False
jet_leptonicgamma0_log_parab2627.6709441624051.01000000000.0Falselorentz-factor*False
jet_leptonics2.19686091286199631.53.0FalseFalse
jet_leptonicr0.177731278950387870.12.0FalseFalse
jet_leptonicR_sh1.6661000241195552e+161000000000000000.03.1622776601683795e+17FalsecmFalse
jet_leptonicR_H1e+170.03.4028234663852886e+38TruecmFalse
jet_leptonicB0.0117250103264519550.03.4028234663852886e+38FalsegaussFalse
jet_leptonicbeam_obj43.379065793979145.050.0FalseFalse
jet_leptonicz_cosm0.03360.03.4028234663852886e+38TrueFalse
host_galaxynuFnu_p_host-9.967371696830856-12.190114433380414-8.190114433380414Falseerg / (s cm2)False
host_galaxynu_scale-0.0022904594810536465-0.00290869660717404770.0029086966071740477TrueHzFalse
Franceschini_2008scale_factor1.00.03.4028234663852886e+38TrueFalse
Franceschini_2008z_cosm0.03360.03.4028234663852886e+38TrueTruez_cosmjet_leptonic
from jetset.sherpa_plugin import plot_sherpa_model
p=plot_sherpa_model(sherpa_model_jet,label='SSC',line_style='--')
p=plot_sherpa_model(sherpa_model_gal,plot_obj=p,label='host gal',line_style='--')
p=plot_sherpa_model(sherpa_model=sherpa_model,plot_obj=p,sed_data=sed_data,fit_range=fit_range,add_res=True,label='(SSC+host gal)*ebl')
../../../../_images/sherpa-plugin-sherpa-interface_53_0.png

You can access all the sherpa fetarues https://sherpa.readthedocs.io/en/latest/fit/index.html

from sherpa.plot import IntervalProjection
iproj = IntervalProjection()
iproj.prepare(fac=5, nloop=15)
iproj.calc(fitter, sherpa_model_jet.s)
iproj.plot()
WARNING: hard minimum hit for parameter jet_leptonic.gmin
WARNING: hard maximum hit for parameter jet_leptonic.gmin
WARNING: hard minimum hit for parameter jet_leptonic.gmax
WARNING: hard maximum hit for parameter jet_leptonic.gmax
WARNING: hard minimum hit for parameter jet_leptonic.B
WARNING: hard maximum hit for parameter jet_leptonic.B
../../../../_images/sherpa-plugin-sherpa-interface_55_1.png