def _setup(self): self.interpolator = MyInterpolator() self.cache = {} self._band_model = Band()
def test_call_with_composite_function_with_units(): def one_test(spectrum): print("Testing %s" % spectrum.expression) pts = PointSource("test", ra=0, dec=0, spectral_shape=spectrum) res = pts([100, 200] * u.keV) # This will fail if the units are wrong res.to(1 / (u.keV * u.cm**2 * u.s)) # Test a simple composition spectrum = Powerlaw() * Exponential_cutoff() one_test(spectrum) spectrum = Band() + Blackbody() one_test(spectrum) # Test a more complicate composition spectrum = Powerlaw() * Exponential_cutoff() + Blackbody() one_test(spectrum) spectrum = Powerlaw() * Exponential_cutoff() * Exponential_cutoff( ) + Blackbody() one_test(spectrum) if has_xspec: spectrum = XS_phabs() * Powerlaw() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() * XS_phabs() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() * XS_phabs() + Blackbody() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() * XS_phabs() + XS_powerlaw() one_test(spectrum)
def get_comparison_function(): mo = Band() mo.K = 1 return mo
class BandPPTemplate(Function1D): r""" description : A Band model multiplied by a pair-production opacity computed by interpolating templates from the pyggop code latex : $ $ parameters : K : desc : Differential flux at 100 keV initial value : 1e-4 alpha : desc : low-energy photon index initial value : -1.0 min : -1.5 max : 0.0 xp : desc : peak energy in the nuFnu spectrum initial value : 350 min : 1 max : 1e5 beta : desc : high-energy photon index initial value : -2.0 min : -2.3 max : -1.7 xc : desc : cutoff energy initial value : 3e4 DRbar : desc : drbar initial value : 1 min : 0.1 max : 130 piv : desc : pivot energy initial value : 100.0 fix : yes """ __metaclass__ = FunctionMeta def _setup(self): self.interpolator = MyInterpolator() self.cache = {} self._band_model = Band() def set_templates_dir(self, directory): self.interpolator = MyInterpolator(directory) self.cache = {} def set_template(self, templateInstance): self.templateInstance = templateInstance def _set_units(self, x_unit, y_unit): # The normalization has the same units as y self.K.unit = y_unit # The break point has always the same dimension as the x variable self.xp.unit = x_unit self.xc.unit = x_unit self.piv.unit = x_unit # alpha and beta are dimensionless self.alpha.unit = astropy_units.dimensionless_unscaled self.beta.unit = astropy_units.dimensionless_unscaled self.DRbar.unit = astropy_units.dimensionless_unscaled def evaluate(self, x, K, alpha, xp, beta, xc, DRbar, piv): if alpha < beta: raise ModelAssertionViolation("Alpha cannot be less than beta") #if xc <= xp: # raise ModelAssertionViolation("Ec cannot be less than Ep") out = self._band_model.evaluate(x, K, alpha, xp, beta, piv) key = ("%.5f, %.4g" % (beta, DRbar)) if key in self.cache.keys(): # Logarithm of the flux template = numpy.array(self.cache[key], copy=True) else: # Logarithm of the flux template = self.interpolator.get_template(beta * (-1), DRbar) self.cache[key] = numpy.array(template, copy=True) pass # Energy grid in "observed energy" ee = self.interpolator.eneGrid * xc # Interpolate in the log space interpolation = numpy.interp(numpy.log10(x), numpy.log10(ee), template) # Go back to the flux space cc = numpy.power(10, interpolation) # Now go to photon flux cc = cc / np.power(x, -beta) # Correct the extremes in case the template does not cover them #idx = (x / xc < self.interpolator.eneGrid.min()) #cc[idx] = cc.max() idx = (x / xc > self.interpolator.eneGrid.max()) cc[idx] = 1e-35 # Match the Band spectrum and the template at E0 E0 = xp / (2 + alpha) Ec = (alpha - beta) * E0 # Diff. flux of the Band spectrum at Ec flux_at_Ec = self._band_model.evaluate(np.array(Ec, ndmin=1), K, alpha, xp, beta, piv) # Template at Ec template_at_Ec = pow(10, numpy.interp(numpy.log10(Ec), numpy.log10(ee), template)) / pow(Ec, -beta) idx = (x >= Ec) # Renorm factor renorm = flux_at_Ec / template_at_Ec cc = renorm * cc # Now join the Band spectrum and the template out[idx] = cc[idx] # This should be np.power(x, -beta) * out * cc / np.power(x, -beta), which of course simplify to: #out = out * cc # This fixes nan(s) and inf values, converting them respectively to zeros and large numbers out = numpy.nan_to_num(out) return out
def test_call_with_composite_function_with_units(): def one_test(spectrum): print(("Testing %s" % spectrum.expression)) # # if we have fixed x_units then we will use those # # in the test # # if spectrum.expression.has_fixed_units(): # # x_unit_to_use, y_unit_to_use = spectrum.expression.fixed_units[0] # # else: x_unit_to_use = u.keV pts = PointSource("test", ra=0, dec=0, spectral_shape=spectrum) res = pts([100, 200] * x_unit_to_use) # This will fail if the units are wrong res.to(1 / (u.keV * u.cm**2 * u.s)) # Test a simple composition spectrum = Powerlaw() * Exponential_cutoff() one_test(spectrum) spectrum = Band() + Blackbody() one_test(spectrum) # Test a more complicate composition spectrum = Powerlaw() * Exponential_cutoff() + Blackbody() one_test(spectrum) spectrum = Powerlaw() * Exponential_cutoff() * Exponential_cutoff() + Blackbody() one_test(spectrum) if has_xspec: spectrum = XS_phabs() * Powerlaw() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() * XS_phabs() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() * XS_phabs() + Blackbody() one_test(spectrum) spectrum = XS_phabs() * XS_powerlaw() * XS_phabs() + XS_powerlaw() one_test(spectrum)