示例#1
0
 def test_synch_reference_sed(self):
     """test agnpy synchrotron SED against the one sampled from Figure
     7.4 of Dermer Menon 2009"""
     sampled_synch_sed_table = np.loadtxt(
         f"{tests_dir}/sampled_seds/synch_figure_7_4_dermer_menon_2009.txt",
         delimiter=",",
         comments="#",
     )
     sampled_synch_nu = sampled_synch_sed_table[:, 0] * u.Hz
     sampled_synch_sed = sampled_synch_sed_table[:,
                                                 1] * u.Unit("erg cm-2 s-1")
     synch = Synchrotron(PWL_BLOB)
     # recompute the SED at the same ordinates where the figure was sampled
     agnpy_synch_sed = synch.sed_flux(sampled_synch_nu)
     # sed comparison plot
     make_sed_comparison_plot(
         sampled_synch_nu,
         sampled_synch_sed,
         agnpy_synch_sed,
         "Synchrotron",
         "synch_comparison_figure_7_4_dermer_menon_2009",
     )
     # requires that the SED points deviate less than 15% from the figure
     assert u.allclose(
         agnpy_synch_sed,
         sampled_synch_sed,
         atol=0 * u.Unit("erg cm-2 s-1"),
         rtol=0.15,
     )
示例#2
0
 def test_synch_reference_sed(self, gamma_max, nu_range_max):
     """test agnpy synchrotron SED against the ones in Figure 7.4 of Dermer 
     Menon 2009"""
     # reference SED
     nu_ref, sed_ref = extract_columns_sample_file(
         f"{data_dir}/reference_seds/dermer_menon_2009/figure_7_4/synchrotron_gamma_max_{gamma_max}.txt",
         "Hz",
         "erg cm-2 s-1",
     )
     # agnpy
     # change the gamma_max in the blob
     pwl_dict_test["parameters"]["gamma_max"] = float(gamma_max)
     pwl_blob_test.set_spectrum(spectrum_norm_test, pwl_dict_test,
                                "integral")
     # recompute the SED at the same ordinates of the reference figures
     synch = Synchrotron(pwl_blob_test)
     sed_agnpy = synch.sed_flux(nu_ref)
     # sed comparison plot
     nu_range = [1e10, nu_range_max] * u.Hz
     make_comparison_plot(
         nu_ref,
         sed_agnpy,
         sed_ref,
         "agnpy",
         "Figure 7.4, Dermer and Menon (2009)",
         "Synchrotron, " + r"$\gamma_{max} = $" + gamma_max,
         f"{figures_dir}/synch_comparison_gamma_max_{gamma_max}_figure_7_4_dermer_menon_2009.png",
         "sed",
         y_range=[1e-13, 1e-9],
         comparison_range=nu_range.to_value("Hz"),
     )
     # requires that the SED points deviate less than 25% from the figure
     assert check_deviation(nu_ref, sed_agnpy, sed_ref, 0.25, nu_range)
示例#3
0
 def test_synch_sed_param_bpl(self):
     """check that the parametrised delta-function approximation for the
     synchrotron radiation gives exactly the same result of the full formula 
     from which it was derived"""
     nu = np.logspace(8, 23) * u.Hz
     synch = Synchrotron(BPL_BLOB)
     sed_delta_approx = synch.sed_flux_delta_approx(nu)
     # check that the synchrotron parameterisation work
     y = BPL_BLOB.B.value * BPL_BLOB.delta_D
     k_eq = (BPL_BLOB.u_e / BPL_BLOB.U_B).to_value("")
     sed_param = synch_sed_param_bpl(
         nu.value,
         y,
         k_eq,
         BPL_BLOB.n_e.p1,
         BPL_BLOB.n_e.p2,
         BPL_BLOB.n_e.gamma_b,
         BPL_BLOB.n_e.gamma_min,
         BPL_BLOB.n_e.gamma_max,
         BPL_BLOB.d_L.cgs.value,
         BPL_BLOB.R_b.cgs.value,
         BPL_BLOB.z,
     )
     assert np.allclose(sed_param,
                        sed_delta_approx.value,
                        atol=0,
                        rtol=1e-2)
示例#4
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')
示例#5
0
 def test_ssa_sed(self):
     """test this version SSA SED against the one generated with version 0.0.6"""
     sampled_ssa_sed_table = np.loadtxt(
         f"{tests_dir}/sampled_seds/ssa_sed_agnpy_v0_0_6.txt",
         delimiter=",",
         comments="#",
     )
     sampled_ssa_nu = sampled_ssa_sed_table[:, 0] * u.Hz
     sampled_ssa_sed = sampled_ssa_sed_table[:, 1] * u.Unit("erg cm-2 s-1")
     ssa = Synchrotron(PWL_BLOB, ssa=True)
     agnpy_ssa_sed = ssa.sed_flux(sampled_ssa_nu)
     assert u.allclose(
         agnpy_ssa_sed,
         sampled_ssa_sed,
         atol=0 * u.Unit("erg cm-2 s-1"),
     )
示例#6
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)
示例#7
0
 def test_synch_delta_sed(self):
     """check that in a given frequency range the full synchrotron SED coincides
     with the delta function approximation"""
     nu = np.logspace(10, 20) * u.Hz
     synch = Synchrotron(lp_blob_test)
     sed_full = synch.sed_flux(nu)
     sed_delta = synch.sed_flux_delta_approx(nu)
     # range of comparison
     nu_range = [1e12, 1e17] * u.Hz
     make_comparison_plot(
         nu,
         sed_delta,
         sed_full,
         "delta function approximation",
         "full integration",
         "Synchrotron",
         f"{figures_dir}/synch_comparison_delta_aprproximation.png",
         "sed",
         [1e-16, 1e-8],
         nu_range.to_value("Hz"),
     )
     # requires that the delta approximation SED points deviate less than 10%
     assert check_deviation(nu, sed_delta, sed_full, 0.1, nu_range)
