redback 1.0.2__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 (48) hide show
  1. redback/constraints.py +15 -0
  2. redback/eos.py +1 -0
  3. redback/get_data/fink.py +1 -1
  4. redback/model_library.py +2 -2
  5. redback/priors/bazin_sne.prior +5 -0
  6. redback/priors/csm_shock_and_arnett.prior +11 -0
  7. redback/priors/csm_shock_and_arnett_bolometric.prior +10 -0
  8. redback/priors/csm_shock_breakout.prior +7 -0
  9. redback/priors/nicholl_bns.prior +2 -1
  10. redback/priors/pwn.prior +7 -0
  11. redback/priors/shocked_cocoon.prior +6 -6
  12. redback/priors/sn_fallback.prior +8 -0
  13. redback/priors/stream_stream_tde.prior +10 -0
  14. redback/priors/stream_stream_tde_bolometric.prior +9 -0
  15. redback/priors/tde_fallback.prior +9 -0
  16. redback/priors/tde_fallback_bolometric.prior +6 -0
  17. redback/priors/tde_synchrotron.prior +6 -0
  18. redback/priors/two_comp_kne_rosswog_heatingrate.prior +2 -2
  19. redback/priors/villar_sne.prior +7 -0
  20. redback/priors.py +1 -1
  21. redback/simulate_transients.py +11 -4
  22. redback/tables/GRBs_w_redshift.txt +430 -413
  23. redback/tables/LGRB_table.txt +70 -6
  24. redback/tables/SGRB_table.txt +139 -135
  25. redback/tables/qdot_rosswogkorobkin24.pck +0 -0
  26. redback/transient/afterglow.py +14 -5
  27. redback/transient/kilonova.py +5 -2
  28. redback/transient/prompt.py +14 -4
  29. redback/transient/supernova.py +6 -2
  30. redback/transient/tde.py +5 -2
  31. redback/transient/transient.py +27 -10
  32. redback/transient_models/afterglow_models.py +110 -146
  33. redback/transient_models/combined_models.py +39 -33
  34. redback/transient_models/extinction_models.py +1 -2
  35. redback/transient_models/general_synchrotron_models.py +518 -0
  36. redback/transient_models/integrated_flux_afterglow_models.py +2 -2
  37. redback/transient_models/kilonova_models.py +88 -72
  38. redback/transient_models/magnetar_models.py +1 -1
  39. redback/transient_models/phenomenological_models.py +57 -2
  40. redback/transient_models/shock_powered_models.py +159 -110
  41. redback/transient_models/supernova_models.py +161 -7
  42. redback/transient_models/tde_models.py +849 -4
  43. redback/utils.py +28 -12
  44. {redback-1.0.2.dist-info → redback-1.0.3.dist-info}/METADATA +42 -5
  45. {redback-1.0.2.dist-info → redback-1.0.3.dist-info}/RECORD +48 -34
  46. {redback-1.0.2.dist-info → redback-1.0.3.dist-info}/WHEEL +1 -1
  47. {redback-1.0.2.dist-info → redback-1.0.3.dist-info}/LICENCE.md +0 -0
  48. {redback-1.0.2.dist-info → redback-1.0.3.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,157 @@
1
1
  import numpy as np
2
2
  from collections import namedtuple
3
3
  from scipy import special
4
+ from scipy.interpolate import interp1d
4
5
  from redback.constants import *
5
6
  import redback.sed as sed
6
7
  from astropy.cosmology import Planck18 as cosmo # noqa
7
8
  from redback.utils import calc_kcorrected_properties, citation_wrapper, lambda_to_nu
8
9
 
10
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022ApJ...933..238M/abstract')
11
+ def _csm_shock_breakout(time, csm_mass, v_min, beta, kappa, shell_radius, shell_width_ratio, **kwargs):
12
+ """
13
+ Dense CSM shock breakout and cooling model From Margalit 2022
14
+
15
+ :param time: time in days
16
+ :param csm_mass: mass of CSM shell in g
17
+ :param v_min: minimum velocity in km/s
18
+ :param beta: velocity ratio in c (beta < 1)
19
+ :param kappa: opacity in cm^2/g
20
+ :param shell_radius: radius of shell in 10^14 cm
21
+ :param shell_width_ratio: shell width ratio (deltaR/R0)
22
+ :return: namedtuple with lbol, r_photosphere, and temperature
23
+ """
24
+ v0 = v_min * 1e5
25
+ e0 = 0.5 * csm_mass * v0**2
26
+ shell_radius *= 1e14
27
+ shell_width = shell_width_ratio * shell_radius
28
+ tdyn = shell_radius / v0
29
+ tshell = shell_width / v0
30
+ time = time * day_to_s
31
+
32
+ velocity = v0/beta
33
+
34
+ tda = (3 * kappa * csm_mass / (4 * np.pi * speed_of_light * velocity)) ** 0.5
35
+
36
+ term1 = ((tdyn + tshell + time) ** 3 - (tdyn + beta * time) ** 3) ** (2 / 3)
37
+ term2 = ((tdyn + tshell) ** 3 - tdyn ** 3) ** (1 / 3)
38
+ term3 = (1 + (1 - beta) * time / tshell) ** (
39
+ -3 * (tdyn / tda) ** 2 * ((1 - beta - beta * tshell / tdyn) ** 2) / (1 - beta) ** 3)
40
+ term4 = np.exp(-time * ((1 - beta ** 3) * time + (2 - 4 * beta * (beta + 1)) * tshell + 6 * (1 - beta ** 2) * tdyn) / (
41
+ 2 * (1 - beta) ** 2 * tda ** 2))
42
+
43
+ lbol = e0 * term1 / (tda ** 2 * (tshell + (1 - beta) * time) ** 2) * term2 * term3 * term4
44
+
45
+ volume = 4./3. * np.pi * velocity**3 * ((tdyn + tshell + time)**3 - (tdyn + beta*time)**3)
46
+ radius = velocity * (tdyn + tshell + time)
47
+ rphotosphere = radius - 2*volume/(3 * kappa * csm_mass)
48
+ teff = (lbol / (4 * np.pi * rphotosphere ** 2 * sigma_sb)) ** 0.25
49
+ output = namedtuple('output', ['lbol', 'r_photosphere', 'temperature', 'time_temp',
50
+ 'tdyn', 'tshell', 'e0', 'tda', 'velocity'])
51
+ output.lbol = lbol
52
+ output.r_photosphere = rphotosphere
53
+ output.temperature = teff
54
+ output.tdyn = tdyn
55
+ output.tshell = tshell
56
+ output.e0 = e0
57
+ output.tda = tda
58
+ output.velocity = velocity
59
+ output.time_temp = time
60
+ return output
61
+
62
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022ApJ...933..238M/abstract')
63
+ def csm_shock_breakout_bolometric(time, csm_mass, v_min, beta, kappa, shell_radius, shell_width_ratio, **kwargs):
64
+ """
65
+ Dense CSM shock breakout and cooling model From Margalit 2022
66
+
67
+ :param time: time in days in source frame
68
+ :param csm_mass: mass of CSM shell in solar masses
69
+ :param v_min: minimum velocity in km/s
70
+ :param beta: velocity ratio in c (beta < 1)
71
+ :param kappa: opacity in cm^2/g
72
+ :param shell_radius: radius of shell in 10^14 cm
73
+ :param shell_width_ratio: shell width ratio (deltaR/R0)
74
+ :param kwargs: Additional parameters required by model
75
+ :param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
76
+ :return: bolometric luminosity
77
+ """
78
+ csm_mass = csm_mass * solar_mass
79
+ time_temp = np.geomspace(1e-2, 200, 300) # days
80
+ outputs = _csm_shock_breakout(time_temp, v_min=v_min, beta=beta,
81
+ kappa=kappa, csm_mass=csm_mass, shell_radius=shell_radius,
82
+ shell_width_ratio=shell_width_ratio, **kwargs)
83
+ func = interp1d(time_temp, outputs.lbol, fill_value='extrapolate')
84
+ return func(time)
85
+
86
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022ApJ...933..238M/abstract')
87
+ def csm_shock_breakout(time, redshift, csm_mass, v_min, beta, kappa, shell_radius, shell_width_ratio, **kwargs):
88
+ """
89
+ Dense CSM shock breakout and cooling model From Margalit 2022
90
+
91
+ :param time: time in days in observer frame
92
+ :param redshift: redshift
93
+ :param csm_mass: mass of CSM shell in solar masses
94
+ :param v_min: minimum velocity in km/s
95
+ :param beta: velocity ratio in c (beta < 1)
96
+ :param kappa: opacity in cm^2/g
97
+ :param shell_radius: radius of shell in 10^14 cm
98
+ :param shell_width_ratio: shell width ratio (deltaR/R0)
99
+ :param kwargs: Additional parameters required by model
100
+ :param frequency: Required if output_format is 'flux_density'.
101
+ frequency to calculate - Must be same length as time array or a single number).
102
+ :param bands: Required if output_format is 'magnitude' or 'flux'.
103
+ :param output_format: 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
104
+ :param lambda_array: Optional argument to set your desired wavelength array (in Angstroms) to evaluate the SED on.
105
+ :param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
106
+ :return: set by output format - 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
107
+ :return:
108
+ """
109
+ csm_mass = csm_mass * solar_mass
110
+ cosmology = kwargs.get('cosmology', cosmo)
111
+ dl = cosmology.luminosity_distance(redshift).cgs.value
112
+ time_temp = np.geomspace(1e-2, 40, 300) #days
113
+ time_obs = time
114
+ outputs = _csm_shock_breakout(time_temp, v_min=v_min, beta=beta,
115
+ kappa=kappa, csm_mass=csm_mass, shell_radius=shell_radius,
116
+ shell_width_ratio=shell_width_ratio, **kwargs)
117
+ if kwargs['output_format'] == 'namedtuple':
118
+ return outputs
119
+ elif kwargs['output_format'] == 'flux_density':
120
+ time = time_obs
121
+ frequency = kwargs['frequency']
122
+ # interpolate properties onto observation times
123
+ temp_func = interp1d(time_temp, y=outputs.temperature)
124
+ rad_func = interp1d(time_temp, y=outputs.r_photosphere)
125
+ # convert to source frame time and frequency
126
+ frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
127
+
128
+ temp = temp_func(time)
129
+ photosphere = rad_func(time)
130
+
131
+ flux_density = sed.blackbody_to_flux_density(temperature=temp, r_photosphere=photosphere,
132
+ dl=dl, frequency=frequency)
133
+
134
+ return flux_density.to(uu.mJy).value
135
+ else:
136
+ lambda_observer_frame = kwargs.get('lambda_array', np.geomspace(100, 60000, 200))
137
+ time_observer_frame = time_temp * (1. + redshift)
138
+ frequency, time = calc_kcorrected_properties(frequency=lambda_to_nu(lambda_observer_frame),
139
+ redshift=redshift, time=time_observer_frame)
140
+ fmjy = sed.blackbody_to_flux_density(temperature=outputs.temperature,
141
+ r_photosphere=outputs.r_photosphere, frequency=frequency[:, None], dl=dl)
142
+ fmjy = fmjy.T
143
+ spectra = fmjy.to(uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
144
+ equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom))
145
+ if kwargs['output_format'] == 'spectra':
146
+ return namedtuple('output', ['time', 'lambdas', 'spectra'])(time=time_observer_frame,
147
+ lambdas=lambda_observer_frame,
148
+ spectra=spectra)
149
+ else:
150
+ return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
151
+ spectra=spectra, lambda_array=lambda_observer_frame,
152
+ **kwargs)
153
+
154
+
9
155
  @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021ApJ...909..209P/abstract')
