Ejemplo n.º 1
0
def ElectronEblAbsorbedSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10**pars[0] / u.eV
    e_break = (10**pars[1]) * u.TeV
    alpha1 = pars[2]
    alpha2 = pars[3]
    B = pars[4] * u.uG

    # Define the redshift of the source, and absorption model
    redshift = pars[5] * u.dimensionless_unscaled
    EBL_transmitance = EblAbsorptionModel(redshift, "Dominguez")

    # Initialize instances of the particle distribution and radiative models
    BPL = BrokenPowerLaw(amplitude, 1.0 * u.TeV, e_break, alpha1, alpha2)

    # Compute IC on a CMB component
    IC = InverseCompton(BPL, seed_photon_fields=["CMB"], Eemin=10 * u.GeV)
    SYN = Synchrotron(BPL, B=B)

    # compute flux at the energies given in data['energy']
    model = EBL_transmitance.transmission(data) * IC.flux(
        data, distance=1.0 * u.kpc) + SYN.flux(data, distance=1.0 * u.kpc)

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Ejemplo n.º 2
0
def ElectronIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10 ** pars[2]) * u.TeV

    # Initialize instances of the particle distribution and radiative model
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10.0 * u.TeV, alpha, e_cutoff)
    # Compute IC on CMB and on a FIR component with values from GALPROP for the
    # position of RXJ1713
    IC = InverseCompton(
        ECPL,
        seed_photon_fields=[
            "CMB",
            ["FIR", 26.5 * u.K, 0.415 * u.eV / u.cm ** 3],
        ],
        Eemin=100 * u.GeV,
    )

    # compute flux at the energies given in data['energy'], and convert to units
    # of flux data
    model = IC.flux(data, distance=1.0 * u.kpc).to(data["flux"].unit)

    # Save this realization of the particle distribution function
    elec_energy = np.logspace(11, 15, 100) * u.eV
    nelec = ECPL(elec_energy)

    # Compute and save total energy in electrons above 1 TeV
    We = IC.compute_We(Eemin=1 * u.TeV)

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stores in the sampler metadata
    # blobs.
    return model, (elec_energy, nelec), We
Ejemplo n.º 3
0
def ElectronIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10**pars[2]) * u.TeV

    # Initialize instances of the particle distribution and radiative model
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10. * u.TeV, alpha, e_cutoff)
    IC = InverseCompton(ECPL,
                        seed_photon_fields=[
                            'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
                        ])

    # compute flux at the energies given in data['energy'], and convert to
    # units of flux data
    model = IC.flux(data, distance=1.0 * u.kpc)

    # Save this realization of the particle distribution function
    elec_energy = np.logspace(11, 15, 100) * u.eV
    nelec = ECPL(elec_energy)

    # Compute and save total energy in electrons above 1 TeV
    We = IC.compute_We(Eemin=1 * u.TeV)

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stores in the sampler metadata
    # blobs.
    return model, (elec_energy, nelec), We
Ejemplo n.º 4
0
def ElectronSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10 ** pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10 ** pars[2]) * u.TeV
    B = pars[3] * u.uG

    # Initialize instances of the particle distribution and radiative models
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10.0 * u.TeV, alpha, e_cutoff)
    # Compute IC on CMB and on a FIR component with values from GALPROP for the
    # position of RXJ1713
    IC = InverseCompton(
        ECPL,
        seed_photon_fields=[
            "CMB",
            ["FIR", 26.5 * u.K, 0.415 * u.eV / u.cm ** 3],
        ],
        Eemin=100 * u.GeV,
    )
    SYN = Synchrotron(ECPL, B=B)

    # compute flux at the energies given in data['energy']
    model = IC.flux(data, distance=1.0 * u.kpc) + SYN.flux(
        data, distance=1.0 * u.kpc
    )

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Ejemplo n.º 5
0
def ElectronSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10**pars[0] / u.eV
    alpha = pars[1]
    e_cutoff = (10**pars[2]) * u.TeV
    B = pars[3] * u.uG

    # Initialize instances of the particle distribution and radiative models
    ECPL = ExponentialCutoffPowerLaw(amplitude, 10. * u.TeV, alpha, e_cutoff)
    # Compute IC on CMB and on a FIR component with values from GALPROP for the
    # position of RXJ1713
    IC = InverseCompton(ECPL,
                        seed_photon_fields=[
                            'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
                        ],
                        Eemin=100 * u.GeV)
    SYN = Synchrotron(ECPL, B=B)

    # compute flux at the energies given in data['energy']
    model = (IC.flux(data, distance=1.0 * u.kpc) +
             SYN.flux(data, distance=1.0 * u.kpc))

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Ejemplo n.º 6
0
def ElectronEblAbsorbedSynIC(pars, data):

    # Match parameters to ECPL properties, and give them the appropriate units
    amplitude = 10**pars[0] / u.eV
    e_break = (10**pars[1]) * u.TeV
    alpha1 = pars[2]
    alpha2 = pars[3]
    B = pars[4] * u.uG

    # Define the redshift of the source, and absorption model
    redshift = pars[5] * u.dimensionless_unscaled
    EBL_transmitance = EblAbsorptionModel(redshift, 'Dominguez')

    # Initialize instances of the particle distribution and radiative models
    BPL = BrokenPowerLaw(amplitude, 1. * u.TeV, e_break, alpha1, alpha2)

    # Compute IC on a CMB component
    IC = InverseCompton(
        BPL,
        seed_photon_fields=['CMB'],
        Eemin=10 * u.GeV)
    SYN = Synchrotron(BPL, B=B)

    # compute flux at the energies given in data['energy']
    model = (EBL_transmitance.transmission(data) * IC.flux(data, distance=1.0 * u.kpc) +
             SYN.flux(data, distance=1.0 * u.kpc))

    # The first array returned will be compared to the observed spectrum for
    # fitting. All subsequent objects will be stored in the sampler metadata
    # blobs.
    return model, IC.compute_We(Eemin=1 * u.TeV)
