redback 1.1__py3-none-any.whl → 1.12.1__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/filters.py +57 -45
- redback/likelihoods.py +274 -6
- redback/model_library.py +2 -2
- redback/plotting.py +5 -3
- redback/priors/blackbody_spectrum_at_z.prior +3 -0
- redback/priors/bpl_cooling_envelope.prior +9 -0
- redback/priors/gaussianrise_cooling_envelope.prior +1 -5
- redback/priors/gaussianrise_cooling_envelope_bolometric.prior +1 -5
- redback/priors/powerlaw_plus_blackbody.prior +12 -0
- redback/priors/powerlaw_plus_blackbody_spectrum_at_z.prior +13 -0
- redback/priors/salt2.prior +6 -0
- redback/priors/shock_cooling_and_arnett_bolometric.prior +11 -0
- redback/priors/smooth_exponential_powerlaw_cooling_envelope_bolometric.prior +9 -0
- redback/priors/sn_nickel_fallback.prior +9 -0
- redback/priors/wr_bh_merger.prior +10 -0
- redback/priors/wr_bh_merger_bolometric.prior +8 -0
- redback/priors.py +14 -3
- redback/sed.py +185 -41
- redback/simulate_transients.py +13 -3
- redback/tables/filters.csv +260 -258
- redback/tables/qdot_rosswogkorobkin24.npz +0 -0
- redback/transient_models/afterglow_models.py +32 -16
- redback/transient_models/combined_models.py +16 -11
- redback/transient_models/extinction_models.py +310 -84
- redback/transient_models/gaussianprocess_models.py +1 -12
- redback/transient_models/kilonova_models.py +3 -3
- redback/transient_models/phase_models.py +97 -43
- redback/transient_models/phenomenological_models.py +172 -0
- redback/transient_models/spectral_models.py +101 -0
- redback/transient_models/stellar_interaction_models.py +254 -0
- redback/transient_models/supernova_models.py +349 -62
- redback/transient_models/tde_models.py +193 -54
- redback/utils.py +34 -7
- {redback-1.1.dist-info → redback-1.12.1.dist-info}/METADATA +7 -4
- {redback-1.1.dist-info → redback-1.12.1.dist-info}/RECORD +39 -28
- {redback-1.1.dist-info → redback-1.12.1.dist-info}/WHEEL +1 -1
- redback/tables/qdot_rosswogkorobkin24.pck +0 -0
- {redback-1.1.dist-info → redback-1.12.1.dist-info}/licenses/LICENCE.md +0 -0
- {redback-1.1.dist-info → redback-1.12.1.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ import pandas as pd
|
|
|
3
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
|
-
from redback.transient_models.shock_powered_models import
|
|
6
|
+
from redback.transient_models.shock_powered_models import _shocked_cocoon, _csm_shock_breakout
|
|
7
7
|
import redback.interaction_processes as ip
|
|
8
8
|
import redback.sed as sed
|
|
9
9
|
import redback.photosphere as photosphere
|
|
@@ -13,7 +13,7 @@ from redback.constants import day_to_s, solar_mass, km_cgs, au_cgs, speed_of_lig
|
|
|
13
13
|
from inspect import isfunction
|
|
14
14
|
import astropy.units as uu
|
|
15
15
|
from collections import namedtuple
|
|
16
|
-
from scipy.interpolate import interp1d
|
|
16
|
+
from scipy.interpolate import interp1d, RegularGridInterpolator
|
|
17
17
|
|
|
18
18
|
homologous_expansion_models = ['exponential_powerlaw_bolometric', 'arnett_bolometric',
|
|
19
19
|
'basic_magnetar_powered_bolometric','slsn_bolometric',
|
|
@@ -115,6 +115,36 @@ def sncosmo_models(time, redshift, model_kwargs=None, **kwargs):
|
|
|
115
115
|
elif kwargs['output_format'] == 'sncosmo_source':
|
|
116
116
|
return model
|
|
117
117
|
|
|
118
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2007A%26A...466...11G/abstract, sncosmo')
|
|
119
|
+
def salt2(time, redshift, x0, x1, c, peak_time, **kwargs):
|
|
120
|
+
"""
|
|
121
|
+
A wrapper to the salt2 model in sncosmo
|
|
122
|
+
|
|
123
|
+
:param time: time in days in observer frame (in mjd days)
|
|
124
|
+
:param redshift: redshift
|
|
125
|
+
:param x0: x0
|
|
126
|
+
:param x1: x1
|
|
127
|
+
:param c: c
|
|
128
|
+
:param peak_time: peak time in mjd
|
|
129
|
+
:param kwargs: Additional keyword arguments
|
|
130
|
+
:param cosmology: astropy cosmology object by default set to Planck18
|
|
131
|
+
:param mw_extinction: Boolean for whether there is MW extinction or not. Default True
|
|
132
|
+
:param host_extinction: Boolean for whether there is host extinction or not. Default True
|
|
133
|
+
if used adds an extra parameter ebv which must also be in kwargs; host galaxy E(B-V). Set to 0.1 by default
|
|
134
|
+
:param use_set_peak_magnitude: Boolean for whether to set the peak magnitude or not. Default False,
|
|
135
|
+
if True the following keyword arguments also apply. Else the brightness is set by the model_kwargs.
|
|
136
|
+
:param peak_abs_mag: SNe peak absolute magnitude default set to -19
|
|
137
|
+
:param peak_abs_mag_band: Band corresponding to the peak abs mag limit, default to standard::b. Must be in SNCosmo
|
|
138
|
+
:param magnitude_system: Mag system; default ab
|
|
139
|
+
:param output_format: 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
|
|
140
|
+
:return: set by output format - 'flux_density', 'magnitude', 'flux', 'sncosmo_source'
|
|
141
|
+
"""
|
|
142
|
+
kwargs['sncosmo_model'] = 'salt2'
|
|
143
|
+
kwargs['peak_time'] = peak_time
|
|
144
|
+
model_kwargs = {'x0':x0, 'x1':x1, 'c':c}
|
|
145
|
+
out = sncosmo_models(time=time, redshift=redshift, model_kwargs=model_kwargs, **kwargs)
|
|
146
|
+
return out
|
|
147
|
+
|
|
118
148
|
@citation_wrapper('redback')
|
|
119
149
|
def exponential_powerlaw_bolometric(time, lbol_0, alpha_1, alpha_2, tpeak_d, **kwargs):
|
|
120
150
|
"""
|
|
@@ -198,6 +228,66 @@ def sn_fallback(time, redshift, logl1, tr, **kwargs):
|
|
|
198
228
|
return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
|
|
199
229
|
spectra=spectra, lambda_array=lambda_observer_frame,
|
|
200
230
|
**kwargs)
|
|
231
|
+
|
|
232
|
+
def sn_nickel_fallback(time, redshift, mej, f_nickel, logl1, tr, **kwargs):
|
|
233
|
+
"""
|
|
234
|
+
:param time: observer frame time in days
|
|
235
|
+
:param redshift: source redshift
|
|
236
|
+
:param mej: total ejecta mass in solar masses
|
|
237
|
+
:param f_nickel: fraction of nickel mass
|
|
238
|
+
:param logl1: bolometric luminosity scale in log10 (cgs)
|
|
239
|
+
:param tr: transition time for luminosity
|
|
240
|
+
:param kwargs: Must be all the kwargs required by the specific interaction_process, photosphere, sed methods used
|
|
241
|
+
e.g., for Diffusion and TemperatureFloor: kappa, kappa_gamma, mej (solar masses), vej (km/s), floor temperature
|
|
242
|
+
:param interaction_process: Default is Diffusion.
|
|
243
|
+
Can also be None in which case the output is just the raw engine luminosity, or another interaction process.
|
|
244
|
+
:param photosphere: Default is TemperatureFloor.
|
|
245
|
+
kwargs must vej or relevant parameters if using different photosphere model
|
|
246
|
+
:param sed: Default is blackbody.
|
|
247
|
+
:param frequency: Required if output_format is ‘flux_density’.
|
|
248
|
+
frequency to calculate - Must be same length as time array or a single number).
|
|
249
|
+
:param bands: Required if output_format is ‘magnitude’ or ‘flux’.
|
|
250
|
+
:param output_format: ‘flux_density’, ‘magnitude’, ‘spectra’, ‘flux’, ‘sncosmo_source’
|
|
251
|
+
:param lambda_array: Optional argument to set your desired wavelength array (in Angstroms) to evaluate the SED on.
|
|
252
|
+
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
253
|
+
:return: set by output format - ‘flux_density’, ‘magnitude’, ‘spectra’, ‘flux’, ‘sncosmo_source’
|
|
254
|
+
"""
|
|
255
|
+
kwargs["interaction_process"] = kwargs.get("interaction_process", ip.Diffusion)
|
|
256
|
+
kwargs["photosphere"] = kwargs.get("photosphere", photosphere.TemperatureFloor)
|
|
257
|
+
kwargs["sed"] = kwargs.get("sed", sed.Blackbody)
|
|
258
|
+
cosmology = kwargs.get("cosmology", cosmo)
|
|
259
|
+
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
260
|
+
if kwargs['output_format'] == 'flux_density':
|
|
261
|
+
frequency = kwargs['frequency']
|
|
262
|
+
frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
|
|
263
|
+
lbol = fallback_lbol(time=time, logl1=logl1, tr=tr) + _nickelcobalt_engine(time=time, f_nickel=f_nickel, mej=mej)
|
|
264
|
+
photo = kwargs['photosphere'](time=time, luminosity=lbol, **kwargs)
|
|
265
|
+
sed_1 = kwargs['sed'](temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
|
|
266
|
+
frequency=frequency, luminosity_distance=dl)
|
|
267
|
+
flux_density = sed_1.flux_density
|
|
268
|
+
return flux_density.to(uu.mJy).value
|
|
269
|
+
else:
|
|
270
|
+
time_obs = time
|
|
271
|
+
lambda_observer_frame = kwargs.get('lambda_array', np.geomspace(100, 60000, 100))
|
|
272
|
+
time_temp = np.geomspace(0.1, 3000, 300) # in days
|
|
273
|
+
time_observer_frame = time_temp * (1. + redshift)
|
|
274
|
+
frequency, time = calc_kcorrected_properties(frequency=lambda_to_nu(lambda_observer_frame),
|
|
275
|
+
redshift=redshift, time=time_observer_frame)
|
|
276
|
+
lbol = fallback_lbol(time=time, logl1=logl1, tr=tr) + _nickelcobalt_engine(time=time, f_nickel=f_nickel, mej=mej)
|
|
277
|
+
photo = kwargs['photosphere'](time=time, luminosity=lbol, **kwargs)
|
|
278
|
+
sed_1 = kwargs['sed'](temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
|
|
279
|
+
frequency=frequency[:,None], luminosity_distance=dl)
|
|
280
|
+
fmjy = sed_1.flux_density.T
|
|
281
|
+
spectra = fmjy.to(uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
|
|
282
|
+
equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom))
|
|
283
|
+
if kwargs['output_format'] == 'spectra':
|
|
284
|
+
return namedtuple('output', ['time', 'lambdas', 'spectra'])(time=time_observer_frame,
|
|
285
|
+
lambdas=lambda_observer_frame,
|
|
286
|
+
spectra=spectra)
|
|
287
|
+
else:
|
|
288
|
+
return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
|
|
289
|
+
spectra=spectra, lambda_array=lambda_observer_frame,
|
|
290
|
+
**kwargs)
|
|
201
291
|
|
|
202
292
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2018ApJS..236....6G/abstract')
|
|
203
293
|
def sn_exponential_powerlaw(time, redshift, lbol_0, alpha_1, alpha_2, tpeak_d, **kwargs):
|
|
@@ -363,10 +453,40 @@ def arnett(time, redshift, f_nickel, mej, **kwargs):
|
|
|
363
453
|
spectra=spectra, lambda_array=lambda_observer_frame,
|
|
364
454
|
**kwargs)
|
|
365
455
|
|
|
456
|
+
def shock_cooling_and_arnett_bolometric(time, log10_mass, log10_radius, log10_energy,
|
|
457
|
+
f_nickel, mej, vej, kappa, kappa_gamma, temperature_floor, **kwargs):
|
|
458
|
+
"""
|
|
459
|
+
Bolometric luminosity of shock cooling and arnett model
|
|
460
|
+
|
|
461
|
+
:param time: time in days in source frame
|
|
462
|
+
:param log10_mass: log10 mass of extended material in solar masses
|
|
463
|
+
:param log10_radius: log10 radius of extended material in cm
|
|
464
|
+
:param log10_energy: log10 energy of extended material in ergs
|
|
465
|
+
:param f_nickel: fraction of nickel mass
|
|
466
|
+
:param mej: total ejecta mass in solar masses
|
|
467
|
+
:param vej: velocity of ejecta in km/s
|
|
468
|
+
:param kappa: opacity in cm^2/g
|
|
469
|
+
:param kappa_gamma: gamma-ray opacity in cm^2/g
|
|
470
|
+
:param temperature_floor: temperature floor in K
|
|
471
|
+
:param kwargs: Additional keyword arguments
|
|
472
|
+
:param nn: density power law slope
|
|
473
|
+
:param delta: inner density power law slope
|
|
474
|
+
:return: bolometric luminosity in erg/s
|
|
475
|
+
"""
|
|
476
|
+
from redback.transient_models.shock_powered_models import shock_cooling_bolometric
|
|
477
|
+
lbol_1 = shock_cooling_bolometric(time=time * day_to_s, log10_mass=log10_mass, log10_radius=log10_radius,
|
|
478
|
+
log10_energy=log10_energy, **kwargs)
|
|
479
|
+
lbol_2 = arnett_bolometric(time=time, f_nickel=f_nickel, mej=mej, vej=vej, kappa=kappa,
|
|
480
|
+
kappa_gamma=kappa_gamma, temperature_floor=temperature_floor, **kwargs)
|
|
481
|
+
return lbol_1 + lbol_2
|
|
482
|
+
|
|
483
|
+
|
|
366
484
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/1982ApJ...253..785A/abstract, Piro+2021')
|
|
367
485
|
def shock_cooling_and_arnett(time, redshift, log10_mass, log10_radius, log10_energy,
|
|
368
|
-
f_nickel, mej, **kwargs):
|
|
486
|
+
f_nickel, mej, vej, kappa, kappa_gamma, temperature_floor, **kwargs):
|
|
369
487
|
"""
|
|
488
|
+
Photometric light curve of shock cooling and arnett model
|
|
489
|
+
|
|
370
490
|
:param time: time in days
|
|
371
491
|
:param redshift: source redshift
|
|
372
492
|
:param log10_mass: log10 mass of extended material in solar masses
|
|
@@ -374,12 +494,13 @@ def shock_cooling_and_arnett(time, redshift, log10_mass, log10_radius, log10_ene
|
|
|
374
494
|
:param log10_energy: log10 energy of extended material in ergs
|
|
375
495
|
:param f_nickel: fraction of nickel mass
|
|
376
496
|
:param mej: total ejecta mass in solar masses
|
|
377
|
-
:param
|
|
378
|
-
|
|
497
|
+
:param vej: velocity of ejecta in km/s
|
|
498
|
+
:param kappa: opacity in cm^2/g
|
|
499
|
+
:param kappa_gamma: gamma-ray opacity in cm^2/g
|
|
500
|
+
:param temperature_floor: temperature floor in K
|
|
501
|
+
:param kwargs: Additional keyword arguments
|
|
379
502
|
:param nn: density power law slope
|
|
380
503
|
:param delta: inner density power law slope
|
|
381
|
-
:param interaction_process: Default is Diffusion.
|
|
382
|
-
Can also be None in which case the output is just the raw engine luminosity, or another interaction process.
|
|
383
504
|
:param photosphere: Default is TemperatureFloor.
|
|
384
505
|
kwargs must have vej or relevant parameters if using different photosphere model
|
|
385
506
|
:param sed: Default is blackbody.
|
|
@@ -391,33 +512,19 @@ def shock_cooling_and_arnett(time, redshift, log10_mass, log10_radius, log10_ene
|
|
|
391
512
|
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
392
513
|
:return: set by output format - 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
|
|
393
514
|
"""
|
|
394
|
-
kwargs['interaction_process'] = kwargs.get("interaction_process", ip.Diffusion)
|
|
395
515
|
kwargs['photosphere'] = kwargs.get("photosphere", photosphere.TemperatureFloor)
|
|
396
516
|
kwargs['sed'] = kwargs.get("sed", sed.Blackbody)
|
|
397
517
|
cosmology = kwargs.get('cosmology', cosmo)
|
|
398
518
|
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
399
|
-
mass = 10 ** log10_mass
|
|
400
|
-
radius = 10 ** log10_radius
|
|
401
|
-
energy = 10 ** log10_energy
|
|
402
519
|
|
|
403
520
|
if kwargs['output_format'] == 'flux_density':
|
|
404
521
|
frequency = kwargs['frequency']
|
|
405
522
|
frequency, time = calc_kcorrected_properties(frequency=frequency, redshift=redshift, time=time)
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
if kwargs['interaction_process'] is not None:
|
|
412
|
-
dense_resolution = kwargs.get("dense_resolution", 300)
|
|
413
|
-
dense_times = np.linspace(0.01, time[-1]+100, dense_resolution)
|
|
414
|
-
dense_lbols = _nickelcobalt_engine(time=dense_times, f_nickel=f_nickel, mej=mej)
|
|
415
|
-
shock_cooling = _shock_cooling(dense_times * day_to_s, mass=mass, radius=radius, energy=energy, **kwargs).lbol
|
|
416
|
-
dense_lbols += shock_cooling
|
|
417
|
-
interaction_class = kwargs['interaction_process'](time=time, dense_times=dense_times, luminosity=dense_lbols,
|
|
418
|
-
mej=mej, **kwargs)
|
|
419
|
-
lbol = interaction_class.new_luminosity
|
|
420
|
-
photo = kwargs['photosphere'](time=time, luminosity=lbol, **kwargs)
|
|
523
|
+
lbol = shock_cooling_and_arnett_bolometric(time, log10_mass=log10_mass, log10_radius=log10_radius,
|
|
524
|
+
log10_energy=log10_energy, f_nickel=f_nickel,
|
|
525
|
+
mej=mej, vej=vej, kappa=kappa, kappa_gamma=kappa_gamma,
|
|
526
|
+
temperature_floor=temperature_floor, **kwargs)
|
|
527
|
+
photo = kwargs['photosphere'](time=time, luminosity=lbol, vej=vej, temperature_floor=temperature_floor, **kwargs)
|
|
421
528
|
|
|
422
529
|
sed_1 = kwargs['sed'](temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
|
|
423
530
|
frequency=frequency, luminosity_distance=dl)
|
|
@@ -430,10 +537,11 @@ def shock_cooling_and_arnett(time, redshift, log10_mass, log10_radius, log10_ene
|
|
|
430
537
|
time_observer_frame = time_temp * (1. + redshift)
|
|
431
538
|
frequency, time = calc_kcorrected_properties(frequency=lambda_to_nu(lambda_observer_frame),
|
|
432
539
|
redshift=redshift, time=time_observer_frame)
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
540
|
+
lbol = shock_cooling_and_arnett_bolometric(time, log10_mass=log10_mass, log10_radius=log10_radius,
|
|
541
|
+
log10_energy=log10_energy, f_nickel=f_nickel,
|
|
542
|
+
mej=mej, vej=vej, kappa=kappa, kappa_gamma=kappa_gamma,
|
|
543
|
+
temperature_floor=temperature_floor, **kwargs)
|
|
544
|
+
photo = kwargs['photosphere'](time=time, luminosity=lbol, vej=vej, temperature_floor=temperature_floor, **kwargs)
|
|
437
545
|
sed_1 = kwargs['sed'](temperature=photo.photosphere_temperature, r_photosphere=photo.r_photosphere,
|
|
438
546
|
frequency=frequency[:,None], luminosity_distance=dl)
|
|
439
547
|
fmjy = sed_1.flux_density.T
|
|
@@ -785,13 +893,12 @@ def slsn(time, redshift, p0, bp, mass_ns, theta_pb,**kwargs):
|
|
|
785
893
|
lbol = slsn_bolometric(time=time, p0=p0, bp=bp, mass_ns=mass_ns, theta_pb=theta_pb, **kwargs)
|
|
786
894
|
photo = kwargs['photosphere'](time=time, luminosity=lbol, **kwargs)
|
|
787
895
|
full_sed = np.zeros((len(time), len(frequency)))
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
full_sed[:, ii] = ss.flux_density.to(uu.mJy).value
|
|
896
|
+
ss = kwargs['sed'](time=time, temperature=photo.photosphere_temperature,
|
|
897
|
+
r_photosphere=photo.r_photosphere, frequency=frequency[:, None],
|
|
898
|
+
luminosity_distance=dl, cutoff_wavelength=cutoff_wavelength, luminosity=lbol)
|
|
899
|
+
full_sed = ss.flux_density.to(uu.mJy).value.T
|
|
793
900
|
spectra = (full_sed * uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
|
|
794
|
-
|
|
901
|
+
equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom))
|
|
795
902
|
if kwargs['output_format'] == 'spectra':
|
|
796
903
|
return namedtuple('output', ['time', 'lambdas', 'spectra'])(time=time_observer_frame,
|
|
797
904
|
lambdas=lambda_observer_frame,
|
|
@@ -1375,17 +1482,17 @@ def type_1a(time, redshift, f_nickel, mej, **kwargs):
|
|
|
1375
1482
|
:param line_duration: line duration, default is 25
|
|
1376
1483
|
:param line_amplitude: line amplitude, default is 0.3
|
|
1377
1484
|
:param frequency: Required if output_format is 'flux_density'.
|
|
1378
|
-
frequency to calculate - Must be same length as time array or a single number
|
|
1485
|
+
frequency to calculate - Must be same length as time array or a single number.
|
|
1379
1486
|
:param bands: Required if output_format is 'magnitude' or 'flux'.
|
|
1380
1487
|
:param output_format: 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
|
|
1381
1488
|
:param lambda_array: Optional argument to set your desired wavelength array (in Angstroms) to evaluate the SED on.
|
|
1382
|
-
:param cosmology:
|
|
1489
|
+
:param cosmology: cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be an astropy.cosmology object.
|
|
1383
1490
|
:return: set by output format - 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
|
|
1384
1491
|
"""
|
|
1385
1492
|
cosmology = kwargs.get('cosmology', cosmo)
|
|
1386
1493
|
dl = cosmology.luminosity_distance(redshift).cgs.value
|
|
1387
1494
|
cutoff_wavelength = kwargs.get('cutoff_wavelength', 3000)
|
|
1388
|
-
line_wavelength = kwargs.get('line_wavelength',7.5e3)
|
|
1495
|
+
line_wavelength = kwargs.get('line_wavelength', 7.5e3)
|
|
1389
1496
|
line_width = kwargs.get('line_width', 500)
|
|
1390
1497
|
line_time = kwargs.get('line_time', 50)
|
|
1391
1498
|
line_duration = kwargs.get('line_duration', 25)
|
|
@@ -1399,13 +1506,13 @@ def type_1a(time, redshift, f_nickel, mej, **kwargs):
|
|
|
1399
1506
|
|
|
1400
1507
|
photo = photosphere.TemperatureFloor(time=time, luminosity=lbol, **kwargs)
|
|
1401
1508
|
sed_1 = sed.CutoffBlackbody(time=time, luminosity=lbol, temperature=photo.photosphere_temperature,
|
|
1402
|
-
r_photosphere=photo.r_photosphere,frequency=frequency, luminosity_distance=dl,
|
|
1509
|
+
r_photosphere=photo.r_photosphere, frequency=frequency, luminosity_distance=dl,
|
|
1403
1510
|
cutoff_wavelength=cutoff_wavelength)
|
|
1404
1511
|
sed_2 = sed.Line(time=time, luminosity=lbol, frequency=frequency, luminosity_distance=dl,
|
|
1405
1512
|
sed=sed_1, line_wavelength=line_wavelength,
|
|
1406
1513
|
line_width=line_width, line_time=line_time,
|
|
1407
1514
|
line_duration=line_duration, line_amplitude=line_amplitude)
|
|
1408
|
-
flux_density = sed_2.flux_density
|
|
1515
|
+
flux_density = sed_2.flux_density.flatten()
|
|
1409
1516
|
return flux_density.to(uu.mJy).value
|
|
1410
1517
|
else:
|
|
1411
1518
|
time_obs = time
|
|
@@ -1417,18 +1524,23 @@ def type_1a(time, redshift, f_nickel, mej, **kwargs):
|
|
|
1417
1524
|
lbol = arnett_bolometric(time=time, f_nickel=f_nickel, mej=mej,
|
|
1418
1525
|
interaction_process=ip.Diffusion, **kwargs)
|
|
1419
1526
|
photo = photosphere.TemperatureFloor(time=time, luminosity=lbol, **kwargs)
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1527
|
+
# Here we construct the CutoffBlackbody SED with frequency reshaped to (n_freq, 1)
|
|
1528
|
+
ss = sed.CutoffBlackbody(time=time, temperature=photo.photosphere_temperature,
|
|
1529
|
+
r_photosphere=photo.r_photosphere, frequency=frequency[:, None],
|
|
1530
|
+
luminosity_distance=dl, cutoff_wavelength=cutoff_wavelength, luminosity=lbol)
|
|
1531
|
+
line_sed = sed.Line(time=time, luminosity=lbol, frequency=frequency[:, None],
|
|
1532
|
+
luminosity_distance=dl, sed=ss,
|
|
1533
|
+
line_wavelength=line_wavelength,
|
|
1534
|
+
line_width=line_width,
|
|
1535
|
+
line_time=line_time,
|
|
1536
|
+
line_duration=line_duration,
|
|
1537
|
+
line_amplitude=line_amplitude)
|
|
1538
|
+
full_sed = line_sed.flux_density.to(uu.mJy).value
|
|
1539
|
+
# The following line converts the full SED (in mJy) to erg/s/cm^2/Angstrom.
|
|
1430
1540
|
spectra = (full_sed * uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
|
|
1431
|
-
equivalencies=uu.spectral_density(
|
|
1541
|
+
equivalencies=uu.spectral_density(
|
|
1542
|
+
wav=(lambdas_observer_frame.reshape(-1, 1) * uu.Angstrom))).T
|
|
1543
|
+
print(spectra.shape)
|
|
1432
1544
|
if kwargs['output_format'] == 'spectra':
|
|
1433
1545
|
return namedtuple('output', ['time', 'lambdas', 'spectra'])(time=time_observer_frame,
|
|
1434
1546
|
lambdas=lambdas_observer_frame,
|
|
@@ -1439,6 +1551,7 @@ def type_1a(time, redshift, f_nickel, mej, **kwargs):
|
|
|
1439
1551
|
**kwargs)
|
|
1440
1552
|
|
|
1441
1553
|
|
|
1554
|
+
|
|
1442
1555
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2018ApJS..236....6G/abstract')
|
|
1443
1556
|
def type_1c(time, redshift, f_nickel, mej, pp, **kwargs):
|
|
1444
1557
|
"""
|
|
@@ -1588,7 +1701,7 @@ def general_magnetar_slsn(time, redshift, l0, tsd, nn, ** kwargs):
|
|
|
1588
1701
|
spectra=spectra, lambda_array=lambda_observer_frame,
|
|
1589
1702
|
**kwargs)
|
|
1590
1703
|
|
|
1591
|
-
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2024MNRAS.527.6455O/abstract')
|
|
1704
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022MNRAS.516.4949S/abstract, https://ui.adsabs.harvard.edu/abs/2024MNRAS.527.6455O/abstract')
|
|
1592
1705
|
def general_magnetar_driven_supernova_bolometric(time, mej, E_sn, kappa, l0, tau_sd, nn, kappa_gamma, **kwargs):
|
|
1593
1706
|
"""
|
|
1594
1707
|
:param time: time in observer frame in days
|
|
@@ -1627,8 +1740,6 @@ def general_magnetar_driven_supernova_bolometric(time, mej, E_sn, kappa, l0, tau
|
|
|
1627
1740
|
time = time * day_to_s
|
|
1628
1741
|
lbol = lbol_func(time)
|
|
1629
1742
|
v_ej = vej_func(time)
|
|
1630
|
-
erot_total = np.trapz(magnetar_luminosity, x=time_temp)
|
|
1631
|
-
erad_total = np.trapz(output.bolometric_luminosity, x=time_temp)
|
|
1632
1743
|
|
|
1633
1744
|
dynamics_output = namedtuple('dynamics_output', ['v_ej', 'tau', 'time', 'bolometric_luminosity', 'kinetic_energy', 'erad_total',
|
|
1634
1745
|
'thermalisation_efficiency', 'magnetar_luminosity', 'erot_total'])
|
|
@@ -1648,7 +1759,7 @@ def general_magnetar_driven_supernova_bolometric(time, mej, E_sn, kappa, l0, tau
|
|
|
1648
1759
|
else:
|
|
1649
1760
|
return lbol
|
|
1650
1761
|
|
|
1651
|
-
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2024MNRAS.527.6455O/abstract')
|
|
1762
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2022MNRAS.516.4949S/abstract, https://ui.adsabs.harvard.edu/abs/2024MNRAS.527.6455O/abstract')
|
|
1652
1763
|
def general_magnetar_driven_supernova(time, redshift, mej, E_sn, kappa, l0, tau_sd, nn, kappa_gamma, **kwargs):
|
|
1653
1764
|
"""
|
|
1654
1765
|
:param time: time in observer frame in days
|
|
@@ -1748,11 +1859,10 @@ def general_magnetar_driven_supernova(time, redshift, mej, E_sn, kappa, l0, tau_
|
|
|
1748
1859
|
return dynamics_output
|
|
1749
1860
|
else:
|
|
1750
1861
|
full_sed = np.zeros((len(time), len(frequency)))
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
full_sed[:, ii] = ss.flux_density.to(uu.mJy).value
|
|
1862
|
+
ss = kwargs['sed'](time=time_temp/day_to_s, temperature=photo.photosphere_temperature,
|
|
1863
|
+
r_photosphere=photo.r_photosphere, frequency=frequency[:, None],
|
|
1864
|
+
luminosity_distance=dl, cutoff_wavelength=cutoff_wavelength, luminosity=output.bolometric_luminosity)
|
|
1865
|
+
full_sed = ss.flux_density.to(uu.mJy).value.T
|
|
1756
1866
|
spectra = (full_sed * uu.mJy).to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
|
|
1757
1867
|
equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom))
|
|
1758
1868
|
if kwargs['output_format'] == 'spectra':
|
|
@@ -2009,4 +2119,181 @@ def shocked_cocoon_and_arnett(time, redshift, mej_c, vej_c, eta, tshock, shocked
|
|
|
2009
2119
|
else:
|
|
2010
2120
|
return sed.get_correct_output_format_from_spectra(time=time_obs, time_eval=time_observer_frame,
|
|
2011
2121
|
spectra=spectra, lambda_array=lambda_observer_frame,
|
|
2012
|
-
**kwargs)
|
|
2122
|
+
**kwargs)
|
|
2123
|
+
|
|
2124
|
+
@citation_wrapper("https://ui.adsabs.harvard.edu/abs/2025arXiv250602107S/abstract, https://ui.adsabs.harvard.edu/abs/2023PASJ...75..634M/abstract")
|
|
2125
|
+
def typeII_bolometric(time, progenitor, ni_mass, log10_mdot, beta, rcsm, esn, **kwargs):
|
|
2126
|
+
"""
|
|
2127
|
+
Bolometric luminosity for a Type II supernova based on Sarin et al. 2025 surrogate model
|
|
2128
|
+
to stella grid in Moriya et al. 2023
|
|
2129
|
+
|
|
2130
|
+
:param time: Time in days in source frame
|
|
2131
|
+
:param progenitor: in solar masses
|
|
2132
|
+
:param ni_mass: in solar masses
|
|
2133
|
+
:param log10_mdot: in solar masses per year
|
|
2134
|
+
:param beta: dimensionless
|
|
2135
|
+
:param rcsm: in 10^14 cm
|
|
2136
|
+
:param esn: in 10^51
|
|
2137
|
+
:param kwargs: None
|
|
2138
|
+
:return: bolometric luminosity in erg/s
|
|
2139
|
+
"""
|
|
2140
|
+
from redback_surrogates.supernovamodels import typeII_lbol
|
|
2141
|
+
tt, lbol = typeII_lbol(time=time, progenitor=progenitor, ni_mass=ni_mass,
|
|
2142
|
+
log10_mdot=log10_mdot, beta=beta, rcsm=rcsm, esn=esn, **kwargs)
|
|
2143
|
+
lbol_func = interp1d(tt, y=lbol, bounds_error=False, fill_value='extrapolate')
|
|
2144
|
+
return lbol_func(time)
|
|
2145
|
+
|
|
2146
|
+
@citation_wrapper("https://ui.adsabs.harvard.edu/abs/2025arXiv250602107S/abstract, https://ui.adsabs.harvard.edu/abs/2023PASJ...75..634M/abstract")
|
|
2147
|
+
def typeII_photosphere_properties(time, progenitor, ni_mass, log10_mdot, beta, rcsm, esn, **kwargs):
|
|
2148
|
+
"""
|
|
2149
|
+
Photosphere properties for a Type II supernova based on Sarin et al. 2025 surrogate model
|
|
2150
|
+
to stella grid in Moriya et al. 2023
|
|
2151
|
+
|
|
2152
|
+
:param time: Time in days in source frame
|
|
2153
|
+
:param progenitor: in solar masses
|
|
2154
|
+
:param ni_mass: in solar masses
|
|
2155
|
+
:param log10_mdot: in solar masses per year
|
|
2156
|
+
:param beta: dimensionless
|
|
2157
|
+
:param rcsm: in 10^14 cm
|
|
2158
|
+
:param esn: in 10^51
|
|
2159
|
+
:param kwargs: None
|
|
2160
|
+
:return: photosphere properties (temperature in K, radius in cm)
|
|
2161
|
+
"""
|
|
2162
|
+
from redback_surrogates.supernovamodels import typeII_photosphere
|
|
2163
|
+
tt, temp, rad = typeII_photosphere(time=time, progenitor=progenitor, ni_mass=ni_mass,
|
|
2164
|
+
log10_mdot=log10_mdot, beta=beta, rcsm=rcsm, esn=esn, **kwargs)
|
|
2165
|
+
temp_func = interp1d(tt, y=temp, bounds_error=False, fill_value='extrapolate')
|
|
2166
|
+
rad_func = interp1d(tt, y=rad, bounds_error=False, fill_value='extrapolate')
|
|
2167
|
+
return temp_func(time), rad_func(time)
|
|
2168
|
+
|
|
2169
|
+
@citation_wrapper("https://ui.adsabs.harvard.edu/abs/2025arXiv250602107S/abstract, https://ui.adsabs.harvard.edu/abs/2023PASJ...75..634M/abstract")
|
|
2170
|
+
def typeII_surrogate_sarin25(time, redshift, progenitor, ni_mass, log10_mdot, beta, rcsm, esn, **kwargs):
|
|
2171
|
+
"""
|
|
2172
|
+
Type II supernova model based on Sarin et al. 2025 surrogate model
|
|
2173
|
+
to stella grid in Moriya et al. 2023
|
|
2174
|
+
|
|
2175
|
+
:param time: Time in days in observer frame
|
|
2176
|
+
:param redshift: redshift
|
|
2177
|
+
:param progenitor: in solar masses
|
|
2178
|
+
:param ni_mass: in solar masses
|
|
2179
|
+
:param log10_mdot: in solar masses per year
|
|
2180
|
+
:param beta: dimensionless
|
|
2181
|
+
:param rcsm: in 10^14 cm
|
|
2182
|
+
:param esn: in 10^51
|
|
2183
|
+
:param kwargs: Additional parameters for the model, such as:
|
|
2184
|
+
:param frequency: Required if output_format is 'flux_density'.
|
|
2185
|
+
frequency to calculate - Must be same length as time array or a single number).
|
|
2186
|
+
:param bands: Required if output_format is 'magnitude' or 'flux'.
|
|
2187
|
+
:param output_format: 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
|
|
2188
|
+
:param lambda_array: Optional argument to set your desired wavelength array (in Angstroms) to evaluate the SED on.
|
|
2189
|
+
:param cosmology: Cosmology to use for luminosity distance calculation. Defaults to Planck18. Must be a astropy.cosmology object.
|
|
2190
|
+
:return: set by output format - 'flux_density', 'magnitude', 'spectra', 'flux', 'sncosmo_source'
|
|
2191
|
+
"""
|
|
2192
|
+
from redback_surrogates.supernovamodels import typeII_spectra
|
|
2193
|
+
cosmology = kwargs.get('cosmology', cosmo)
|
|
2194
|
+
dl = cosmology.luminosity_distance(redshift).cgs
|
|
2195
|
+
|
|
2196
|
+
# Get the rest-frame spectrum using typeII_spectra
|
|
2197
|
+
spectra_output = typeII_spectra(
|
|
2198
|
+
progenitor=progenitor,
|
|
2199
|
+
ni_mass=ni_mass,
|
|
2200
|
+
log10_mdot=log10_mdot,
|
|
2201
|
+
beta=beta,
|
|
2202
|
+
rcsm=rcsm,
|
|
2203
|
+
esn=esn,
|
|
2204
|
+
**kwargs
|
|
2205
|
+
)
|
|
2206
|
+
|
|
2207
|
+
# Extract components from the output
|
|
2208
|
+
rest_spectrum = spectra_output.spectrum # erg/s/Hz in rest frame
|
|
2209
|
+
standard_freqs = spectra_output.frequency.value # Angstrom in rest frame
|
|
2210
|
+
standard_times = spectra_output.time.value # days in rest frame
|
|
2211
|
+
|
|
2212
|
+
# Apply cosmological dimming
|
|
2213
|
+
observed_spectrum = rest_spectrum / (4 * np.pi * dl ** 2)
|
|
2214
|
+
|
|
2215
|
+
# Handle different output formats
|
|
2216
|
+
if kwargs.get('output_format') == 'flux_density':
|
|
2217
|
+
# Use redback's K-correction utilities
|
|
2218
|
+
frequency = kwargs['frequency']
|
|
2219
|
+
frequency, time = calc_kcorrected_properties(frequency=frequency, time=time, redshift=redshift)
|
|
2220
|
+
|
|
2221
|
+
# Convert wavelengths to frequencies for interpolation
|
|
2222
|
+
nu_array = lambda_to_nu(standard_freqs)
|
|
2223
|
+
|
|
2224
|
+
# Convert spectrum from erg/s/Hz to erg/s/cm²/Hz (already done above)
|
|
2225
|
+
# Convert to wavelength density for astropy conversion
|
|
2226
|
+
spectra_lambda = spectra_lambda.to(uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom)
|
|
2227
|
+
|
|
2228
|
+
# Convert to mJy using astropy
|
|
2229
|
+
fmjy = spectra_lambda.to(uu.mJy,
|
|
2230
|
+
equivalencies=uu.spectral_density(wav=standard_freqs * uu.Angstrom)).value
|
|
2231
|
+
|
|
2232
|
+
# Create interpolator
|
|
2233
|
+
flux_interpolator = RegularGridInterpolator(
|
|
2234
|
+
(standard_times, nu_array),
|
|
2235
|
+
fmjy,
|
|
2236
|
+
bounds_error=False,
|
|
2237
|
+
fill_value=0.0
|
|
2238
|
+
)
|
|
2239
|
+
|
|
2240
|
+
# Prepare points for interpolation
|
|
2241
|
+
if isinstance(frequency, (int, float)):
|
|
2242
|
+
frequency = np.ones_like(time) * frequency
|
|
2243
|
+
|
|
2244
|
+
# Create points for evaluation
|
|
2245
|
+
points = np.column_stack((time, frequency))
|
|
2246
|
+
|
|
2247
|
+
# Return interpolated flux
|
|
2248
|
+
return flux_interpolator(points)
|
|
2249
|
+
|
|
2250
|
+
else:
|
|
2251
|
+
# Create denser grid for output (in rest frame)
|
|
2252
|
+
new_rest_times = np.geomspace(np.min(standard_times), np.max(standard_times), 200)
|
|
2253
|
+
new_rest_freqs = np.geomspace(np.min(standard_freqs), np.max(standard_freqs), 200)
|
|
2254
|
+
|
|
2255
|
+
# Create interpolator for the spectrum in rest frame
|
|
2256
|
+
spectra_func = RegularGridInterpolator(
|
|
2257
|
+
(standard_times, standard_freqs),
|
|
2258
|
+
observed_spectrum.value,
|
|
2259
|
+
bounds_error=False,
|
|
2260
|
+
fill_value=0.0
|
|
2261
|
+
)
|
|
2262
|
+
|
|
2263
|
+
# Create meshgrid for new grid points
|
|
2264
|
+
tt_mesh, ff_mesh = np.meshgrid(new_rest_times, new_rest_freqs, indexing='ij')
|
|
2265
|
+
points_to_evaluate = np.column_stack((tt_mesh.ravel(), ff_mesh.ravel()))
|
|
2266
|
+
|
|
2267
|
+
# Interpolate spectrum onto new grid
|
|
2268
|
+
interpolated_values = spectra_func(points_to_evaluate)
|
|
2269
|
+
interpolated_spectrum = interpolated_values.reshape(tt_mesh.shape) * observed_spectrum.unit
|
|
2270
|
+
|
|
2271
|
+
# Convert times to observer frame
|
|
2272
|
+
time_observer_frame = new_rest_times * (1 + redshift)
|
|
2273
|
+
|
|
2274
|
+
# Convert wavelengths to observer frame
|
|
2275
|
+
lambda_observer_frame = new_rest_freqs * (1 + redshift)
|
|
2276
|
+
|
|
2277
|
+
# Convert spectrum units using astropy
|
|
2278
|
+
interpolated_spectrum = interpolated_spectrum.to(
|
|
2279
|
+
uu.erg / uu.cm ** 2 / uu.s / uu.Angstrom,
|
|
2280
|
+
equivalencies=uu.spectral_density(wav=lambda_observer_frame * uu.Angstrom)
|
|
2281
|
+
)
|
|
2282
|
+
|
|
2283
|
+
# Create output structure
|
|
2284
|
+
if kwargs.get('output_format') == 'spectra':
|
|
2285
|
+
return namedtuple('output', ['time', 'lambdas', 'spectra'])(
|
|
2286
|
+
time=time_observer_frame,
|
|
2287
|
+
lambdas=lambda_observer_frame,
|
|
2288
|
+
spectra=interpolated_spectrum
|
|
2289
|
+
)
|
|
2290
|
+
else:
|
|
2291
|
+
# Get correct output format using redback utility
|
|
2292
|
+
return sed.get_correct_output_format_from_spectra(
|
|
2293
|
+
time=time, # Original observer frame time for evaluation
|
|
2294
|
+
time_eval=time_observer_frame,
|
|
2295
|
+
spectra=interpolated_spectrum,
|
|
2296
|
+
lambda_array=lambda_observer_frame,
|
|
2297
|
+
time_spline_degree=1,
|
|
2298
|
+
**kwargs
|
|
2299
|
+
)
|