Exemple #1
0
def plot_S_model():
    # Debug plotting
    B = 5e-10
    print('huhu')
    nu_range = np.logspace(np.log10(30e6), 9, 6)
    age_range = np.linspace(0, 200, 5)

    from agnpy.emission_regions import Blob
    from agnpy.synchrotron import Synchrotron
    blob = Blob(z=0.001,
                B=10**4 * B * u.gauss,
                spectrum_dict={
                    "type": "PowerLaw",
                    "parameters": {
                        "p": 2.3,
                        "gamma_min": 2,
                        "gamma_max": 1e7
                    }
                })
    synch = Synchrotron(blob)
    sed = synch.sed_flux(nu_range * u.Hz)
    sed = sed.value / nu_range

    results = np.zeros((len(age_range), len(nu_range)))
    for i, age in enumerate(age_range):
        with mp.Pool() as p:
            results[i] = p.starmap(S_model, [[nu, B, 0.65, 1000, age]
                                             for nu in nu_range])
        print(results[i], nu_range)

    PL = (nu_range**-0.65)
    PL /= (PL[0] / sed[0])
    print((results[0, 0] / sed[0]))
    results /= (results[0, 0] / sed[0])

    import matplotlib.pyplot as plt
    plt.close()
    print(nu_range, sed)
    plt.plot(nu_range, sed, c='k', label=f'AGNPY for 0 Myr; B = {B}T')
    plt.plot(nu_range, PL, label=f'PL alpha = 0.65', c='k', ls='dotted')
    for age, res in zip(age_range, results):
        plt.plot(nu_range, res, label=f'{age}Myr; B = {B}T')
    plt.xscale('log')
    plt.yscale('log')
    plt.xlabel('frequency [Hz]')
    plt.ylabel('S')
    # plt.xlim([np.min(nu_range), np.max(nu_range)])
    # plt.ylim([np.min(res), 1.05*np.max(res)])
    plt.legend()
    plt.savefig(
        __file__.replace('lib_aging.py', '') +
        'lib_aging_data/synch_vs_nu.png')
Exemple #2
0
 def test_ssa_reference_sed(
     self,
     file_ref,
     spectrum_type,
     spectrum_parameters,
     figure_title,
     figure_path,
 ):
     """test SSA SED generated by a given electron distribution against the 
     ones generated with jetset version 1.1.2, via jetset_ssa_sed.py script"""
     # reference SED
     nu_ref, sed_ref = extract_columns_sample_file(file_ref, "Hz",
                                                   "erg cm-2 s-1")
     # same parameters used to produce the jetset SED
     spectrum_norm = 1e2 * u.Unit("cm-3")
     spectrum_dict = {
         "type": spectrum_type,
         "parameters": spectrum_parameters
     }
     blob = Blob(
         R_b=5e15 * u.cm,
         z=0.1,
         delta_D=10,
         Gamma=10,
         B=0.1 * u.G,
         spectrum_norm=spectrum_norm,
         spectrum_dict=spectrum_dict,
     )
     # recompute the SED at the same ordinates where the figure was sampled
     ssa = Synchrotron(blob, ssa=True)
     sed_agnpy = ssa.sed_flux(nu_ref)
     # sed comparison plot, we will check between 10^(11) and 10^(19) Hz
     nu_range = [1e11, 1e19] * u.Hz
     make_comparison_plot(
         nu_ref,
         sed_agnpy,
         sed_ref,
         "agnpy",
         "jetset 1.1.2",
         figure_title,
         figure_path,
         "sed",
         comparison_range=nu_range.to_value("Hz"),
     )
     # requires that the SED points deviate less than 5% from the figure
     assert check_deviation(nu_ref, sed_agnpy, sed_ref, 0.05, nu_range)
Exemple #3
0
    def test_absorption_pointlike_and_homogeneous(self):
        """Simple test for checking the attenuation factors in both considered cases."""

        blob = Blob()
        absorb = Absorption(blob)

        nu_tau = np.logspace(22, 34, 100) * u.Hz  # for absorption calculations

        tau = absorb.tau(nu_tau)
        abs_pointlike = absorb.absorption(nu_tau)
        abs_homogeneous = absorb.absorption_homogeneous(nu_tau)
        # select good points (to avoid division by zero)
        idxs = tau > 1.0e-3
        # if this fails something is wrong with the test itself (e.g. default parameters of the blob)
        assert sum(idxs) > 10

        # the formulas reproduce what should be in the function, so the agreement should be down to numerical accuracy
        assert np.allclose(np.exp(-tau), abs_pointlike, atol=1.0e-5)
        assert np.allclose((1 - np.exp(-tau)) / tau,
                           abs_homogeneous,
                           atol=1.0e-5)
