redback 1.0.1__py3-none-any.whl → 1.0.3__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.
Files changed (66) hide show
  1. redback/__init__.py +4 -0
  2. redback/constraints.py +46 -25
  3. redback/eos.py +1 -0
  4. redback/get_data/fink.py +1 -1
  5. redback/get_data/lasair.py +3 -4
  6. redback/get_data/swift.py +7 -7
  7. redback/interaction_processes.py +1 -4
  8. redback/likelihoods.py +207 -21
  9. redback/model_library.py +2 -2
  10. redback/plotting.py +10 -10
  11. redback/priors/bazin_sne.prior +5 -0
  12. redback/priors/csm_interaction.prior +6 -7
  13. redback/priors/csm_nickel.prior +3 -3
  14. redback/priors/csm_shock_and_arnett.prior +11 -0
  15. redback/priors/csm_shock_and_arnett_bolometric.prior +10 -0
  16. redback/priors/csm_shock_breakout.prior +7 -0
  17. redback/priors/nicholl_bns.prior +2 -1
  18. redback/priors/one_comp_kne_rosswog_heatingrate.prior +5 -0
  19. redback/priors/pwn.prior +7 -0
  20. redback/priors/shocked_cocoon.prior +6 -6
  21. redback/priors/sn_fallback.prior +8 -0
  22. redback/priors/stream_stream_tde.prior +10 -0
  23. redback/priors/stream_stream_tde_bolometric.prior +9 -0
  24. redback/priors/tde_analytical.prior +5 -5
  25. redback/priors/tde_analytical_bolometric.prior +6 -4
  26. redback/priors/tde_fallback.prior +9 -0
  27. redback/priors/tde_fallback_bolometric.prior +6 -0
  28. redback/priors/tde_synchrotron.prior +6 -0
  29. redback/priors/tophat_from_emulator.prior +9 -0
  30. redback/priors/two_comp_kne_rosswog_heatingrate.prior +9 -0
  31. redback/priors/two_layer_stratified_kilonova.prior +1 -1
  32. redback/priors/villar_sne.prior +7 -0
  33. redback/priors.py +12 -1
  34. redback/sed.py +194 -2
  35. redback/simulate_transients.py +71 -35
  36. redback/tables/GRBs_w_redshift.txt +430 -413
  37. redback/tables/LGRB_table.txt +70 -6
  38. redback/tables/SGRB_table.txt +139 -135
  39. redback/tables/filters.csv +14 -0
  40. redback/tables/qdot_rosswogkorobkin24.pck +0 -0
  41. redback/tables/ztf.tar.gz +0 -0
  42. redback/transient/afterglow.py +17 -7
  43. redback/transient/kilonova.py +6 -3
  44. redback/transient/prompt.py +14 -4
  45. redback/transient/supernova.py +7 -3
  46. redback/transient/tde.py +6 -3
  47. redback/transient/transient.py +29 -12
  48. redback/transient_models/afterglow_models.py +152 -146
  49. redback/transient_models/combined_models.py +69 -48
  50. redback/transient_models/extinction_models.py +6 -6
  51. redback/transient_models/general_synchrotron_models.py +518 -0
  52. redback/transient_models/integrated_flux_afterglow_models.py +2 -2
  53. redback/transient_models/kilonova_models.py +310 -61
  54. redback/transient_models/magnetar_driven_ejecta_models.py +2 -2
  55. redback/transient_models/magnetar_models.py +1 -1
  56. redback/transient_models/phenomenological_models.py +69 -1
  57. redback/transient_models/shock_powered_models.py +159 -110
  58. redback/transient_models/supernova_models.py +211 -43
  59. redback/transient_models/tde_models.py +975 -5
  60. redback/utils.py +309 -16
  61. {redback-1.0.1.dist-info → redback-1.0.3.dist-info}/METADATA +46 -6
  62. {redback-1.0.1.dist-info → redback-1.0.3.dist-info}/RECORD +65 -49
  63. {redback-1.0.1.dist-info → redback-1.0.3.dist-info}/WHEEL +1 -1
  64. redback/tables/ztf_obslog.csv +0 -106649
  65. {redback-1.0.1.dist-info → redback-1.0.3.dist-info}/LICENCE.md +0 -0
  66. {redback-1.0.1.dist-info → redback-1.0.3.dist-info}/top_level.txt +0 -0
@@ -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
@@ -1,7 +1,7 @@
1
1
  from inspect import isfunction
2
2
  import numpy as np
3
3
 
4
- from scipy.integrate import simps
4
+ from scipy.integrate import simpson
5
5
 
6
6
  from redback.utils import logger, citation_wrapper
7
7
 
@@ -45,7 +45,7 @@ def integrated_flux_afterglowpy_base_model(time, **kwargs):
45
45
  lightcurve_at_nu = flux_density.reshape(len(nu_1d), len(time))
46
46
  prefactor = 1e-26
47
47
  lightcurve_at_nu = prefactor * lightcurve_at_nu
48
- integrated_flux = simps(lightcurve_at_nu, axis=0, x=nu_1d)
48
+ integrated_flux = simpson(np.array(lightcurve_at_nu), axis=0, x=nu_1d)
49
49
  return integrated_flux
50
50
 
51
51
  @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021arXiv210510108S/abstract')