Ejemplo n.º 7
0
def ElectronIC(pars, data):
    """
    Define particle distribution model, radiative model, and return model flux
    at data energy values
    """

    ECPL = ExponentialCutoffPowerLaw(pars[0] / u.eV, 10.0 * u.TeV, pars[1],
                                     10**pars[2] * u.TeV)
    IC = InverseCompton(ECPL, seed_photon_fields=["CMB"])

    return IC.flux(data, distance=1.0 * u.kpc)
Ejemplo n.º 8
0
def ElectronIC(pars, data):
    """
    Define particle distribution model, radiative model, and return model flux
    at data energy values
    """

    ECPL = ExponentialCutoffPowerLaw(pars[0] / u.eV, 10. * u.TeV, pars[1],
                                     10**pars[2] * u.TeV)
    IC = InverseCompton(ECPL, seed_photon_fields=['CMB'])

    return IC.flux(data, distance=1.0 * u.kpc)
Ejemplo n.º 9
0
class ElectronIC(SpectralModel):
    """This class inherits from SpectralModel in 3ML, and can be used
    to infer the population of electrons in a source.  The fit works 
    as follows:

    1. Choose a parametric form for the electron spectrum, e.g., a power
       law with an exponential cutoff.
    2. Use Inverse Compton scattering to calculate the gamma-ray flux.
    3. Fit the calculated gamma-ray flux to the data using one of the
       plugins available in 3ML.

    The free parameters of this model include the parameters of the
    electron spectrum and the distance to the source.
    
    Additional quantities which affect the calculation are the components
    of the interstellar radiation field (ISRF) which contribute to the IC
    flux.  These are not floated in the fit.  Users may wish to obtain an
    estimate of the ISRF in the vicinity of the source of interest using
    GALPROP.
    """
    def setup(self):
        self.functionName = "ElectronIC"
        self.formula = r"$f(E)=A(E/E_{\rm piv}}^\gamma}$"

        self.parameters = collections.OrderedDict()
        self.parameters["gamma"] = Parameter("gamma",
                                             -2.,
                                             -10.,
                                             10,
                                             0.1,
                                             fixed=False,
                                             nuisance=False,
                                             dataset=None)
        self.parameters["logA"] = Parameter("logA",
                                            -4.,
                                            -40.,
                                            30,
                                            0.1,
                                            fixed=False,
                                            nuisance=False,
                                            dataset=None)
        self.parameters["Epiv"] = Parameter("Epiv",
                                            1.,
                                            1e-10,
                                            1e10,
                                            1.,
                                            fixed=True,
                                            unit="keV")
        self.parameters["dist"] = Parameter("dist",
                                            1.,
                                            1e-10,
                                            1e10,
                                            1.,
                                            fixed=True)
        self.ncalls = 0

        self.pdist_unit = 1. / u.Unit(m_e * c**2)
        self.PL = PowerLaw(1 * self.pdist_unit, 1 * u.keV, -2.5)
        self.IC = InverseCompton(
            self.PL,
            seed_photon_fields=[
                'CMB', ['FIR', 26.5 * u.K, 0.415 * u.eV / u.cm**3]
            ],
            Eemin=1 * u.TeV)

    #        def integral(E1, E2):
    #            a  = self.parameters["gamma"].value
    #            Ep = self.parameters["Epiv"].value
    #            A  = 10.**self.parameters["logA"].value
    #
    #            if a == -1.:
    #                def f(energy):
    #                    return A * E0 * np.log(energy)
    #            else:
    #                def f(energy):
    #                    return A * energy * (energy/Ep)**a / (a + 1.)
    #            return f(E2) - f(E1)
    #
    #        self.integral = integral

    def __call__(self, energy):
        #        pdist_unit = 1. / u.Unit(m_e * c**2)

        self.ncalls += 1

        # Convert spectral index to naima sign convention
        a = -self.parameters["gamma"].value

        # Convert to naima base units: all energies in keV
        Ep = self.parameters["Epiv"].value * u.keV

        # Normalization is actually for electron differential spectrum
        A = 10.**self.parameters["logA"].value * self.pdist_unit

        # Initialize the electron particle distribution
        self.PL.amplitude = A
        self.PL.e_0 = Ep
        self.PL.alpha = a

        # Fix the distance of the source, in kpc
        dist = self.parameters["dist"].value * u.kpc

        if type(energy) is float or type(energy) is int:
            E = [energy] * u.keV
        else:
            E = energy * u.keV

        icFlux = self.IC.flux(E, distance=dist)
        return icFlux.to(1. / (u.keV * u.cm**2 * u.s)).value

    def electronFlux(self, energy):
        # Convert spectral index to naima sign convention
        a = -self.parameters["gamma"].value

        # Convert to naima base units: all energies in keV
        Ep = self.parameters["Epiv"].value * u.keV

        # Normalization is actually for electron differential spectrum
        A = 10.**self.parameters["logA"].value * self.pdist_unit

        # Initialize the electron particle distribution
        PL = PowerLaw(A, Ep, a)

        if type(energy) is float or type(energy) is int:
            E = [energy] * u.keV
        else:
            E = energy * u.keV

        return PL(E).to(1. / u.keV).value

    def photonFlux(self, E1, E2):
        return self.integral(E1, E2)

    def energyFlux(self, E1, E2):
        a = self.parameters["gamma"].value
        Ep = self.parameters["Epiv"].value
        A = 10.**self.parameters["logA"].value

        if a == 2:

            def eF(E):
                return np.maximum(A * np.log(E / Ep), 1e-100)
        else:

            def eF(E):
                return np.maximum(A * np.power(E / Ep, 2 - a) / (2 - a),
                                  1e-100)

        return (eF(E2) - eF(E1)) * self.keVtoErg