Exemple #4
0
    },
}

R_b = 1e16 * u.cm
B = 1 * u.G
z = Distance(1e27, unit=u.cm).z
delta_D = 10
Gamma = 10

for spectrum_dict in (spectrum_dict_pwl, spectrum_dict_bpl, spectrum_dict_bpl_2):
    for norm_type in ("integral", "differential", "gamma=1"):
        blob = Blob(
            R_b,
            z,
            delta_D,
            Gamma,
            B,
            spectrum_norm,
            spectrum_dict,
            spectrum_norm_type=norm_type,
        )
        blob.plot_n_e()

# let us trigger the error
blob = Blob(
    R_b,
    z,
    delta_D,
    Gamma,
    B,
    1e48 * u.Unit("erg"),
    spectrum_dict_bpl_2,
Exemple #5
0
r0 = 1.0e14 * u.m
dist = 3.0e16 * u.cm
xi = 1.0e-4
nu = np.logspace(8, 26, 200) * u.Hz
norm = 15000.0 * u.Unit("cm-3")

parameters = {
    "p1": 2.0,
    "p2": 3.0,
    "gamma_b": gbreak,
    "gamma_min": gmin0,
    "gamma_max": gmax0,
}
spectrum_dict = {"type": "BrokenPowerLaw", "parameters": parameters}

blob = Blob(r0, z, delta_D, Gamma, B0, norm, spectrum_dict, xi=xi)

# plt.loglog(blob.gamma, blob.n_e (blob.gamma))

#############################################
# limits from confinement of particles inside the blob:
gmaxconf = blob.gamma_max_larmor
# computing larmor radius of this electron, should be of the size of the blob
# R_L = 33.36 km * (p/(GeV/c)) * (G/B) * Z^-1
# https://w3.iihe.ac.be/~aguilar/PHYS-467/PA3.pdf
rlarmor = (33.36 * u.km * gmaxconf * 511.0e3 / 1.0e9 / (blob.B / u.G)).to("cm")

# both values are similar
print("R_L (gmaxconf)=", rlarmor, "R_b=", blob.R_b)

#############################################
Exemple #6
0
    "p1": 1.5,
    "p2": 2.5,
    "gamma_b": 1.0e3,
    "gamma_min": 1,
    "gamma_max": 1.0e6,
}
spectrum_dict = {"type": "BrokenPowerLaw", "parameters": parameters}
delta_D = 1.01
Gamma = 1.01
B = 1.0 * u.G
r_b = 1.0e15 * u.cm
# no beaming
blob0 = Blob(r_b,
             0.01,
             delta_D,
             Gamma,
             B,
             spectrum_norm,
             spectrum_dict,
             xi=0.01)

synch0 = Synchrotron(blob0, ssa=True)
synch0_sed = synch0.sed_flux(nu)