10
156
  def _shock_cooling(time, mass, radius, energy, **kwargs):
11
157
  """
@@ -22,6 +168,7 @@ def _shock_cooling(time, mass, radius, energy, **kwargs):
22
168
  delta = kwargs.get('delta',1.1)
23
169
  kk_pow = (nn - 3) * (3 - delta) / (4 * np.pi * (nn - delta))
24
170
  kappa = 0.2
171
+ mass = mass * solar_mass
25
172
  vt = (((nn - 5) * (5 - delta) / ((nn - 3) * (3 - delta))) * (2 * energy / mass))**0.5
26
173
  td = ((3 * kappa * kk_pow * mass) / ((nn - 1) * vt * speed_of_light))**0.5
27
174
 
@@ -34,18 +181,17 @@ def _shock_cooling(time, mass, radius, energy, **kwargs):
34
181
 
35
182
  tph = np.sqrt(3 * kappa * kk_pow * mass / (2 * (nn - 1) * vt * vt))
36
183
  r_photosphere_pre_td = np.power(tph / time, 2 / (nn - 1)) * vt * time
37
- r_photosphere_post_td = (np.power((delta - 1) / (nn - 1) * ((time / td) ** 2 - 1) + 1, -1 / (delta + 1))* vt * time)
38
- r_photosphere = np.zeros(len(time))
39
- r_photosphere[time < td] = r_photosphere_pre_td[time < td]
40
- r_photosphere[time >= td] = r_photosphere_post_td[time >= td]
184
+ r_photosphere_post_td = (np.power((delta - 1) / (nn - 1) * ((time / td) ** 2 - 1) + 1, -1 / (delta + 1)) * vt * time)
185
+ r_photosphere = r_photosphere_pre_td + r_photosphere_post_td
41
186
 
42
187
  sigmaT4 = lbol / (4 * np.pi * r_photosphere**2)
43
188
  temperature = np.power(sigmaT4 / sigma_sb, 0.25)
44
189
 
45
- output = namedtuple('output', ['lbol', 'r_photosphere', 'temperature'])
190
+ output = namedtuple('output', ['lbol', 'r_photosphere', 'temperature', 'td'])
46
191
  output.lbol = lbol
47
192
  output.r_photosphere = r_photosphere
48
193
  output.temperature = temperature
194
+ output.td = td
49
195
  return output
50
196
 
51
197
  @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021MNRAS.505.3016N/abstract')
@@ -138,7 +284,7 @@ def shock_cooling(time, redshift, log10_mass, log10_radius, log10_energy, **kwar
138
284
  dl=dl, frequency=frequency)
139
285
  return flux_density.to(uu.mJy).value
140
286
  else:
141
- time_temp = np.linspace(1e-4, 50, 50)
287
+ time_temp = np.linspace(1e-2, 10, 100)
142
288
  lambda_observer_frame = kwargs.get('lambda_array', np.geomspace(100, 60000, 100))
143
289
 
144
290
  time_observer_frame = time_temp
@@ -155,7 +301,7 @@ def shock_cooling(time, redshift, log10_mass, log10_radius, log10_energy, **kwar
155
301
  lambdas=lambda_observer_frame,
156
302
  spectra=spectra)
157
303
  else:
158
- return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame / day_to_s,
304
+ return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
159
305
  spectra=spectra, lambda_array=lambda_observer_frame,
160
306
  **kwargs)
161
307
 
@@ -320,110 +466,12 @@ def _tau_nu(x, nism, radius, bfield, theta, xi, p, z_cool):
320
466
  val = radius*(alphanu_thermal + alphanu_pl)
321
467
  return val
322
468
 
323
- @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021ApJ...923L..14M/abstract')
324
- def thermal_synchrotron_lnu(time, logn0, v0, logr0, eta, logepse, logepsb, xi, p, **kwargs):
325
- """
326
- :param time: time in source frame in seconds
327
- :param logn0: log10 initial ambient ism density
328
- :param v0: initial velocity in c
329
- :param logr0: log10 initial radius
330
- :param eta: deceleration slope (r = r0 * (time/t0)**eta; v = v0*(time/t0)**(eta-1))
331
- :param logepse: log10 epsilon_e; electron thermalisation efficiency
332
- :param logepsb: log10 epsilon_b; magnetic field amplification efficiency
333
- :param xi: fraction of energy carried by power law electrons
334
- :param p: electron power law slope
335
- :param kwargs: extra parameters to change physics/settings
336
- :param frequency: frequency to calculate model on - Must be same length as time array or a single number)
337
- :param wind_slope: slope for ism density scaling (nism = n0 * (r/r0)**(-wind_slope)). Default is 2
338
- :param mu: mean molecular weight, default is 0.62
339
- :param mu_e: mean molecular weight per electron, default is 1.18
340
- :return: lnu
341
- """
342
- v0 = v0 * speed_of_light
343
- r0 = 10**logr0
344
- t0 = eta * r0 / v0
345
- radius = r0 * (time / t0) ** eta
346
- velocity = v0 * (time/t0)**(eta - 1)
347
- wind_slope = kwargs.get('wind_slope',2)
348
- mu = kwargs.get('mu', 0.62)
349
- mu_e = kwargs.get('mu_e', 1.18)
350
- n0 = 10 ** logn0
351
- nism = n0 * (radius / r0) ** (-wind_slope)
352
-
353
- epsilon_T = 10**logepse
354
- epsilon_B = 10**logepsb
355
-
356
- frequency = kwargs['frequency']
357
-
358
- ne = 4.0*mu_e*nism
359
- beta = velocity/speed_of_light
360
-
361
- theta0 = epsilon_T * (9.0 * mu * proton_mass / (32.0 * mu_e * electron_mass)) * beta ** 2
362
- theta = (5.0*theta0-6.0+(25.0*theta0**2+180.0*theta0+36.0)**0.5)/30.0
363
-
364
- bfield = (9.0*np.pi*epsilon_B*nism*mu*proton_mass)**0.5*velocity
365
- # mean dynamical time:
366
- td = radius/velocity
367
-
368
- z_cool = (6.0 * np.pi * electron_mass * speed_of_light / (sigma_T * bfield ** 2 * td)) / theta
369
- normalised_frequency_denom = 3.0*theta**2*qe*bfield/(4.0*np.pi*electron_mass*speed_of_light)
370
- x = frequency / normalised_frequency_denom
371
-
372
- emissivity_pl = _emissivity_pl(x=x, nism=ne, bfield=bfield, theta=theta, xi=xi, p=p, z_cool=z_cool)
373
-
374
- emissivity_thermal = _emissivity_thermal(x=x, nism=ne, bfield=bfield, theta=theta, z_cool=z_cool)
375
-
376
- emissivity = emissivity_thermal + emissivity_pl
377
-
378
- tau = _tau_nu(x=x, nism=ne, radius=radius, bfield=bfield, theta=theta, xi=xi, p=p, z_cool=z_cool)
379
-
380
- lnu = 4.0 * np.pi ** 2 * radius ** 3 * emissivity * (1e0 - np.exp(-tau)) / tau
381
- if np.size(x) > 1:
382
- lnu[tau < 1e-10] = (4.0 * np.pi ** 2 * radius ** 3 * emissivity)[tau < 1e-10]
383
- elif tau < 1e-10:
384
- lnu = 4.0 * np.pi ** 2 * radius ** 3 * emissivity
385
- return lnu
386
-
387
- @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2021ApJ...923L..14M/abstract')
388
- def thermal_synchrotron_fluxdensity(time, redshift, logn0, v0, logr0, eta, logepse, logepsb,
389
- xi, p, **kwargs):
390
- """
391
- :param time: time in observer frame in days
392
- :param redshift: redshift
393
- :param logn0: log10 initial ambient ism density
394
- :param v0: initial velocity in c
395
- :param logr0: log10 initial radius
396
- :param eta: deceleration slope (r = r0 * (time/t0)**eta; v = v0*(time/t0)**(eta-1))
397
- :param logepse: log10 epsilon_e; electron thermalisation efficiency
398
- :param logepsb: log10 epsilon_b; magnetic field amplification efficiency
399
- :param xi: fraction of energy carried by power law electrons
400
- :param p: electron power law slope
401
- :param kwargs: extra parameters to change physics/settings
402
- :param frequency: frequency to calculate model on - Must be same length as time array or a single number)
403
- :param wind_slope: slope for ism density scaling (nism = n0 * (r/r0)**(-wind_slope)). Default is 2
404
- :param mu: mean molecular weight, default is 0.62
405
- :param mu_e: mean molecular weight per electron, default is 1.18
406
- :param kwargs: extra parameters to change physics and other settings
407
- :param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
408
- :return: flux density
409
- """
410
- frequency = kwargs['frequency']
411
- frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
412
- new_kwargs = kwargs.copy()
413
- new_kwargs['frequency'] = frequency
414
- time = time * day_to_s
415
- cosmology = kwargs.get('cosmology', cosmo)
416
- dl = cosmology.luminosity_distance(redshift).cgs.value
417
- lnu = thermal_synchrotron_lnu(time,logn0, v0, logr0, eta, logepse, logepsb, xi, p,**new_kwargs)
418
- flux_density = lnu / (4.0 * np.pi * dl**2)
419
- return flux_density
420
-
421
469
  @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2018ApJ...855..103P/abstract')
422
470
  def _shocked_cocoon(time, mej, vej, eta, tshock, shocked_fraction, cos_theta_cocoon, kappa):
423
471
  """