# In[47]:

#gamma-ray flux dN/dE

#energies at which we want to evaluate the spectrum
Egamma = np.logspace(-6, 5, 100) * u.GeV

#source distance
D=2*u.kpc

#get_ipython().magic(u'matplotlib inline')

plt.clf()
plt.loglog(Egamma, synch.flux(Egamma, distance=D), label="Synchrotron emission")
plt.loglog(Egamma, IC.flux(Egamma, distance=D), label="IC emission")
plt.loglog(Egamma, brems.flux(Egamma, distance=D), label="Bremsstrahlung")
plt.ylabel("Emission spectrum dN/dE [1/eV/cm^2/s]")
plt.xlabel("Photon energy [GeV]")
plt.ylim(1e-30,1e2)
plt.legend()

plt.savefig("PhotonFlux.png" )

# In[49]:

#gamma-ray SED E^2 dN/dE

#energies at which we want to evaluate the spectrum
Egamma = np.logspace(-6, 6, 100) * u.GeV
Ejemplo n.º 11
0
#gamma-ray flux dN/dE

#energies at which we want to evaluate the spectrum
Egamma = np.logspace(-6, 5, 100) * u.GeV

#source distance
D = 2 * u.kpc

#get_ipython().magic(u'matplotlib inline')

plt.clf()
plt.loglog(Egamma,
           synch.flux(Egamma, distance=D),
           label="Synchrotron emission")
plt.loglog(Egamma, IC.flux(Egamma, distance=D), label="IC emission")
plt.loglog(Egamma, brems.flux(Egamma, distance=D), label="Bremsstrahlung")
plt.ylabel("Emission spectrum dN/dE [1/eV/cm^2/s]")
plt.xlabel("Photon energy [GeV]")
plt.ylim(1e-30, 1e2)
plt.legend()

plt.savefig("PhotonFlux.png")

# In[49]:

#gamma-ray SED E^2 dN/dE

#energies at which we want to evaluate the spectrum
Egamma = np.logspace(-6, 6, 100) * u.GeV