示例#8
0
 def test_sed_integration_methods(self):
     """test different integration methods agains each other
     simpole trapezoidal rule vs trapezoidal rule in log-log space
     """
     nu = np.logspace(8, 22) * u.Hz
     synch_trapz = Synchrotron(pwl_blob_test, integrator=np.trapz)
     synch_trapz_loglog = Synchrotron(pwl_blob_test,
                                      integrator=trapz_loglog)
     sed_synch_trapz = synch_trapz.sed_flux(nu)
     sed_synch_trapz_loglog = synch_trapz_loglog.sed_flux(nu)
     make_comparison_plot(
         nu,
         sed_synch_trapz_loglog,
         sed_synch_trapz,
         "trapezoidal log-log integration",
         "trapezoidal integration",
         "Synchrotron",
         f"{figures_dir}/synch_comparison_integration_methods.png",
         "sed",
     )
     # requires that the SED points deviate less than 1%
     assert check_deviation(nu, sed_synch_trapz_loglog, sed_synch_trapz,
                            0.01)
示例#9
0
Gamma = 1.01
delta_D = 1.02
z = 0.01
blob1 = Blob(r0, z, delta_D, Gamma, B0 * 10.0, norm, spectrum_dict, xi=xi)

u_ph_synch = blob1.u_ph_synch  # energy density of synchr photons
# u_dens * V_b is the total energy in the blob,
# photons spend an average time of 0.75 * R_b/c in the blob
# so the total energy flux is:
# total energy in blob / (average time  * 4 pi dist^2)
energy_flux_predicted = (blob.u_ph_synch * blob1.V_b /
                         (0.75 * blob1.R_b / const.c.cgs) *
                         np.power(blob1.d_L, -2) /
                         (4 * np.pi)).to("erg cm-2 s-1")

synch1 = Synchrotron(blob1, ssa=False)
synch1_sed = synch1.sed_flux(nu)

energy_flux_sim = np.trapz(synch1_sed / (nu * const.h.cgs), nu * const.h.cgs)
print(
    f"predicted energy flux: {energy_flux_predicted:.5e}, simulated energy flux: {energy_flux_sim:.5e}"
)
# nice agreement

ssc1 = SynchrotronSelfCompton(blob1, synch1)
ssc1_sed = ssc1.sed_flux(nu)

print("UB/Usynch = ", blob1.U_B / u_ph_synch)
print(
    "SED_synch/SED_SSC=",
    energy_flux_sim / np.trapz(ssc1_sed /
示例#10
0
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,
             spectrum_norm,
             spectrum_dict,
             xi=0.01)

synch1 = Synchrotron(blob1, ssa=True)
示例#11
0
    "type": "PowerLaw",
    "parameters": {
        "p": 2.8,
        "gamma_min": 1e2,
        "gamma_max": 1e7
    },
}
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)
print("blob definition:")
print(blob)
synch = Synchrotron(blob)
ssc = SynchrotronSelfCompton(blob, synch)
nu_syn = np.logspace(8, 23) * u.Hz
nu_ssc = np.logspace(15, 30) * u.Hz

# commands to profile
syn_sed_command = "synch.sed_flux(nu_syn)"
syn_sed_SSA_command = "synch.sed_flux(nu_syn, SSA=True)"
ssc_sed_command = "ssc.sed_flux(nu_ssc)"

n = 100
print("\nprofiling synchrotron sed computation:")
profile(syn_sed_command, "syn_sed")
time_syn = timing(syn_sed_command, n)
time_syn /= n
print(f"time: {time_syn:.2e} s")
示例#12
0
import numpy as np
import astropy.units as u
from agnpy.emission_regions import Blob
from agnpy.synchrotron import Synchrotron
from agnpy.utils.plot import plot_sed
import matplotlib.pyplot as plt

# define the emission region and the radiative process
blob = Blob()
synch = Synchrotron(blob)
# compute the SED over an array of frequencies
nu = np.logspace(8, 23) * u.Hz
sed = synch.sed_flux(nu)
# plot it
plot_sed(nu, sed, label="Synchrotron")
plt.show()
示例#13
0
    "type": "PowerLaw",
    "parameters": {
        "p": 2.8,
        "gamma_min": 1e2,
        "gamma_max": 1e7
    },
}
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)
print("blob definition:")
print(blob)
synch = Synchrotron(blob)
synch_ssa = Synchrotron(blob, ssa=True)
ssc = SynchrotronSelfCompton(blob, synch)
ssc_ssa = SynchrotronSelfCompton(blob, synch_ssa)
nu_syn = np.logspace(8, 23) * u.Hz
nu_ssc = np.logspace(15, 30) * u.Hz

# commands to profile
syn_sed_command = "synch.sed_flux(nu_syn)"
syn_sed_ssa_command = "synch_ssa.sed_flux(nu_syn)"
ssc_sed_command = "ssc.sed_flux(nu_ssc)"
ssc_ssa_sed_command = "ssc_ssa.sed_flux(nu_ssc)"

n = 100
print("\nprofiling synchrotron sed computation:")
profile(syn_sed_command, "syn_sed")
示例#14
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)