424
472
  :param time: source frame time in days
425
473
  :param mej: ejecta mass in solar masses
426
- :param vej: ejecta mass in km/s
474
+ :param vej: ejecta velocity in c
427
475
  :param eta: slope for ejecta density profile
428
476
  :param tshock: shock time in seconds
429
477
  :param shocked_fraction: fraction of ejecta mass shocked
@@ -431,8 +479,9 @@ def _shocked_cocoon(time, mej, vej, eta, tshock, shocked_fraction, cos_theta_coc
431
479
  :param kappa: opacity
432
480
  :return: namedtuple with lbol, r_photosphere, and temperature
433
481
  """
434
- diff_const = solar_mass / (4*np.pi * speed_of_light * km_cgs)
435
482
  c_kms = speed_of_light / km_cgs
483
+ vej = vej * c_kms
484
+ diff_const = solar_mass / (4*np.pi * speed_of_light * km_cgs)
436
485
  rshock = tshock * speed_of_light
437
486
  shocked_mass = mej * shocked_fraction
438
487
  theta = np.arccos(cos_theta_cocoon)
@@ -479,7 +528,7 @@ def shocked_cocoon(time, redshift, mej, vej, eta, tshock, shocked_fraction, cos_
479
528
  :param time: observer frame time in days
480
529
  :param redshift: redshift
481
530
  :param mej: ejecta mass in solar masses
482
- :param vej: ejecta mass in km/s
531
+ :param vej: ejecta velocity in c
483
532
  :param eta: slope for ejecta density profile
484
533
  :param tshock: shock time in seconds
485
534
  :param shocked_fraction: fraction of ejecta mass shocked
@@ -509,7 +558,7 @@ def shocked_cocoon(time, redshift, mej, vej, eta, tshock, shocked_fraction, cos_
509
558
  return flux_density.to(uu.mJy).value
510
559
  else:
511
560
  lambda_observer_frame = kwargs.get('frequency_array', np.geomspace(100, 60000, 100))
512
- time_temp = np.linspace(1e-4, 50, 30)
561
+ time_temp = np.linspace(1e-2, 10, 100)
513
562
  time_observer_frame = time_temp
514
563
  frequency, time = calc_kcorrected_properties(frequency=lambda_to_nu(lambda_observer_frame),
515
564
  redshift=redshift, time=time_observer_frame)
@@ -526,7 +575,7 @@ def shocked_cocoon(time, redshift, mej, vej, eta, tshock, shocked_fraction, cos_
526
575
  lambdas=lambda_observer_frame,
527
576
  spectra=spectra)
528
577
  else:
529
- return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame / day_to_s,
578
+ return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
530
579
  spectra=spectra, lambda_array=lambda_observer_frame,
531
580
  **kwargs)
532
581
 
@@ -1,6 +1,6 @@
1
1
  import numpy as np
2
2
  import pandas as pd
3
- from redback.transient_models.phenomenological_models import exponential_powerlaw
3
+ from redback.transient_models.phenomenological_models import exponential_powerlaw, fallback_lbol
4
4
  from redback.transient_models.magnetar_models import magnetar_only, basic_magnetar
5
5
  from redback.transient_models.magnetar_driven_ejecta_models import _ejecta_dynamics_and_interaction
6
6
  from redback.transient_models.shock_powered_models import _shock_cooling
@@ -107,11 +107,11 @@ def sncosmo_models(time, redshift, model_kwargs=None, **kwargs):
107
107
  if kwargs['output_format'] == 'flux':
108
108
  bands = kwargs['bands']
109
109
  magnitude = model.bandmag(time=time, band=bands, magsys='ab')
110
- return sed.bandpass_magnitude_to_flux(magnitude=magnitude, bands=bands)
110
+ return np.nan_to_num(sed.bandpass_magnitude_to_flux(magnitude=magnitude, bands=bands))
111
111
  elif kwargs['output_format'] == 'magnitude':
112
112
  bands = kwargs['bands']
113
113
  magnitude = model.bandmag(time=time, band=bands, magsys='ab')
114
- return magnitude
114
+ return np.nan_to_num(magnitude)
115
115
  elif kwargs['output_format'] == 'sncosmo_source':
116
116
  return model
117
117
 
@@ -141,6 +141,64 @@ def exponential_powerlaw_bolometric(time, lbol_0, alpha_1, alpha_2, tpeak_d, **k
141
141
  lbol = interaction_class.new_luminosity
142
142
  return lbol
143
143
 
144
+ def sn_fallback(time, redshift, logl1, tr, **kwargs):
145
+ """
146
+ :param time: observer frame time in days
147
+ :param redshift: source redshift
148
+ :param logl1: bolometric luminosity scale in log10 (cgs)
149
+ :param tr: transition time for luminosity
150
+ :param kwargs: Must be all the kwargs required by the specific interaction_process, photosphere, sed methods used
151
+ e.g., for Diffusion and TemperatureFloor: kappa, kappa_gamma, mej (solar masses), vej (km/s), floor temperature
152
+ :param interaction_process: Default is Diffusion.
153
+ Can also be None in which case the output is just the raw engine luminosity, or another interaction process.
154
+ :param photosphere: Default is TemperatureFloor.
155
+ kwargs must vej or relevant parameters if using different photosphere model
156
+ :param sed: Default is blackbody.
157
+ :param frequency: Required if output_format is ‘flux_density’.
158
+ frequency to calculate - Must be same length as time array or a single number).
159
+ :param bands: Required if output_format is ‘magnitude’ or ‘flux’.
160
+ :param output_format: ‘flux_density’, ‘magnitude’, ‘spectra’, ‘flux’, ‘sncosmo_source’
161
+ :param lambda_array: Optional argument to set your desired wavelength array (in Angstroms) to evaluate the SED on.
162
+ :param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
163
+ :return: set by output format - ‘flux_density’, ‘magnitude’, ‘spectra’, ‘flux’, ‘sncosmo_source’
164
+ """
165
+ kwargs["interaction_process"] = kwargs.get("interaction_process", ip.Diffusion)
166
+ kwargs["photosphere"] = kwargs.get("photosphere", photosphere.TemperatureFloor)
167
+ kwargs["sed"] = kwargs.get("sed", sed.Blackbody)
168
+ cosmology = kwargs.get("cosmology", cosmo)
169
+ dl = cosmology.luminosity_distance(redshift).cgs.value
170
+ if kwargs['output_format'] == 'flux_density':
171
+ frequency = kwargs['frequency']
172
+ frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
173
+ lbol = fallback_lbol(time=time, logl1=logl1, tr=tr)
174
+ photo = kwargs['photosphere'](time=time, luminosity=lbol, **kwargs)
175
+ sed_1 = kwargs['sed'](temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
176
+ frequency=frequency, luminosity_distance=dl)
177
+ flux_density = sed_1.flux_density
178
+ return flux_density.to(uu.mJy).value
179
+ else:
180
+ time_obs = time
181
+ lambda_observer_frame = kwargs.get('lambda_array', np.geomspace(100, 60000, 100))
182
+ time_temp = np.geomspace(0.1, 3000, 300) # in days
183
+ time_observer_frame = time_temp * (1. + redshift)
184
+ frequency, time = calc_kcorrected_properties(frequency=lambda_to_nu(lambda_observer_frame),
185
+ redshift=redshift, time=time_observer_frame)
186
+ lbol = fallback_lbol(time=time, logl1=logl1, tr=tr)
187
+ photo = kwargs['photosphere'](time=time, luminosity=lbol, **kwargs)
188
+ sed_1 = kwargs['sed'](temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
189
+ frequency=frequency[:,None], luminosity_distance=dl)
190
+ fmjy = sed_1.flux_density.T
191
+ spectra = fmjy.to(uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
192
+ equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom))
193
+ if kwargs['output_format'] == 'spectra':
194
+ return namedtuple('output', ['time', 'lambdas', 'spectra'])(time=time_observer_frame,
195
+ lambdas=lambda_observer_frame,
196
+ spectra=spectra)
197
+ else:
198
+ return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
199
+ spectra=spectra, lambda_array=lambda_observer_frame,
200
+ **kwargs)
201
+
144
202
  @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2018ApJS..236....6G/abstract')
145
203
  def sn_exponential_powerlaw(time, redshift, lbol_0, alpha_1, alpha_2, tpeak_d, **kwargs):
146
204
  """
