def trapz_loglog(y, x, axis=-1): """Integrate using the composite trapezoidal rule in log-log space. Integrate `y` (`x`) along given axis in loglog space. Parameters ---------- y : array_like Input array to integrate. x : array_like, optional Independent variable to integrate over. axis : int, optional Specify the axis. Returns ------- trapz : float Definite integral as approximated by trapezoidal rule in loglog space. """ from gammapy.modeling.models import PowerLawSpectralModel as pl # see https://stackoverflow.com/a/56840428 x, y = np.moveaxis(x, axis, 0), np.moveaxis(y, axis, 0) energy_min, energy_max = x[:-1], x[1:] vals_energy_min, vals_energy_max = y[:-1], y[1:] # log scale has the build-in zero clipping log = LogScale() with np.errstate(invalid="ignore", divide="ignore"): index = -log(vals_energy_min / vals_energy_max) / log(energy_min / energy_max) index[np.isnan(index)] = np.inf return pl.evaluate_integral( energy_min=energy_min, energy_max=energy_max, index=index, reference=energy_min, amplitude=vals_energy_min, )
def _dnde_from_flux(flux, model, e_ref, e_min, e_max, pwl_approx): """Helper for `to_sed_type`. Compute dnde under the assumption that flux equals expected flux from model. """ dnde_model = model(e_ref) if pwl_approx: index = model.spectral_index(e_ref) flux_model = PowerLawSpectralModel.evaluate_integral( emin=e_min, emax=e_max, index=index, reference=e_ref, amplitude=dnde_model, ) else: flux_model = model.integral(e_min, e_max, intervals=True) return dnde_model * (flux / flux_model)