Skip to content

Commit fbe30d8

Browse files
authored
Merge pull request #242 from icecube/CutoffPL_fix
Implement CutoffPowerLaw Fluxes with public data
2 parents 3aa71e5 + 977f2ec commit fbe30d8

File tree

2 files changed

+79
-8
lines changed

2 files changed

+79
-8
lines changed

skyllh/analyses/i3/publicdata_ps/time_integrated_ps.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
SpatialBoxEventSelectionMethod,
4343
)
4444
from skyllh.core.flux_model import (
45+
CutoffPowerLawEnergyFluxProfile,
4546
PowerLawEnergyFluxProfile,
4647
SteadyPointlikeFFM,
4748
)
@@ -134,6 +135,7 @@ def create_analysis(
134135
refplflux_Phi0=1,
135136
refplflux_E0=1e3,
136137
refplflux_gamma=2.0,
138+
refplflux_Ec=np.inf,
137139
ns_seed=10.0,
138140
ns_min=0.,
139141
ns_max=1e3,
@@ -171,6 +173,8 @@ def create_analysis(
171173
The reference energy to use for the reference power law flux model.
172174
refplflux_gamma : float
173175
The spectral index to use for the reference power law flux model.
176+
refplflux_Ec: float,
177+
The cutoff energy for the cutoff power law flux model.
174178
ns_seed : float
175179
Value to seed the minimizer with for the ns fit.
176180
ns_min : float
@@ -269,15 +273,28 @@ def create_analysis(
269273
dtc_except_fields = ['mcweight', 'time']
270274

271275
# Define the flux model.
272-
fluxmodel = SteadyPointlikeFFM(
273-
Phi0=refplflux_Phi0,
274-
energy_profile=PowerLawEnergyFluxProfile(
275-
E0=refplflux_E0,
276-
gamma=refplflux_gamma,
276+
if refplflux_Ec == np.inf:
277+
fluxmodel = SteadyPointlikeFFM(
278+
Phi0=refplflux_Phi0,
279+
energy_profile=PowerLawEnergyFluxProfile(
280+
E0=refplflux_E0,
281+
gamma=refplflux_gamma,
282+
cfg=cfg,
283+
),
277284
cfg=cfg,
278-
),
279-
cfg=cfg,
280-
)
285+
)
286+
else:
287+
fluxmodel = SteadyPointlikeFFM(
288+
Phi0=refplflux_Phi0,
289+
energy_profile=CutoffPowerLawEnergyFluxProfile(
290+
E0=refplflux_E0,
291+
gamma=refplflux_gamma,
292+
Ecut=refplflux_Ec, #in GeV
293+
cfg=cfg,
294+
),
295+
cfg=cfg,
296+
)
297+
281298

282299
# Define the fit parameter ns.
283300
param_ns = Parameter(

skyllh/core/flux_model.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,60 @@ def __call__(
771771
values *= np.exp(-E / self._Ecut)
772772

773773
return values
774+
def get_integral(
775+
self,
776+
E1,
777+
E2,
778+
unit=None,
779+
):
780+
"""This falls back to the default implementation for the CutoffPowerLawEnergyFluxProfile
781+
to avoid using the inhereted function
782+
.. note::
783+
784+
This implementation utilizes the ``scipy.integrate.quad`` function
785+
to perform a generic numeric integration. Hence, this implementation
786+
is slow and should be reimplemented by the derived class if an
787+
analytic integral form is available.
788+
789+
Parameters
790+
----------
791+
E1 : float | 1d numpy ndarray of float
792+
The lower energy bound of the integration.
793+
E2 : float | 1d numpy ndarray of float
794+
The upper energy bound of the integration.
795+
unit : instance of astropy.units.UnitBase | None
796+
The unit of the given energies.
797+
If set to ``None``, the set energy unit of this EnergyFluxProfile
798+
instance is assumed.
799+
800+
Returns
801+
-------
802+
integral : instance of ndarray
803+
The (n,)-shaped numpy ndarray holding the integral values of the
804+
given integral ranges.
805+
"""
806+
E1 = np.atleast_1d(E1)
807+
E2 = np.atleast_1d(E2)
808+
809+
if (unit is not None) and (unit != self._energy_unit):
810+
time_unit_conv_factor = unit.to(self._energy_unit)
811+
E1 = E1 * time_unit_conv_factor
812+
E2 = E2 * time_unit_conv_factor
813+
814+
integral = np.empty((len(E1),), dtype=np.float64)
815+
816+
for (i, (E1_i, E2_i)) in enumerate(zip(E1, E2)):
817+
818+
# integration for log(energy) for hopefully better numerical stability
819+
tmp_e = np.linspace(np.log10(E1_i), np.log10(E2_i), 5000)
820+
tmp_int = np.trapz(np.log(10) * self(10**tmp_e) * 10**tmp_e, tmp_e)
821+
822+
# make sure it is always positive (probably not an issue any more with np.trapz.
823+
# used to be an issue using the spline integrate self.function.integrate)
824+
integral[i] = max(0.0, tmp_int)
825+
826+
return integral
827+
774828

775829

776830
class LogParabolaPowerLawEnergyFluxProfile(

0 commit comments

Comments
 (0)