redback 1.0.2__py3-none-any.whl → 1.0.31__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- redback/__init__.py +1 -1
- redback/constraints.py +15 -0
- redback/eos.py +1 -0
- redback/get_data/fink.py +1 -1
- redback/model_library.py +2 -2
- redback/priors/bazin_sne.prior +5 -0
- redback/priors/csm_shock_and_arnett.prior +11 -0
- redback/priors/csm_shock_and_arnett_bolometric.prior +10 -0
- redback/priors/csm_shock_breakout.prior +7 -0
- redback/priors/nicholl_bns.prior +2 -1
- redback/priors/pwn.prior +7 -0
- redback/priors/shocked_cocoon.prior +6 -6
- redback/priors/sn_fallback.prior +8 -0
- redback/priors/stream_stream_tde.prior +10 -0
- redback/priors/stream_stream_tde_bolometric.prior +9 -0
- redback/priors/tde_fallback.prior +9 -0
- redback/priors/tde_fallback_bolometric.prior +6 -0
- redback/priors/tde_synchrotron.prior +6 -0
- redback/priors/two_comp_kne_rosswog_heatingrate.prior +2 -2
- redback/priors/villar_sne.prior +7 -0
- redback/priors.py +1 -1
- redback/simulate_transients.py +11 -4
- redback/tables/GRBs_w_redshift.txt +430 -413
- redback/tables/LGRB_table.txt +70 -6
- redback/tables/SGRB_table.txt +139 -135
- redback/tables/qdot_rosswogkorobkin24.pck +0 -0
- redback/transient/afterglow.py +14 -5
- redback/transient/kilonova.py +5 -2
- redback/transient/prompt.py +14 -4
- redback/transient/supernova.py +6 -2
- redback/transient/tde.py +5 -2
- redback/transient/transient.py +27 -10
- redback/transient_models/afterglow_models.py +110 -146
- redback/transient_models/combined_models.py +39 -33
- redback/transient_models/extinction_models.py +1 -2
- redback/transient_models/general_synchrotron_models.py +518 -0
- redback/transient_models/integrated_flux_afterglow_models.py +2 -2
- redback/transient_models/kilonova_models.py +88 -72
- redback/transient_models/magnetar_models.py +1 -1
- redback/transient_models/phenomenological_models.py +57 -2
- redback/transient_models/shock_powered_models.py +159 -110
- redback/transient_models/supernova_models.py +161 -7
- redback/transient_models/tde_models.py +849 -4
- redback/utils.py +28 -12
- {redback-1.0.2.dist-info → redback-1.0.31.dist-info}/METADATA +42 -5
- {redback-1.0.2.dist-info → redback-1.0.31.dist-info}/RECORD +49 -35
- {redback-1.0.2.dist-info → redback-1.0.31.dist-info}/WHEEL +1 -1
- {redback-1.0.2.dist-info → redback-1.0.31.dist-info}/LICENCE.md +0 -0
- {redback-1.0.2.dist-info → redback-1.0.31.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import redback.transient_models.extinction_models as em
|
|
2
|
+
import redback.transient_models as tm
|
|
3
|
+
from redback.utils import nu_to_lambda
|
|
2
4
|
from redback.utils import citation_wrapper
|
|
3
5
|
|
|
4
6
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract, https://ui.adsabs.harvard.edu/abs/2020ApJ...891..152H/abstract')
|
|
@@ -38,16 +40,16 @@ def tophat_and_twolayerstratified(time, redshift, av, thv, loge0, thc, logn0, p,
|
|
|
38
40
|
:return: flux density signal with extinction added
|
|
39
41
|
|
|
40
42
|
"""
|
|
41
|
-
kwargs['output_format']='flux_density'
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
kwargs['base_model']='two_layer_stratified_kilonova'
|
|
47
|
-
kilonova = em.extinction_with_kilonova_base_model(time=time, redshift=redshift, av=av,
|
|
48
|
-
mej=mej, vej_1=vej_1, vej_2=vej_2, kappa=kappa, beta=beta, **kwargs)
|
|
49
|
-
|
|
43
|
+
kwargs['output_format'] = 'flux_density'
|
|
44
|
+
afterglow = tm.afterglow_models.tophat(time=time, redshift=redshift, thv=thv, loge0=loge0, thc=thc, logn0=logn0,
|
|
45
|
+
p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0, **kwargs)
|
|
46
|
+
kilonova = tm.kilonova_models.two_layer_stratified_kilonova(time=time, redshift=redshift, mej=mej, vej_1=vej_1,
|
|
47
|
+
vej_2=vej_2, kappa=kappa, beta=beta, **kwargs)
|
|
50
48
|
combined = afterglow+kilonova
|
|
49
|
+
r_v = kwargs.get('r_v', 3.1)
|
|
50
|
+
# correct for extinction
|
|
51
|
+
angstroms = nu_to_lambda(kwargs['frequency'])
|
|
52
|
+
combined = em._perform_extinction(flux_density=combined, angstroms=angstroms, av=av, r_v=r_v)
|
|
51
53
|
return combined
|
|
52
54
|
|
|
53
55
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract, redback')
|
|
@@ -92,17 +94,18 @@ def tophat_and_twocomponent(time, redshift, av, thv, loge0, thc, logn0,
|
|
|
92
94
|
"""
|
|
93
95
|
|
|
94
96
|
kwargs['output_format'] = 'flux_density'
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
kwargs['base_model'] = 'two_component_kilonova_model'
|
|
100
|
-
kilonova = em.extinction_with_kilonova_base_model(time=time, redshift=redshift, av=av,
|
|
97
|
+
afterglow = tm.afterglow_models.tophat(time=time, redshift=redshift, thv=thv, loge0=loge0, thc=thc, logn0=logn0,
|
|
98
|
+
p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0, **kwargs)
|
|
99
|
+
kilonova = tm.kilonova_models.two_component_kilonova_model(time=time, redshift=redshift, av=av,
|
|
101
100
|
mej_1=mej_1, vej_1=vej_1, temperature_floor_1=temperature_floor_1,
|
|
102
101
|
kappa_1=kappa_1, mej_2=mej_2, vej_2=vej_2,
|
|
103
102
|
temperature_floor_2=temperature_floor_2, kappa_2=kappa_2, **kwargs)
|
|
104
103
|
|
|
105
104
|
combined = afterglow + kilonova
|
|
105
|
+
r_v = kwargs.get('r_v', 3.1)
|
|
106
|
+
# correct for extinction
|
|
107
|
+
angstroms = nu_to_lambda(kwargs['frequency'])
|
|
108
|
+
combined = em._perform_extinction(flux_density=combined, angstroms=angstroms, av=av, r_v=r_v)
|
|
106
109
|
return combined
|
|
107
110
|
|
|
108
111
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract, https://ui.adsabs.harvard.edu/abs/1982ApJ...253..785A/abstract')
|
|
@@ -146,52 +149,55 @@ def tophat_and_arnett(time, av, redshift, thv, loge0, thc, logn0, p, logepse, lo
|
|
|
146
149
|
"""
|
|
147
150
|
|
|
148
151
|
kwargs['output_format'] = 'flux_density'
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
thv=thv, loge0=loge0, thc=thc, logn0=logn0, p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0,
|
|
152
|
-
**kwargs)
|
|
152
|
+
afterglow = tm.afterglow_models.tophat(time=time, redshift=redshift, thv=thv, loge0=loge0, thc=thc, logn0=logn0,
|
|
153
|
+
p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0, **kwargs)
|
|
153
154
|
kwargs['base_model'] = 'arnett'
|
|
154
|
-
supernova =
|
|
155
|
-
f_nickel=f_nickel, mej=mej, **kwargs)
|
|
156
|
-
|
|
155
|
+
supernova = tm.supernova_models.arnett(time=time, redshift=redshift, f_nickel=f_nickel, mej=mej, **kwargs)
|
|
157
156
|
combined = afterglow + supernova
|
|
157
|
+
r_v = kwargs.get('r_v', 3.1)
|
|
158
|
+
# correct for extinction
|
|
159
|
+
angstroms = nu_to_lambda(kwargs['frequency'])
|
|
160
|
+
combined = em._perform_extinction(flux_density=combined, angstroms=angstroms, av=av, r_v=r_v)
|
|
158
161
|
return combined
|
|
159
162
|
|
|
160
163
|
@citation_wrapper('redback, and any citations for the specific model you use')
|
|
161
164
|
def afterglow_and_optical(time, redshift, av, **model_kwargs):
|
|
162
|
-
|
|
163
165
|
"""
|
|
164
166
|
function to combine the signals of any afterglow and any other optical transient with extinction added
|
|
165
167
|
|
|
166
168
|
:param time: time in days in observer frame
|
|
167
169
|
:param redshift: source redshift
|
|
168
170
|
:param av: absolute mag extinction
|
|
169
|
-
:param model_kwargs: kwargs shared by models
|
|
170
|
-
:param model_type: specify type of optical transient model- 'supernova', 'tde', 'kilonova', 'magnetar_driven', 'shock_powered'
|
|
171
|
+
:param model_kwargs: kwargs shared by models frequency and r_v (extinction paramater defaults to 3.1)
|
|
171
172
|
:param afterglow_kwargs: dictionary of parameters required by the afterglow transient model specified by 'base_model'
|
|
172
173
|
and any additional keyword arguments. Refer to model documentation for details.
|
|
173
174
|
:param optical_kwargs: dictionary of parameters required by the optical transient model specifed by 'base_model'
|
|
174
175
|
and any additional keyword arguments. Note the base model must correspond to the given model type. Refer to model documentation
|
|
175
176
|
for details.
|
|
176
|
-
:return:
|
|
177
|
-
note that only afterglow_models_sed allow for magnitude outputs
|
|
177
|
+
:return: flux density signal with extinction added
|
|
178
178
|
"""
|
|
179
179
|
|
|
180
|
+
from redback.model_library import all_models_dict
|
|
180
181
|
optical_kwargs = model_kwargs['optical_kwargs']
|
|
181
182
|
afterglow_kwargs = model_kwargs['afterglow_kwargs']
|
|
183
|
+
model_kwargs['output_format']= model_kwargs.get('output_format', 'flux_density')
|
|
182
184
|
|
|
183
185
|
_afterglow_kwargs = afterglow_kwargs.copy()
|
|
184
186
|
_afterglow_kwargs.update(model_kwargs)
|
|
185
|
-
_afterglow_kwargs.pop('model_type')
|
|
186
187
|
|
|
187
188
|
_optical_kwargs = optical_kwargs.copy()
|
|
188
189
|
_optical_kwargs.update(model_kwargs)
|
|
189
190
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
afterglow_function = all_models_dict[_afterglow_kwargs['base_model']]
|
|
192
|
+
afterglow = afterglow_function(time=time, redshift=redshift, **_afterglow_kwargs)
|
|
193
|
+
|
|
194
|
+
optical_function = all_models_dict[_optical_kwargs['base_model']]
|
|
195
|
+
optical = optical_function(time=time, redshift=redshift, **_optical_kwargs)
|
|
194
196
|
|
|
195
|
-
combined= afterglow + optical
|
|
197
|
+
combined = afterglow + optical
|
|
198
|
+
r_v = model_kwargs.get('r_v', 3.1)
|
|
199
|
+
# correct for extinction
|
|
200
|
+
angstroms = nu_to_lambda(model_kwargs['frequency'])
|
|
201
|
+
combined = em._perform_extinction(flux_density=combined, angstroms=angstroms, av=av, r_v=r_v)
|
|
196
202
|
return combined
|
|
197
203
|
|
|
@@ -23,7 +23,7 @@ extinction_integrated_flux_afterglow_models = extinction_afterglow_base_models
|
|
|
23
23
|
extinction_supernova_base_models = ['sn_exponential_powerlaw', 'arnett', 'shock_cooling_and_arnett',
|
|
24
24
|
'basic_magnetar_powered', 'slsn', 'magnetar_nickel',
|
|
25
25
|
'csm_interaction', 'csm_nickel', 'type_1a', 'type_1c',
|
|
26
|
-
'general_magnetar_slsn','general_magnetar_driven_supernova']
|
|
26
|
+
'general_magnetar_slsn','general_magnetar_driven_supernova', 'sn_fallback']
|
|
27
27
|
extinction_kilonova_base_models = ['nicholl_bns', 'mosfit_rprocess', 'mosfit_kilonova',
|
|
28
28
|
'power_law_stratified_kilonova','bulla_bns_kilonova',
|
|
29
29
|
'bulla_nsbh_kilonova', 'kasen_bns_kilonova','two_layer_stratified_kilonova',
|
|
@@ -87,7 +87,6 @@ def _perform_extinction(flux_density, angstroms, av, r_v):
|
|
|
87
87
|
:return: flux
|
|
88
88
|
"""
|
|
89
89
|
import extinction # noqa
|
|
90
|
-
import numpy.ma as ma
|
|
91
90
|
if isinstance(angstroms, float):
|
|
92
91
|
angstroms = np.array([angstroms])
|
|
93
92
|
mag_extinction = extinction.fitzpatrick99(angstroms, av, r_v=r_v)
|
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from redback.transient_models.magnetar_models import magnetar_only, basic_magnetar
|
|
3
|
+
from redback.transient_models.magnetar_driven_ejecta_models import _ejecta_dynamics_and_interaction
|
|
4
|
+
from redback.transient_models.shock_powered_models import _emissivity_pl, _emissivity_thermal, _tau_nu
|
|
5
|
+
from redback.transient_models.afterglow_models import _get_kn_dynamics, _pnu_synchrotron
|
|
6
|
+
from astropy.cosmology import Planck18 as cosmo
|
|
7
|
+
from redback.utils import calc_kcorrected_properties, citation_wrapper, logger, get_csm_properties, nu_to_lambda, lambda_to_nu, velocity_from_lorentz_factor, calc_ABmag_from_flux_density
|
|
8
|
+
from redback.constants import day_to_s, solar_mass, km_cgs, au_cgs, speed_of_light, qe, electron_mass, proton_mass, sigma_T
|
|
9
|
+
from scipy import integrate
|
|
10
|
+
from scipy.interpolate import interp1d
|
|
11
|
+
import astropy.units as uu
|
|
12
|
+
from collections import namedtuple
|
|
13
|
+
|
|
14
|
+
def _calc_free_free_abs(frequency, Y_fe, Zbar, mej, radius_2darray, F_nu_2darray):
|
|
15
|
+
"""
|
|
16
|
+
:param frequency: frequency to calculate
|
|
17
|
+
:param Y_fe: free electron fraction
|
|
18
|
+
:param Zbar: average proton number
|
|
19
|
+
:param mej: ejecta mass in solar units
|
|
20
|
+
:param radius_2darray: radius of the ejecta at each time
|
|
21
|
+
:param F_nu_2darray: unabsorbed flux density
|
|
22
|
+
:return: absorbed flux density
|
|
23
|
+
"""
|
|
24
|
+
n_e = mej * solar_mass * 3 / (4 * np.pi * radius_2darray**3) * Y_fe / proton_mass
|
|
25
|
+
tau_ff = 8.4e-28 * n_e**2 * radius_2darray * Zbar**2 * (frequency / 1.0e10) ** -2.1
|
|
26
|
+
F_nu_2darray = F_nu_2darray * np.exp(-tau_ff)
|
|
27
|
+
|
|
28
|
+
return F_nu_2darray
|
|
29
|
+
|
|
30
|
+
def _calc_compton_scat(frequency, Y_e, mej, radius_2darray, F_nu_2darray):
|
|
31
|
+
"""
|
|
32
|
+
:param frequency: frequency to calculate
|
|
33
|
+
:param Y_e: electron fraction
|
|
34
|
+
:param mej: ejecta mass in solar units
|
|
35
|
+
:param radius_2darray: radius of the ejecta at each time
|
|
36
|
+
:param F_nu_2darray: unabsorbed flux density
|
|
37
|
+
:return: absorbed flux density
|
|
38
|
+
"""
|
|
39
|
+
nu_e = 1.24e20
|
|
40
|
+
x = frequency/nu_e
|
|
41
|
+
msk = (x < 1e-3)
|
|
42
|
+
sigknpre = (1.0 + x)/x**3
|
|
43
|
+
sigkn1 = 2.0 * x * (1.0 + x)/(1.0 + 2.0*x) - np.log(1.0 + 2*x)
|
|
44
|
+
sigkn2 = np.log(1.0 + 2.0*x)/(2.0*x)
|
|
45
|
+
sigkn3 = (1.0 + 3.0*x)/(1.0 + 2.0*x)**2
|
|
46
|
+
sig_kn = (3.0/4.0) * sigma_T * (sigknpre*sigkn1 + sigkn2 - sigkn3)
|
|
47
|
+
if (np.size(sig_kn) > 1):
|
|
48
|
+
sig_kn[msk] = sigma_T
|
|
49
|
+
elif ((np.size(sig_kn) == 1) and (msk == True)):
|
|
50
|
+
sig_kn = sigma_T
|
|
51
|
+
kappa_comp = sig_kn * Y_e / proton_mass
|
|
52
|
+
tau_comp = 3.0 * kappa_comp * mej * solar_mass / (4.0 * np.pi * radius_2darray**2)
|
|
53
|
+
F_nu_2darray = F_nu_2darray * np.exp(-tau_comp)
|
|
54
|
+
|
|
55
|
+
return F_nu_2darray
|
|
56
|
+
|
|
57
|
+
def _calc_photoelectric_abs(frequency, Zbar, mej, radius_2darray, F_nu_2darray):
|
|
58
|
+
"""
|
|
59
|
+
:param frequency: frequency to calculate
|
|
60
|
+
:param Zbar: average proton number
|
|
61
|
+
:param mej: ejecta mass in solar units
|
|
62
|
+
:param radius_2darray: radius of the ejecta at each time
|
|
63
|
+
:param F_nu_2darray: unabsorbed flux density
|
|
64
|
+
:return: absorbed flux density
|
|
65
|
+
"""
|
|
66
|
+
msk = (frequency > 2.42e15)
|
|
67
|
+
kappa_pe = 2.37 * (Zbar/6.0)**3 * (frequency/2.42e18)**-3
|
|
68
|
+
tau_pe = 3.0 * kappa_pe * mej * solar_mass / (4.0 * np.pi * radius_2darray**2)
|
|
69
|
+
F_nu_2darray[:,msk] = F_nu_2darray[:,msk] * np.exp(-tau_pe[:,msk])
|
|
70
|
+
|
|
71
|
+
return F_nu_2darray
|
|
72
|
+
|
|
73
|
+
def _calc_optical_abs(frequency, kappa, mej, radius_2darray, F_nu_2darray):
|
|
74
|
+
"""
|
|
75
|
+
:param frequency: frequency to calculate
|
|
76
|
+
:param kappa: thermalization opacity
|
|
77
|
+
:param mej: ejecta mass in solar units
|
|
78
|
+
:param radius_2darray: radius of the ejecta at each time
|
|
79
|
+
:param F_nu_2darray: unabsorbed flux density
|
|
80
|
+
:return: absorbed flux density
|
|
81
|
+
"""
|
|
82
|
+
msk = np.logical_and((frequency < 2.42e15),(frequency > 2.42e13))
|
|
83
|
+
tau_opt = 3.0 * kappa * mej * solar_mass / (4.0 * np.pi * radius_2darray**2)
|
|
84
|
+
F_nu_2darray[:,msk] = F_nu_2darray[:,msk] * np.exp(-tau_opt[:,msk])
|
|
85
|
+
|
|
86
|
+
return F_nu_2darray
|
|
87
|
+
|
|
88
|
+
@citation_wrapper('Omand et al. (2024)')
|
|
89
|
+
def pwn(time, redshift, mej, l0, tau_sd, nn, eps_b, gamma_b, **kwargs):
|
|
90
|
+
"""
|
|
91
|
+
:param time: time in observer frame in days
|
|
92
|
+
:param redshift: redshift
|
|
93
|
+
:param mej: ejecta mass in solar units
|
|
94
|
+
:param l0: initial magnetar spin-down luminosity (in erg/s)
|
|
95
|
+
:param tau_sd: magnetar spin down damping timescale (in seconds)
|
|
96
|
+
:param nn: braking index
|
|
97
|
+
:param eps_b: magnetization of the PWN
|
|
98
|
+
:param gamma_b: Lorentz factor of electrons at synchrotron break
|
|
99
|
+
:param kwargs: Additional parameters -
|
|
100
|
+
:param E_sn: supernova explosion energy
|
|
101
|
+
:param kappa: opacity (used only in dynamics and optical absorption)
|
|
102
|
+
:param kappa_gamma: gamma-ray opacity used to calculate magnetar thermalisation efficiency (used only in dynamics)
|
|
103
|
+
:param q1: low energy spectral index (must be < 2)
|
|
104
|
+
:param q2: high energy spectral index (must be > 2)
|
|
105
|
+
:param Zbar: average proton number (used for free-free and photoelectric absorption)
|
|
106
|
+
:param Y_e: electron fraction (used for Compton scattering)
|
|
107
|
+
:param Y_fe: free electron fraction (used for free-free absorption)
|
|
108
|
+
:param pair_cascade_switch: whether to account for pair cascade losses, default is False
|
|
109
|
+
:param ejecta albedo: ejecta albedo; default is 0.5
|
|
110
|
+
:param pair_cascade_fraction: fraction of magnetar luminosity lost to pair cascades; default is 0.05
|
|
111
|
+
:param use_r_process: determine whether the ejecta is composed of r-process material; default is no
|
|
112
|
+
:param frequency: (frequency to calculate - Must be same length as time array or a single number)
|
|
113
|
+
:param f_nickel: Ni^56 mass as a fraction of ejecta mass
|
|
114
|
+
:return: flux density or AB magnitude or dynamics output
|
|
115
|
+
"""
|
|
116
|
+
#get parameter values or use defaults
|
|
117
|
+
E_sn = kwargs.get('E_sn', 1.0e51)
|
|
118
|
+
kappa = kwargs.get('kappa', 0.1)
|
|
119
|
+
if 'kappa' in kwargs:
|
|
120
|
+
del kwargs['kappa']
|
|
121
|
+
kappa_gamma = kwargs.get('kappa_gamma', 0.01)
|
|
122
|
+
kwargs['kappa_gamma'] = kappa_gamma
|
|
123
|
+
q1 = kwargs.get('q1',1.5)
|
|
124
|
+
q2 = kwargs.get('q2',2.5)
|
|
125
|
+
Zbar = kwargs.get('Zbar',8.0)
|
|
126
|
+
Y_e = kwargs.get('Y_e',0.5)
|
|
127
|
+
Y_fe = kwargs.get('Y_fe',0.0625)
|
|
128
|
+
|
|
129
|
+
ejecta_radius = 1.0e11
|
|
130
|
+
epse=1.0-eps_b
|
|
131
|
+
n_ism = 1.0e-5
|
|
132
|
+
dl = cosmo.luminosity_distance(redshift).cgs.value
|
|
133
|
+
pair_cascade_switch = kwargs.get('pair_cascade_switch', False)
|
|
134
|
+
use_r_process = kwargs.get('use_r_process', False)
|
|
135
|
+
nu_M=3.8e22*np.ones(2500)
|
|
136
|
+
|
|
137
|
+
#initial values and dynamics
|
|
138
|
+
time_temp = np.geomspace(1e0, 1e10, 2500)
|
|
139
|
+
frequency = kwargs['frequency']
|
|
140
|
+
if (np.size(frequency) == 1):
|
|
141
|
+
frequency = np.ones(len(time))*frequency
|
|
142
|
+
frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
|
|
143
|
+
magnetar_luminosity = magnetar_only(time=time_temp, l0=l0, tau=tau_sd, nn=nn)
|
|
144
|
+
v_init = np.sqrt(E_sn / (0.5 * mej * solar_mass)) / speed_of_light
|
|
145
|
+
output = _ejecta_dynamics_and_interaction(time=time_temp, mej=mej,
|
|
146
|
+
beta=v_init, ejecta_radius=ejecta_radius,
|
|
147
|
+
kappa=kappa, n_ism=n_ism, magnetar_luminosity=magnetar_luminosity,
|
|
148
|
+
pair_cascade_switch=pair_cascade_switch,
|
|
149
|
+
use_gamma_ray_opacity=True, **kwargs)
|
|
150
|
+
vej = velocity_from_lorentz_factor(output.lorentz_factor)/km_cgs
|
|
151
|
+
|
|
152
|
+
#calculating synchrotron quantites
|
|
153
|
+
int_lsd = integrate.cumulative_trapezoid(magnetar_luminosity, time_temp,initial=0)
|
|
154
|
+
B_nb = np.sqrt(6.0 * eps_b * int_lsd / output.radius**3)
|
|
155
|
+
B_nb[0] = B_nb[1]
|
|
156
|
+
nu_b = 3.0 / 4.0 / np.pi * gamma_b**2 * qe * B_nb / electron_mass / speed_of_light
|
|
157
|
+
nu_0 = np.minimum(nu_M, nu_b)
|
|
158
|
+
beta1 = np.maximum(1.5, ((2.0 + q1) / 2.0))
|
|
159
|
+
beta2 = (2.0 + q2) / 2.0
|
|
160
|
+
Rb = ((1.0 / (2.0 - q1)) - (1.0 / (2.0 - q2))) #bolometric correction
|
|
161
|
+
F_nu_0 = epse * magnetar_luminosity / (8.0 * np.pi * dl**2 * nu_0 * Rb)
|
|
162
|
+
nu_ssa = (dl**2 * 3.0**1.5 * qe**0.5 * B_nb**0.5 * F_nu_0 * nu_0**(beta1 - 1.0) / (4.0 * np.pi**1.5 * output.radius**2 * speed_of_light**0.5 * electron_mass**1.5))**(2.0 / (2 * beta1 + 3))
|
|
163
|
+
F_nu_ssa = F_nu_0 * (nu_ssa / nu_0) ** (1-beta1)
|
|
164
|
+
|
|
165
|
+
#making arrays to vectorize properly
|
|
166
|
+
freq_arr = np.tile(frequency, (2500,1))
|
|
167
|
+
F_nu_0_arr = np.tile(F_nu_0, (np.size(frequency),1))
|
|
168
|
+
nu_0_arr = np.tile(nu_0, (np.size(frequency),1))
|
|
169
|
+
F_nu_ssa_arr = np.tile(F_nu_ssa, (np.size(frequency),1))
|
|
170
|
+
nu_ssa_arr = np.tile(nu_ssa, (np.size(frequency),1))
|
|
171
|
+
r_arr = np.tile(output.radius, (np.size(frequency),1))
|
|
172
|
+
nu_b_arr = np.tile(nu_b, (np.size(frequency),1))
|
|
173
|
+
|
|
174
|
+
#calculate synchtron light curves for each desired frequency
|
|
175
|
+
F_nu = F_nu_0_arr.T * (frequency / nu_0_arr.T) ** (1-beta1)
|
|
176
|
+
|
|
177
|
+
if (np.max(frequency) > np.min(nu_b)):
|
|
178
|
+
msk = (freq_arr >= nu_b_arr.T)
|
|
179
|
+
F_nu[msk] = F_nu_0_arr.T[msk] * (freq_arr[msk] / nu_0_arr.T[msk]) ** (1-beta2)
|
|
180
|
+
|
|
181
|
+
if (np.min(frequency) < np.max(nu_ssa)):
|
|
182
|
+
msk = (freq_arr < nu_ssa_arr.T)
|
|
183
|
+
F_nu[msk] = F_nu_ssa_arr.T[msk] * (freq_arr[msk] / nu_ssa_arr.T[msk]) ** 2.5
|
|
184
|
+
|
|
185
|
+
F_nu = _calc_free_free_abs(frequency, Y_fe, Zbar, mej, r_arr.T, F_nu)
|
|
186
|
+
F_nu = _calc_compton_scat(frequency, Y_e, mej, r_arr.T, F_nu)
|
|
187
|
+
F_nu = _calc_optical_abs(frequency, kappa, mej, r_arr.T, F_nu)
|
|
188
|
+
if (np.max(frequency) > 2.42e15):
|
|
189
|
+
F_nu = _calc_photoelectric_abs(frequency, Zbar, mej, r_arr.T, F_nu)
|
|
190
|
+
|
|
191
|
+
#interpolate for each time
|
|
192
|
+
fnu_func = {}
|
|
193
|
+
fnu_func = interp1d(time_temp/day_to_s, y=F_nu.T)
|
|
194
|
+
fnu = np.diag(fnu_func(time))
|
|
195
|
+
fmjy = np.array(fnu) / 1.0e-26
|
|
196
|
+
|
|
197
|
+
return fmjy
|
|
198
|
+
|
|
199
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022MNRAS.516.4949S/abstract')
|
|
200
|
+
def kilonova_afterglow_redback(time, redshift, loge0, mej, logn0, logepse, logepsb, p,
|
|
201
|
+
**kwargs):
|
|
202
|
+
"""
|
|
203
|
+
Calculate the afterglow emission from a kilonova remnant, following the model of Sarin et al. 2022.
|
|
204
|
+
This model was modified by Nikhil Sarin following code provided by Ben Margalit.
|
|
205
|
+
|
|
206
|
+
:param time: time in observer frame (days) in observer frame
|
|
207
|
+
:param redshift: source redshift
|
|
208
|
+
:param loge0: log10 of the initial kinetic energy of the ejecta (erg)
|
|
209
|
+
:param mej: ejecta mass (solar masses)
|
|
210
|
+
:param logn0: log10 of the circumburst density (cm^-3)
|
|
211
|
+
:param logepse: log10 of the fraction of shock energy given to electrons
|
|
212
|
+
:param logepsb: log10 of the fraction of shock energy given to magnetic field
|
|
213
|
+
:param p: power-law index of the electron energy distribution
|
|
214
|
+
:param kwargs: Additional keyword arguments
|
|
215
|
+
:param zeta_e: fraction of electrons participating in diffusive shock acceleration. Default is 1.
|
|
216
|
+
:param output_format: Whether to output flux density or AB mag
|
|
217
|
+
:param frequency: frequency in Hz for the flux density calculation
|
|
218
|
+
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
219
|
+
:return: flux density or AB mag. Note this is going to give the monochromatic magnitude at the effective frequency for the band.
|
|
220
|
+
For a proper calculation of the magntitude use the sed variant models.
|
|
221
|
+
"""
|
|
222
|
+
Eej = 10 ** loge0
|
|
223
|
+
Mej = mej * solar_mass
|
|
224
|
+
cosmology = kwargs.get('cosmology', cosmo)
|
|
225
|
+
epsilon_e = 10 ** logepse
|
|
226
|
+
epsilon_B = 10 ** logepsb
|
|
227
|
+
n0 = 10 ** logn0
|
|
228
|
+
zeta_e = kwargs.get('zeta_e', 1.0)
|
|
229
|
+
qe = 4.803e-10
|
|
230
|
+
|
|
231
|
+
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
232
|
+
# calculate blast-wave dynamics
|
|
233
|
+
t, R, beta, Gamma, eden, tobs, beta_sh, Gamma_sh = _get_kn_dynamics(n0=n0, Eej=Eej, Mej=Mej)
|
|
234
|
+
|
|
235
|
+
# shock-amplified magnetic field, minimum & cooling Lorentz factors
|
|
236
|
+
B = (8.0 * np.pi * epsilon_B * eden) ** 0.5
|
|
237
|
+
gamma_m = 1.0 + (epsilon_e / zeta_e) * ((p - 2.0) / (p - 1.0)) * (proton_mass / electron_mass) * (Gamma - 1.0)
|
|
238
|
+
gamma_c = 6.0 * np.pi * electron_mass * speed_of_light / (sigma_T * Gamma * t * B ** 2)
|
|
239
|
+
|
|
240
|
+
# number of emitting electrons, where zeta_DN is an approximate smooth interpolation between the "standard"
|
|
241
|
+
# and deep-Newtonian regime discussed by Sironi & Giannios (2013)
|
|
242
|
+
zeta_DN = (gamma_m - 1.0) / gamma_m
|
|
243
|
+
Ne = zeta_DN * zeta_e * (4.0 * np.pi / 3.0) * R ** 3 * n0
|
|
244
|
+
|
|
245
|
+
# LOS approximation
|
|
246
|
+
mu = 1.0
|
|
247
|
+
blueshift = Gamma * (1.0 - beta * mu)
|
|
248
|
+
|
|
249
|
+
frequency = kwargs['frequency']
|
|
250
|
+
if isinstance(frequency, float):
|
|
251
|
+
frequency = np.ones(len(time)) * frequency
|
|
252
|
+
fnu_func = {}
|
|
253
|
+
for nu in frequency:
|
|
254
|
+
Fnu_opt_thin = _pnu_synchrotron(nu * blueshift * (1.0 + redshift), B, gamma_m, gamma_c, Ne, p) * (1.0 + redshift) / (
|
|
255
|
+
4.0 * np.pi * dl ** 2 * blueshift)
|
|
256
|
+
|
|
257
|
+
# correct for synchrotron self-absorption (approximate treatment, correct up to factors of order unity)
|
|
258
|
+
Fnu_opt_thick = Gamma * (8 * np.pi ** 2 * (nu * blueshift * (1.0 + redshift)) ** 2 / speed_of_light ** 2) * R ** 2 * (
|
|
259
|
+
1.0 / 3.0) * electron_mass * speed_of_light ** 2 * np.maximum(gamma_m, (
|
|
260
|
+
2 * np.pi * electron_mass * speed_of_light * nu * blueshift * (1.0 + redshift) / (qe * B)) ** 0.5) * (1.0 + redshift) / (
|
|
261
|
+
4.0 * np.pi * dl ** 2 * blueshift)
|
|
262
|
+
# new prescription:
|
|
263
|
+
Fnu = Fnu_opt_thick * (1e0 - np.exp(-Fnu_opt_thin / Fnu_opt_thick))
|
|
264
|
+
# add brute-force optically-thin case to avoid roundoff error in 1e0-np.exp(-x) term (above) when x->0
|
|
265
|
+
Fnu[Fnu == 0.0] = Fnu_opt_thin[Fnu == 0.0]
|
|
266
|
+
|
|
267
|
+
fnu_func[nu] = interp1d(tobs/day_to_s, Fnu, bounds_error=False, fill_value='extrapolate')
|
|
268
|
+
|
|
269
|
+
# interpolate onto actual observed frequency and time values
|
|
270
|
+
flux_density = []
|
|
271
|
+
for freq, tt in zip(frequency, time):
|
|
272
|
+
flux_density.append(fnu_func[freq](tt))
|
|
273
|
+
|
|
274
|
+
fmjy = np.array(flux_density) / 1e-26
|
|
275
|
+
if kwargs['output_format'] == 'flux_density':
|
|
276
|
+
return fmjy
|
|
277
|
+
elif kwargs['output_format'] == 'magnitude':
|
|
278
|
+
return calc_ABmag_from_flux_density(fmjy).value
|
|
279
|
+
|
|
280
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2011Natur.478...82N/abstract')
|
|
281
|
+
def kilonova_afterglow_nakarpiran(time, redshift, loge0, mej, logn0, logepse, logepsb, p, **kwargs):
|
|
282
|
+
"""
|
|
283
|
+
A kilonova afterglow model based on Nakar & Piran 2011
|
|
284
|
+
|
|
285
|
+
:param time: time in days in the observer frame
|
|
286
|
+
:param redshift: source redshift
|
|
287
|
+
:param loge0: initial kinetic energy in erg of ejecta
|
|
288
|
+
:param mej: mass of ejecta in solar masses
|
|
289
|
+
:param logn0: log10 of the number density of the circumburst medium in cm^-3
|
|
290
|
+
:param logepse: log10 of the fraction of energy given to electrons
|
|
291
|
+
:param logepsb: log10 of the fraction of energy given to the magnetic field
|
|
292
|
+
:param p: electron power law index
|
|
293
|
+
:param kwargs: Additional keyword arguments
|
|
294
|
+
:param output_format: Whether to output flux density or AB mag
|
|
295
|
+
:param frequency: frequency in Hz for the flux density calculation
|
|
296
|
+
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
297
|
+
:return: flux density or AB mag. Note this is going to give the monochromatic magnitude at the effective frequency for the band.
|
|
298
|
+
For a proper calculation of the magntitude use the sed variant models.
|
|
299
|
+
:return:
|
|
300
|
+
"""
|
|
301
|
+
Eej = 10 ** loge0
|
|
302
|
+
Mej = mej * solar_mass
|
|
303
|
+
Gamma0 = 1.0 + Eej / (Mej * speed_of_light ** 2)
|
|
304
|
+
vej = speed_of_light * (1.0 - Gamma0 ** (-2)) ** 0.5
|
|
305
|
+
cosmology = kwargs.get('cosmology', cosmo)
|
|
306
|
+
epsilon_e = 10 ** logepse
|
|
307
|
+
epsilon_B = 10 ** logepsb
|
|
308
|
+
n0 = 10 ** logn0
|
|
309
|
+
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
310
|
+
|
|
311
|
+
# in days
|
|
312
|
+
t_dec = 30 * (Eej / 1e49) ** (1.0 / 3.0) * (n0 / 1e0) ** (-1.0 / 3.0) * (vej / speed_of_light) ** (-5.0 / 3.0)
|
|
313
|
+
|
|
314
|
+
fnu_dec_dict = {}
|
|
315
|
+
fnu_func = {}
|
|
316
|
+
temp_time = np.linspace(0.1, 100, 200) * t_dec
|
|
317
|
+
frequency = kwargs['frequency']
|
|
318
|
+
if isinstance(frequency, float):
|
|
319
|
+
frequency = np.ones(len(time)) * frequency
|
|
320
|
+
for freq in frequency:
|
|
321
|
+
# Eq. 11 in Nakar & Piran 2011 (in Mjy)
|
|
322
|
+
fnu_dec_dict[freq] = 0.3 * (Eej / 1e49) * n0 ** (0.25 * (p + 1)) * (epsilon_B / 1e-1) ** (0.25 * (p + 1)) * (
|
|
323
|
+
epsilon_e / 1e-1) ** (p - 1) * (vej / speed_of_light) ** (0.5 * (5 * p - 7)) * (freq / 1.4e9) ** (
|
|
324
|
+
-0.5 * (p - 1)) * (dl / 1e27) ** (-2)
|
|
325
|
+
fnu = fnu_dec_dict[freq] * (temp_time / t_dec) ** 3
|
|
326
|
+
fnu[temp_time > t_dec] = fnu_dec_dict[freq] * (temp_time[temp_time > t_dec] / t_dec) ** (-0.3 * (5 * p - 7))
|
|
327
|
+
fnu_func[freq] = interp1d(temp_time, fnu, bounds_error=False, fill_value='extrapolate')
|
|
328
|
+
|
|
329
|
+
# interpolate onto actual observed frequency and time values
|
|
330
|
+
flux_density = []
|
|
331
|
+
for freq, tt in zip(frequency, time):
|
|
332
|
+
flux_density.append(fnu_func[freq](tt))
|
|
333
|
+
fmjy = flux_density * uu.mJy
|
|
334
|
+
if kwargs['output_format'] == 'flux_density':
|
|
335
|
+
return fmjy.value
|
|
336
|
+
elif kwargs['output_format'] == 'magnitude':
|
|
337
|
+
return calc_ABmag_from_flux_density(fmjy.value).value
|
|
338
|
+
|
|
339
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021ApJ...923L..14M/abstract')
|
|
340
|
+
def thermal_synchrotron_lnu(time, logn0, v0, logr0, eta, logepse, logepsb, xi, p, **kwargs):
|
|
341
|
+
"""
|
|
342
|
+
:param time: time in source frame in seconds
|
|
343
|
+
:param logn0: log10 initial ambient ism density
|
|
344
|
+
:param v0: initial velocity in c
|
|
345
|
+
:param logr0: log10 initial radius
|
|
346
|
+
:param eta: deceleration slope (r = r0 * (time/t0)**eta; v = v0*(time/t0)**(eta-1))
|
|
347
|
+
:param logepse: log10 epsilon_e; electron thermalisation efficiency
|
|
348
|
+
:param logepsb: log10 epsilon_b; magnetic field amplification efficiency
|
|
349
|
+
:param xi: fraction of energy carried by power law electrons
|
|
350
|
+
:param p: electron power law slope
|
|
351
|
+
:param kwargs: extra parameters to change physics/settings
|
|
352
|
+
:param frequency: frequency to calculate model on - Must be same length as time array or a single number)
|
|
353
|
+
:param wind_slope: slope for ism density scaling (nism = n0 * (r/r0)**(-wind_slope)). Default is 2
|
|
354
|
+
:param mu: mean molecular weight, default is 0.62
|
|
355
|
+
:param mu_e: mean molecular weight per electron, default is 1.18
|
|
356
|
+
:return: lnu
|
|
357
|
+
"""
|
|
358
|
+
v0 = v0 * speed_of_light
|
|
359
|
+
r0 = 10**logr0
|
|
360
|
+
t0 = eta * r0 / v0
|
|
361
|
+
radius = r0 * (time / t0) ** eta
|
|
362
|
+
velocity = v0 * (time/t0)**(eta - 1)
|
|
363
|
+
wind_slope = kwargs.get('wind_slope',2)
|
|
364
|
+
mu = kwargs.get('mu', 0.62)
|
|
365
|
+
mu_e = kwargs.get('mu_e', 1.18)
|
|
366
|
+
n0 = 10 ** logn0
|
|
367
|
+
nism = n0 * (radius / r0) ** (-wind_slope)
|
|
368
|
+
|
|
369
|
+
epsilon_T = 10**logepse
|
|
370
|
+
epsilon_B = 10**logepsb
|
|
371
|
+
|
|
372
|
+
frequency = kwargs['frequency']
|
|
373
|
+
|
|
374
|
+
ne = 4.0*mu_e*nism
|
|
375
|
+
beta = velocity/speed_of_light
|
|
376
|
+
|
|
377
|
+
theta0 = epsilon_T * (9.0 * mu * proton_mass / (32.0 * mu_e * electron_mass)) * beta ** 2
|
|
378
|
+
theta = (5.0*theta0-6.0+(25.0*theta0**2+180.0*theta0+36.0)**0.5)/30.0
|
|
379
|
+
|
|
380
|
+
bfield = (9.0*np.pi*epsilon_B*nism*mu*proton_mass)**0.5*velocity
|
|
381
|
+
# mean dynamical time:
|
|
382
|
+
td = radius/velocity
|
|
383
|
+
|
|
384
|
+
z_cool = (6.0 * np.pi * electron_mass * speed_of_light / (sigma_T * bfield ** 2 * td)) / theta
|
|
385
|
+
normalised_frequency_denom = 3.0*theta**2*qe*bfield/(4.0*np.pi*electron_mass*speed_of_light)
|
|
386
|
+
x = frequency / normalised_frequency_denom
|
|
387
|
+
|
|
388
|
+
emissivity_pl = _emissivity_pl(x=x, nism=ne, bfield=bfield, theta=theta, xi=xi, p=p, z_cool=z_cool)
|
|
389
|
+
|
|
390
|
+
emissivity_thermal = _emissivity_thermal(x=x, nism=ne, bfield=bfield, theta=theta, z_cool=z_cool)
|
|
391
|
+
|
|
392
|
+
emissivity = emissivity_thermal + emissivity_pl
|
|
393
|
+
|
|
394
|
+
tau = _tau_nu(x=x, nism=ne, radius=radius, bfield=bfield, theta=theta, xi=xi, p=p, z_cool=z_cool)
|
|
395
|
+
|
|
396
|
+
lnu = 4.0 * np.pi ** 2 * radius ** 3 * emissivity * (1e0 - np.exp(-tau)) / tau
|
|
397
|
+
if np.size(x) > 1:
|
|
398
|
+
lnu[tau < 1e-10] = (4.0 * np.pi ** 2 * radius ** 3 * emissivity)[tau < 1e-10]
|
|
399
|
+
elif tau < 1e-10:
|
|
400
|
+
lnu = 4.0 * np.pi ** 2 * radius ** 3 * emissivity
|
|
401
|
+
return lnu
|
|
402
|
+
|
|
403
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021ApJ...923L..14M/abstract')
|
|
404
|
+
def thermal_synchrotron_fluxdensity(time, redshift, logn0, v0, logr0, eta, logepse, logepsb,
|
|
405
|
+
xi, p, **kwargs):
|
|
406
|
+
"""
|
|
407
|
+
:param time: time in observer frame in days
|
|
408
|
+
:param redshift: redshift
|
|
409
|
+
:param logn0: log10 initial ambient ism density
|
|
410
|
+
:param v0: initial velocity in c
|
|
411
|
+
:param logr0: log10 initial radius
|
|
412
|
+
:param eta: deceleration slope (r = r0 * (time/t0)**eta; v = v0*(time/t0)**(eta-1))
|
|
413
|
+
:param logepse: log10 epsilon_e; electron thermalisation efficiency
|
|
414
|
+
:param logepsb: log10 epsilon_b; magnetic field amplification efficiency
|
|
415
|
+
:param xi: fraction of energy carried by power law electrons
|
|
416
|
+
:param p: electron power law slope
|
|
417
|
+
:param kwargs: extra parameters to change physics/settings
|
|
418
|
+
:param frequency: frequency to calculate model on - Must be same length as time array or a single number)
|
|
419
|
+
:param wind_slope: slope for ism density scaling (nism = n0 * (r/r0)**(-wind_slope)). Default is 2
|
|
420
|
+
:param mu: mean molecular weight, default is 0.62
|
|
421
|
+
:param mu_e: mean molecular weight per electron, default is 1.18
|
|
422
|
+
:param kwargs: extra parameters to change physics and other settings
|
|
423
|
+
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
424
|
+
:return: flux density
|
|
425
|
+
"""
|
|
426
|
+
frequency = kwargs['frequency']
|
|
427
|
+
frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
|
|
428
|
+
new_kwargs = kwargs.copy()
|
|
429
|
+
new_kwargs['frequency'] = frequency
|
|
430
|
+
time = time * day_to_s
|
|
431
|
+
cosmology = kwargs.get('cosmology', cosmo)
|
|
432
|
+
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
433
|
+
lnu = thermal_synchrotron_lnu(time,logn0, v0, logr0, eta, logepse, logepsb, xi, p,**new_kwargs)
|
|
434
|
+
flux_density = lnu / (4.0 * np.pi * dl**2)
|
|
435
|
+
return flux_density
|
|
436
|
+
|
|
437
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022MNRAS.511.5328G/abstract')
|
|
438
|
+
def tde_synchrotron(time, redshift, Mej, vej, logepse, logepsb, p, **kwargs):
|
|
439
|
+
"""
|
|
440
|
+
:param time: time in observer frame in days
|
|
441
|
+
:param redshift: redshift
|
|
442
|
+
:param Mej: mass of the emitting region (solar masses)
|
|
443
|
+
:param vej: initial velocity of the outflow (km/s)
|
|
444
|
+
:param logepse: log10 epsilon_e; electron thermalisation efficiency
|
|
445
|
+
:param logepsb: log10 epsilon_b; magnetic field amplification efficiency
|
|
446
|
+
:param p: electron power law slope
|
|
447
|
+
:param kwargs: extra parameters to change physics/settings
|
|
448
|
+
:param frequency: frequency to calculate model on - Must be same length as time array or a single number)
|
|
449
|
+
:param geometry: geometry of the outflow. Either "sphere" or "cone" is supported.
|
|
450
|
+
:param output_format: Whether to output light curves or physical parameters.
|
|
451
|
+
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
452
|
+
:return: flux density
|
|
453
|
+
"""
|
|
454
|
+
frequency = kwargs['frequency']
|
|
455
|
+
geometry = kwargs.get('geometry', 'sphere')
|
|
456
|
+
cosmology = kwargs.get('cosmology', cosmo)
|
|
457
|
+
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
458
|
+
beta1 = 5.0 / 2.0
|
|
459
|
+
beta2 = (1.0 - p) / 2.0
|
|
460
|
+
s = 1.47 - (0.21 * p)
|
|
461
|
+
eps_e = 10.0 ** logepse
|
|
462
|
+
eps_b = 10.0 ** logepsb
|
|
463
|
+
if geometry == 'cone':
|
|
464
|
+
F_A = 0.13
|
|
465
|
+
F_V = 1.15
|
|
466
|
+
else:
|
|
467
|
+
F_A = 1.0
|
|
468
|
+
F_V = 4.0/3.0
|
|
469
|
+
|
|
470
|
+
beta = vej * km_cgs / speed_of_light
|
|
471
|
+
E = Mej * solar_mass * (beta * speed_of_light) ** 2.0 / 2.0
|
|
472
|
+
R = time * day_to_s * beta * speed_of_light / ((1 - beta) * (1 + redshift))
|
|
473
|
+
eps = 11.0 * eps_b / (6.0 * eps_e)
|
|
474
|
+
R_eq = R / eps ** (1.0 / 17.0)
|
|
475
|
+
E_eq = E / ((11.0 / 17.0) * eps ** (-6.0 / 17.0) + (6.0 / 17.0) * eps ** (11.0 / 17.0))
|
|
476
|
+
chi_e = 2.0
|
|
477
|
+
xi = 1.0 + (1.0 / eps_e)
|
|
478
|
+
|
|
479
|
+
R_prefac = (1e17 * (21.8 * 525.0 ** (p - 1.0)) ** (1.0 / (13.0 + 2.0 * p))
|
|
480
|
+
* chi_e ** ((2.0 - p) / (13.0 + 2.0 * p))
|
|
481
|
+
* xi ** (1.0 / (13.0 + 2.0 * p))
|
|
482
|
+
* (dl / 1.0e28) ** (2.0 * (p + 6.0) / (13.0 + 2.0 * p))
|
|
483
|
+
* (1.0 + redshift) ** (-(19.0 + 3.0 * p) / (13.0 + 2.0 * p))
|
|
484
|
+
* F_A ** (-(5.0 + p) / (13.0 + 2.0 * p))
|
|
485
|
+
* F_V ** (-1.0 / (13.0 + 2.0 * p))
|
|
486
|
+
* 4.0 ** (1.0 / (13.0 + 2.0 * p)))
|
|
487
|
+
E_prefac = (1.3e48 * 21.8 ** ((-2.0 * (p + 1.0)) / (13.0 + 2.0 * p))
|
|
488
|
+
* (525 ** (p - 1.0) * chi_e ** (2.0 - p)) ** (11.0 / (13.0 + 2.0 * p))
|
|
489
|
+
* xi ** (11.0 / (13.0 + 2.0 * p))
|
|
490
|
+
* (dl / 1.0e28) ** (2.0 * (3.0 * p + 14.0) / (13.0 + 2.0 * p))
|
|
491
|
+
* (1.0 + redshift) ** ((-27.0 + 5.0 * p) / (13.0 + 2.0 * p))
|
|
492
|
+
* F_A ** (-(3.0 * (p + 1.0)) / (13.0 + 2.0 * p))
|
|
493
|
+
* F_V ** ((2.0 * (p + 1.0)) / (13.0 + 2.0 * p))
|
|
494
|
+
* 4.0 ** (11.0 / (13.0 + 2.0 * p)))
|
|
495
|
+
|
|
496
|
+
Fvb = (E_prefac * R_eq / (R_prefac * E_eq)) ** ((2.0 * (p + 4.0)) / (13.0 + 2.0 * p))
|
|
497
|
+
vb = (R_prefac * Fvb ** ((p + 6.0) / (13.0 + 2.0 * p)) / R_eq) * 1.0e10
|
|
498
|
+
|
|
499
|
+
if kwargs['output_format'] == 'physical_parameters':
|
|
500
|
+
physical_parameters = namedtuple('physical_parameters', ['E', 'R', 'N_e', 'n_e', 'B'])
|
|
501
|
+
gamma_m = 2.0
|
|
502
|
+
gamma_a = (525.0 * Fvb * (dl / 1.0e28) ** 2.0 * (1.0 + redshift) ** -3.0
|
|
503
|
+
* (vb / 1.0e10) ** -2.0 / (F_A * (R / 1.0e17) ** 2.0))
|
|
504
|
+
N_e = (4.0e54 * Fvb ** 3.0 * (dl / 1.0e28) ** 6.0 * (vb / 1.0e10) ** -5.0
|
|
505
|
+
* (1.0 + redshift) ** -8.0 * F_A ** -2.0 * (R / 1.0e17) ** -4.0
|
|
506
|
+
* (gamma_m / gamma_a) ** (1.0 - p))
|
|
507
|
+
n_e = N_e / (4.0 /3.0 * np.pi * R ** 3.0)
|
|
508
|
+
B = (1.3e-2 * Fvb ** -2.0 * (dl / 1.0e28) ** -4.0 * (vb / 1.0e10) ** 5.0
|
|
509
|
+
* (1.0 + redshift) ** 7.0 * F_A ** 2.0 * (R / 1.0e17) ** 4.0)
|
|
510
|
+
physical_parameters.E = E
|
|
511
|
+
physical_parameters.R = R
|
|
512
|
+
physical_parameters.N_e = N_e
|
|
513
|
+
physical_parameters.n_e = n_e
|
|
514
|
+
physical_parameters.B = B
|
|
515
|
+
return physical_parameters
|
|
516
|
+
else:
|
|
517
|
+
flux_density = Fvb * ((frequency / vb) ** (-beta1 * s) + (frequency / vb) ** (-beta2 * s)) ** (-1.0 / s)
|
|
518
|
+
return flux_density
|