# beaming
delta_D = 20
Gamma = 15
blob1 = Blob(r_b,
             0.01,
             delta_D,
             Gamma,
             B,
Exemple #7
0
from astropy.coordinates import Distance
from agnpy.emission_regions import Blob
import matplotlib.pyplot as plt
from agnpy.utils.plot import load_mpl_rc

# matplotlib adjustments
load_mpl_rc()

# set the spectrum normalisation (total energy in electrons in this case)
spectrum_norm = 1e48 * u.Unit("erg")
# define the spectral function parametrisation through a dictionary
spectrum_dict = {
    "type": "PowerLaw",
    "parameters": {
        "p": 2.8,
        "gamma_min": 1e2,
        "gamma_max": 1e7
    },
}
# set the remaining quantities defining the blob
R_b = 1e16 * u.cm
B = 1 * u.G
z = Distance(1e27, unit=u.cm).z
delta_D = 10
Gamma = 10
blob = Blob(R_b, z, delta_D, Gamma, B, spectrum_norm, spectrum_dict)

# plot the electron distribution
blob.plot_n_e(gamma_power=2)
plt.show()
Exemple #8
0
bpwl_dict_test = {
    "type": "BrokenPowerLaw",
    "parameters": {
        "p1": 2.0,
        "p2": 3.5,
        "gamma_b": 1e4,
        "gamma_min": 20,
        "gamma_max": 5e7,
    },
}
# blob reproducing Figure 7.4 of Dermer Menon 2009
pwl_blob_test = Blob(
    1e16 * u.cm,
    Distance(1e27, unit=u.cm).z,
    10,
    10,
    1 * u.G,
    pwl_spectrum_norm_test,
    pwl_dict_test,
)
# blob reproducing the EC scenarios in Finke 2016
bpwl_blob_test = Blob(
    1e16 * u.cm,
    1,
    40,
    40,
    0.56 * u.G,
    bpwl_spectrum_norm_test,
    bpwl_dict_test,
)
bpwl_blob_test.set_gamma_size(400)
Exemple #9
0
    def test_tau_on_synchrotron_compare_with_delta_approximation(self):
        """Compare the output of the calculation of absorption of gamma rays
        in synchrotron radiation and compare it with simplified delta approximation.
        """

        # create a test blob
        r_b = 1.0e16 * u.cm
        z = 2.01
        delta_D = 10.1
        Gamma = 10.05
        B0 = 1.1 * u.G
        gmin = 10
        gbreak = 1.0e3
        gmax = 1.0e5
        spectrum_norm = 0.1 * u.Unit("erg cm-3")
        parameters = {
            "p1": 1.5,
            "p2": 2.5,
            "gamma_b": gbreak,
            "gamma_min": gmin,
            "gamma_max": gmax,
        }
        spectrum_dict = {"type": "BrokenPowerLaw", "parameters": parameters}
        blob = Blob(r_b, z, delta_D, Gamma, B0, spectrum_norm, spectrum_dict)

        nu_tau = np.logspace(22, 34, 100) * u.Hz  # for absorption calculations
        e_tau = nu_tau.to("eV", equivalencies=u.spectral())

        # full calculations
        absorb = Absorption(blob)
        tau = absorb.tau(nu_tau)

        # now simplified calculations using Eq. 37 of Finke 2008
        mec2 = (m_e * c**2).to("eV")
        eps1 = e_tau / mec2
        eps1p = eps1 * (1 + z) / blob.delta_D
        eps_bar = 2 * blob.delta_D**2 / (1 + z)**2 / eps1
        nu_bar = (eps_bar * mec2).to("Hz", equivalencies=u.spectral())
        synch = Synchrotron(blob, ssa=True)
        synch_sed_ebar = synch.sed_flux(nu_bar)

        tau_delta = (synch_sed_ebar * sigma_T * Distance(z=z)**2 * eps1p /
                     (2 * m_e * c**3 * blob.R_b * blob.delta_D**4))
        tau_delta = tau_delta.to("")

        # the delta approximation does not work well with sharp cut-offs of synchrotron SED.
        # We first find the peak of the synchr SED
        maxidx = np.where(synch_sed_ebar == np.amax(synch_sed_ebar))[0][0]
        # and only take energies below the peak, (note that energies are ordered
        # in reversed order), and  take only those that are at least 1% of the peak
        idxs = synch_sed_ebar[maxidx:] > 1.0e-2 * synch_sed_ebar[maxidx]

        # if there are not many points something went wrong with the test
        assert sum(idxs) > 10

        # the agreement in the middle range is pretty good, but at the edges
        # of energy range it spoils very fast, so only rough agreement is checked
        # (0.6 in the log space)
        assert np.allclose(np.log(tau)[maxidx:][idxs],
                           np.log(tau_delta)[maxidx:][idxs],
                           atol=0.6)
Exemple #10
0
import numpy as np
import astropy.units as u
from agnpy.emission_regions import Blob
from agnpy.compton import SynchrotronSelfCompton
from agnpy.utils.plot import plot_sed
import matplotlib.pyplot as plt
from agnpy.utils.plot import load_mpl_rc

# matplotlib adjustments
load_mpl_rc()

# define the emission region and the radiative process
blob = Blob()
ssc = SynchrotronSelfCompton(blob)

# compute the SED over an array of frequencies
nu = np.logspace(15, 28) * u.Hz
sed = ssc.sed_flux(nu)

# plot it
plot_sed(nu, sed, label="Synchrotron Self Compton")
plt.show()
Exemple #11
0
import numpy as np
import astropy.units as u
from astropy.coordinates import Distance
from astropy.constants import e, c, m_e, M_sun, G, sigma_sb
from agnpy.emission_regions import Blob
from agnpy.targets import (
    CMB,
    PointSourceBehindJet,
    SSDisk,
    SphericalShellBLR,
    RingDustTorus,
)
import pytest

# variables with _test are global and meant to be used in all tests
blob_test = Blob()

# CMB at z = 1
cmb_test = CMB(z=1)

# PointSourceBehindJet
ps_test = PointSourceBehindJet(1e46 * u.Unit("erg s-1"), 1e-5)

# disk
M_BH_test = 1.2 * 1e9 * M_sun
L_disk_test = 1.512 * 1e46 * u.Unit("erg s-1")
eta_test = 1 / 12
R_g_test = 1.77 * 1e14 * u.cm
R_in_tilde_test = 6
R_out_tilde_test = 200
R_in_test = R_in_tilde_test * R_g_test
spectrum_norm = 6e42 * u.erg
parameters = {
    "p1": 2.0,
    "p2": 3.5,
    "gamma_b": 1e4,
    "gamma_min": 20,
    "gamma_max": 5e7,
}
spectrum_dict = {"type": "BrokenPowerLaw", "parameters": parameters}
R_b = 1e16 * u.cm
B = 0.56 * u.G
z = 1
delta_D = 40
Gamma = 40
blob = Blob(R_b, z, delta_D, Gamma, B, spectrum_norm, spectrum_dict)
blob.set_gamma_size(500)

L_disk = 2 * 1e46 * u.Unit("erg s-1")
# dust torus
T_dt = 1e3 * u.K
csi_dt = 0.1
dt = RingDustTorus(L_disk, csi_dt, T_dt)
# blr
xi_line = 0.024
R_line = 1e17 * u.cm
blr = SphericalShellBLR(L_disk, xi_line, "Lyalpha", R_line)

# point source behind the jet approximating the DT
ps_dt = PointSourceBehindJet(dt.xi_dt * L_disk, dt.epsilon_dt)
# point source behind the jet approximating the BLR
Exemple #13
0
# global PWL blob, same parameters of Figure 7.4 in Dermer Menon 2009
SPECTRUM_NORM = 1e48 * u.Unit("erg")
PWL_DICT = {
    "type": "PowerLaw",
    "parameters": {
        "p": 2.8,
        "gamma_min": 1e2,
        "gamma_max": 1e5
    },
}
R_B = 1e16 * u.cm
B = 1 * u.G
Z = Distance(1e27, unit=u.cm).z
DELTA_D = 10
GAMMA = 10
PWL_BLOB = Blob(R_B, Z, DELTA_D, GAMMA, B, SPECTRUM_NORM, PWL_DICT)

# global blob with BPL law of electrons, to test the parametrisation of the
# delta function approximation
BPL_DICT = {
    "type": "BrokenPowerLaw",
    "parameters": {
        "p1": 2.5,
        "p2": 3.5,
        "gamma_b": 1e4,
        "gamma_min": 1e2,
        "gamma_max": 1e7,
    },
}
BPL_BLOB = Blob(R_B, Z, DELTA_D, GAMMA, B, SPECTRUM_NORM, BPL_DICT)
        "gamma_0": 1e3,
        "gamma_min": gamma_min_test,
        "gamma_max": gamma_max_test,
    },
}
# blob parameters
R_b_test = 1e16 * u.cm
z_test = 0.1
delta_D_test = 10
Gamma_test = 10
B_test = 0.1 * u.G
pwl_blob_test = Blob(
    R_b_test,
    z_test,
    delta_D_test,
    Gamma_test,
    B_test,
    spectrum_norm_test,
    pwl_dict_test,
)
bpwl_blob_test = Blob(
    R_b_test,
    z_test,
    delta_D_test,
    Gamma_test,
    B_test,
    spectrum_norm_test,
    bpwl_dict_test,
)
lp_blob_test = Blob(
    R_b_test,
Exemple #15
0

#####################
# test one with emission region in the center of the DT
L_disk = 0.91e45 * u.Unit("erg s-1")
xi_dt = 0.6
T_dt = 100 * u.K
R_dt = 1.0e18 * u.cm
h = 0.01 * R_dt

## test with lower numbers, gives virtually the same
# B0/=10
# T_dt/=10
# L_disk/=100

blob1 = Blob(r0, z, delta_D, Gamma, B0, norm, spectrum_dict, xi=xi)
dt1 = RingDustTorus(L_disk, xi_dt, T_dt, R_dt=R_dt)

# energy density of DT radiation field in the blob
u_dt1 = dt1.u_ph(h, blob1)
u_synch1 = blob1.u_ph_synch
print(
    "energy density in the blob, DT radiation: ",
    u_dt1,
    "synchrotron photons: ",
    u_synch1,
)
dt1_sed = dt1.sed_flux(nu, z)
# energy density was set to be the same

synch1 = Synchrotron(blob1, ssa=False)
Exemple #16
0
mec2 = m_e.to("erg", equivalencies=u.mass_energy())
# a global test blob with spectral index 2
SPECTRUM_NORM = 1e-13 * u.Unit("cm-3")
GAMMA_MIN = 1
GAMMA_MAX = 1e6
PWL_IDX_2_DICT = {
    "type": "PowerLaw",
    "parameters": {"p": 2.0, "gamma_min": GAMMA_MIN, "gamma_max": GAMMA_MAX},
}
# blob parameters
R_B = 1e16 * u.cm
Z = 0.1
DELTA_D = 10
GAMMA = 10
B = 0.1 * u.G
PWL_BLOB = Blob(R_B, Z, DELTA_D, GAMMA, B, SPECTRUM_NORM, PWL_IDX_2_DICT)
# useful for checks
BETA = 1 - 1 / np.power(GAMMA, 2)
V_B = 4 / 3 * np.pi * np.power(R_B, 3)


class TestBlob:
    """class grouping all tests related to the Blob emission region"""

    def test_default_norm_type(self):
        """the default norm type should be 'integral'"""
        assert PWL_BLOB.spectrum_norm_type == "integral"

    def test_integral_norm_cm3(self):
        """test if the integral norm in cm-3 is correctly set"""
        PWL_BLOB.set_n_e(SPECTRUM_NORM, PWL_IDX_2_DICT, "integral")
Exemple #17
0
n = -2.0
x = np.logspace(2, 5)
y = line_loglog(x, m, n)

analytical_integral = integral_line_loglog(x[0], x[-1], m, n)
trapz_loglog_integral = trapz_loglog(y, x)
np_trapz_integral = np.trapz(y, x)

print(f"analyitcal integral: {analytical_integral:e}")
print(f"trapz_loglog integral: {analytical_integral:e}")
print(f"np.trapz integral: {analytical_integral:e}")

# a test with sycnhrotron radiation
print("-> test with synchrotron radiation")

blob = Blob()
nu = np.logspace(9, 20, 20) * u.Hz

# check the blob
print(blob)


def sed_synch(nu, blob, integration):
    """compute the synchrotron SED"""
    epsilon = nu_to_epsilon_prime(nu, blob.z, blob.delta_D)
    # electrond distribution lorentz factor
    gamma = blob.gamma
    N_e = blob.N_e(gamma)
    prefactor = np.sqrt(3) * epsilon * np.power(e, 3) * blob.B_cgs / h
    # for multidimensional integration
    # axis 0: electrons gamma
# define the blob
spectrum_norm = 6e42 * u.erg
parameters = {
    "p1": 2.0001,
    "p2": 3.5,
    "gamma_b": 1e4,
    "gamma_min": 20,
    "gamma_max": 5e7,
}
spectrum_dict = {"type": "BrokenPowerLaw", "parameters": parameters}
R_b = 1e16 * u.cm
B = 0.56 * u.G
z = 1
delta_D = 40
Gamma = 40
blob = Blob(R_b, z, delta_D, Gamma, B, spectrum_norm, spectrum_dict)
print("\nblob definition:")
print(blob)

# disk parameters
M_sun = const.M_sun.cgs
M_BH = 1.2 * 1e9 * M_sun
R_g = ((const.G * M_BH) / (const.c * const.c)).cgs
L_disk = 2 * 1e46 * u.Unit("erg s-1")
eta = 1 / 12
R_in = 6 * R_g
R_out = 200 * R_g
disk = SSDisk(M_BH, L_disk, eta, R_in, R_out)
print("\ndisk definition:")
print(disk)
Exemple #19
0
    fig.savefig(f"{tests_dir}/crosscheck_figures/{fig_name}.png")


# global PWL blob, same parameters of Figure 7.4 in Dermer Menon 2009
PWL_SPECTRUM_NORM = 1e48 * u.Unit("erg")
PWL_DICT = {
    "type": "PowerLaw",
    "parameters": {"p": 2.8, "gamma_min": 1e2, "gamma_max": 1e5},
}
R_B_PWL = 1e16 * u.cm
B_PWL = 1 * u.G
Z_PWL = Distance(1e27, unit=u.cm).z
DELTA_D_PWL = 10
GAMMA_PWL = 10
PWL_BLOB = Blob(
    R_B_PWL, Z_PWL, DELTA_D_PWL, GAMMA_PWL, B_PWL, PWL_SPECTRUM_NORM, PWL_DICT
)

# global BPL blob, same parameters of the examples in Finke 2016
BPL_SPECTRUM_NORM = 6e42 * u.Unit("erg")
BPL_DICT = {
    "type": "BrokenPowerLaw",
    "parameters": {
        "p1": 2.0,
        "p2": 3.5,
        "gamma_b": 1e4,
        "gamma_min": 20,
        "gamma_max": 5e7,
    },
}
R_B_BPL = 1e16 * u.cm