@@ -305,7 +363,7 @@ def arnett(time, redshift, f_nickel, mej, **kwargs):
305
363
  spectra=spectra, lambda_array=lambda_observer_frame,
306
364
  **kwargs)
307
365
 
308
- @citation_wrapper('redback')
366
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/1982ApJ...253..785A/abstract')
309
367
  def shock_cooling_and_arnett(time, redshift, log10_mass, log10_radius, log10_energy,
310
368
  f_nickel, mej, **kwargs):
311
369
  """
@@ -1355,7 +1413,7 @@ def general_magnetar_slsn(time, redshift, l0, tsd, nn, ** kwargs):
1355
1413
  spectra=spectra, lambda_array=lambda_observer_frame,
1356
1414
  **kwargs)
1357
1415
 
1358
- @citation_wrapper('Omand and Sarin (2023)')
1416
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2024MNRAS.527.6455O/abstract')
1359
1417
  def general_magnetar_driven_supernova_bolometric(time, mej, E_sn, kappa, l0, tau_sd, nn, kappa_gamma, **kwargs):
1360
1418
  """
1361
1419
  :param time: time in observer frame in days
@@ -1415,7 +1473,7 @@ def general_magnetar_driven_supernova_bolometric(time, mej, E_sn, kappa, l0, tau
1415
1473
  else:
1416
1474
  return lbol
1417
1475
 
1418
- @citation_wrapper('Omand and Sarin (2023)')
1476
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2024MNRAS.527.6455O/abstract')
1419
1477
  def general_magnetar_driven_supernova(time, redshift, mej, E_sn, kappa, l0, tau_sd, nn, kappa_gamma, **kwargs):
1420
1478
  """
1421
1479
  :param time: time in observer frame in days
@@ -1529,4 +1587,100 @@ def general_magnetar_driven_supernova(time, redshift, mej, E_sn, kappa, l0, tau_
1529
1587
  else:
1530
1588
  return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame/day_to_s,
1531
1589
  spectra=spectra, lambda_array=lambda_observer_frame,
1532
- **kwargs)
1590
+ **kwargs)
1591
+
1592
+
1593
+
1594
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022ApJ...933..238M/abstract, https://ui.adsabs.harvard.edu/abs/1982ApJ...253..785A/abstract')
1595
+ def csm_shock_and_arnett_bolometric(time, mej, f_nickel, csm_mass, v_min, beta, shell_radius,
1596
+ shell_width_ratio, kappa, **kwargs):
1597
+ """
1598
+ Assumes CSM interaction for a shell-like CSM with a hard outer boundary and arnett model for radioactive decay
1599
+
1600
+ :param time: time in days in source frame
1601
+ :param mej: ejecta mass in solar masses
1602
+ :param f_nickel: fraction of nickel mass
1603
+ :param csm_mass: csm mass in solar masses
1604
+ :param v_min: ejecta velocity in km/s
1605
+ :param beta: velocity ratio in c (beta < 1)
1606
+ :param shell_radius: radius of shell in 10^14 cm
1607
+ :param kappa: opacity
1608
+ :param shell_width_ratio: shell width ratio (deltaR/R0)
1609
+ :param kwargs: kappa_gamma, temperature_floor, and any kwarg to
1610
+ change any other input physics/parameters from default.
1611
+ :return: bolometric luminosity in erg/s
1612
+ """
1613
+ from redback.transient_models.shock_powered_models import csm_shock_breakout_bolometric
1614
+ nickel_lbol = arnett_bolometric(time=time, f_nickel=f_nickel,
1615
+ mej=mej, interaction_process=ip.Diffusion, kappa=kappa, vej=v_min, **kwargs)
1616
+ sbo_output = csm_shock_breakout_bolometric(time=time, v_min=v_min, beta=beta,
1617
+ kappa=kappa, csm_mass=csm_mass, shell_radius=shell_radius,
1618
+ shell_width_ratio=shell_width_ratio, **kwargs)
1619
+ lbol = nickel_lbol + sbo_output
1620
+ return lbol
1621
+
1622
+
1623
+ @citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022ApJ...933..238M/abstract, https://ui.adsabs.harvard.edu/abs/1982ApJ...253..785A/abstract')
1624
+ def csm_shock_and_arnett(time, redshift, mej, f_nickel, csm_mass, v_min, beta, shell_radius,
1625
+ shell_width_ratio, kappa, **kwargs):
1626
+ """
1627
+ Assumes CSM interaction for a shell-like CSM with a hard outer boundary and arnett model for radioactive decay
1628
+
1629
+ :param time: time in days in observer frame
1630
+ :param redshift: source redshift
1631
+ :param mej: ejecta mass in solar masses
1632
+ :param f_nickel: fraction of nickel mass
1633
+ :param csm_mass: csm mass in solar masses
1634
+ :param v_min: ejecta velocity in km/s
1635
+ :param beta: velocity ratio in c (beta < 1)
1636
+ :param shell_radius: radius of shell in 10^14 cm
1637
+ :param kappa: opacity
1638
+ :param shell_width_ratio: shell width ratio (deltaR/R0)
1639
+ :param kwargs: kappa_gamma, temperature_floor, and any kwarg to
1640
+ change any other input physics/parameters from default.
1641
+ :param frequency: Required if output_format is 'flux_density'.
1642
+ frequency to calculate - Must be same length as time array or a single number).
1643
+ :param bands: Required if output_format is 'magnitude' or 'flux'.
1644
+ :param output_format: 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
1645
+ :param lambda_array: Optional argument to set your desired wavelength array (in Angstroms) to evaluate the SED on.
1646
+ :param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
1647
+ :return: set by output format - 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
1648
+ """
1649
+ cosmology = kwargs.get('cosmology', cosmo)
1650
+ dl = cosmology.luminosity_distance(redshift).cgs.value
1651
+
1652
+ if kwargs['output_format'] == 'flux_density':
1653
+ frequency = kwargs['frequency']
1654
+ frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
1655
+ lbol = csm_shock_and_arnett_bolometric(time=time, mej=mej, f_nickel=f_nickel, csm_mass=csm_mass,
1656
+ v_min=v_min, beta=beta, shell_radius=shell_radius,
1657
+ shell_width_ratio=shell_width_ratio, kappa=kappa, **kwargs)
1658
+ photo = photosphere.TemperatureFloor(time=time, luminosity=lbol, vej=v_min, **kwargs)
1659
+ sed_1 = sed.Blackbody(temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
1660
+ frequency=frequency, luminosity_distance=dl)
1661
+ flux_density = sed_1.flux_density
1662
+ return flux_density.to(uu.mJy).value
1663
+ else:
1664
+ time_obs = time
1665
+ lambda_observer_frame = kwargs.get('lambda_array', np.geomspace(100, 60000, 100))
1666
+ time_temp = np.geomspace(0.1, 3000, 300) # in days
1667
+ time_observer_frame = time_temp * (1. + redshift)
1668
+ frequency, time = calc_kcorrected_properties(frequency=lambda_to_nu(lambda_observer_frame),
1669
+ redshift=redshift, time=time_observer_frame)
1670
+ lbol = csm_shock_and_arnett_bolometric(time=time, mej=mej, f_nickel=f_nickel, csm_mass=csm_mass,
1671
+ v_min=v_min, beta=beta, shell_radius=shell_radius,
1672
+ shell_width_ratio=shell_width_ratio, kappa=kappa, **kwargs)
1673
+ photo = photosphere.TemperatureFloor(time=time, luminosity=lbol, vej=v_min, **kwargs)
1674
+ sed_1 = sed.Blackbody(temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
1675
+ frequency=frequency[:, None], luminosity_distance=dl)
1676
+ fmjy = sed_1.flux_density.T
1677
+ spectra = fmjy.to(uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
1678
+ equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom))
1679
+ if kwargs['output_format'] == 'spectra':
1680
+ return namedtuple('output', ['time', 'lambdas', 'spectra'])(time=time_observer_frame,
1681
+ lambdas=lambda_observer_frame,
1682
+ spectra=spectra)
1683
+ else:
1684
+ return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
1685
+ spectra=spectra, lambda_array=lambda_observer_frame,
1686
+ **kwargs)