redback 1.0.0__py3-none-any.whl → 1.0.2__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 +4 -0
- redback/constraints.py +31 -25
- redback/ejecta_relations.py +8 -8
- redback/get_data/lasair.py +3 -4
- redback/get_data/swift.py +7 -7
- redback/interaction_processes.py +1 -4
- redback/likelihoods.py +207 -21
- redback/plotting.py +11 -11
- redback/priors/csm_interaction.prior +6 -7
- redback/priors/csm_nickel.prior +3 -3
- redback/priors/one_comp_kne_rosswog_heatingrate.prior +5 -0
- redback/priors/one_component_nsbh_ejecta_relation.prior +1 -1
- redback/priors/tde_analytical.prior +5 -5
- redback/priors/tde_analytical_bolometric.prior +6 -4
- redback/priors/tophat_from_emulator.prior +9 -0
- redback/priors/two_comp_kne_rosswog_heatingrate.prior +9 -0
- redback/priors/two_component_nsbh_ejecta_relation.prior +1 -1
- redback/priors/two_layer_stratified_kilonova.prior +1 -1
- redback/priors.py +11 -0
- redback/sed.py +194 -2
- redback/simulate_transients.py +61 -32
- redback/tables/filters.csv +15 -1
- redback/tables/ztf.tar.gz +0 -0
- redback/transient/afterglow.py +3 -2
- redback/transient/kilonova.py +1 -1
- redback/transient/supernova.py +1 -1
- redback/transient/tde.py +1 -1
- redback/transient/transient.py +2 -2
- redback/transient_models/afterglow_models.py +42 -0
- redback/transient_models/combined_models.py +47 -32
- redback/transient_models/extinction_models.py +12 -5
- redback/transient_models/kilonova_models.py +247 -14
- redback/transient_models/magnetar_driven_ejecta_models.py +2 -2
- redback/transient_models/phenomenological_models.py +13 -0
- redback/transient_models/supernova_models.py +50 -36
- redback/transient_models/tde_models.py +126 -1
- redback/utils.py +283 -6
- {redback-1.0.0.dist-info → redback-1.0.2.dist-info}/METADATA +7 -4
- {redback-1.0.0.dist-info → redback-1.0.2.dist-info}/RECORD +42 -40
- {redback-1.0.0.dist-info → redback-1.0.2.dist-info}/WHEEL +1 -1
- redback/tables/ztf_obslog.csv +0 -106649
- {redback-1.0.0.dist-info → redback-1.0.2.dist-info}/LICENCE.md +0 -0
- {redback-1.0.0.dist-info → redback-1.0.2.dist-info}/top_level.txt +0 -0
redback/sed.py
CHANGED
|
@@ -6,6 +6,193 @@ from sncosmo import TimeSeriesSource
|
|
|
6
6
|
from redback.constants import *
|
|
7
7
|
from redback.utils import nu_to_lambda, bandpass_magnitude_to_flux
|
|
8
8
|
|
|
9
|
+
def _bandflux_single_redback(model, band, time_or_phase):
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
Synthetic photometry of a model through a single bandpass
|
|
13
|
+
|
|
14
|
+
:param model: Source object
|
|
15
|
+
:param band: Bandpass
|
|
16
|
+
:param time_or_phase: Time or phase numpy array
|
|
17
|
+
:return: bandflux through the bandpass
|
|
18
|
+
"""
|
|
19
|
+
from sncosmo.utils import integration_grid
|
|
20
|
+
HC_ERG_AA = 1.9864458571489284e-08 # planck * speed_of_light in AA/s
|
|
21
|
+
MODEL_BANDFLUX_SPACING = 5.0 # Angstroms
|
|
22
|
+
|
|
23
|
+
if (band.minwave() < model.minwave() or band.maxwave() > model.maxwave()):
|
|
24
|
+
raise ValueError('bandpass {0!r:s} [{1:.6g}, .., {2:.6g}] '
|
|
25
|
+
'outside spectral range [{3:.6g}, .., {4:.6g}]'
|
|
26
|
+
.format(band.name, band.minwave(), band.maxwave(),
|
|
27
|
+
model.minwave(), model.maxwave()))
|
|
28
|
+
|
|
29
|
+
# Set up wavelength grid. Spacing (dwave) evenly divides the bandpass,
|
|
30
|
+
# closest to 5 angstroms without going over.
|
|
31
|
+
wave, dwave = integration_grid(band.minwave(), band.maxwave(),
|
|
32
|
+
MODEL_BANDFLUX_SPACING)
|
|
33
|
+
trans = band(wave)
|
|
34
|
+
f = model._flux(time_or_phase, wave)
|
|
35
|
+
f = np.abs(f)
|
|
36
|
+
return np.sum(wave * trans * f, axis=1) * dwave / HC_ERG_AA
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _bandflux_redback(model, band, time_or_phase, zp, zpsys):
|
|
40
|
+
"""
|
|
41
|
+
Support function for bandflux in Source and Model. Follows SNCOSMO
|
|
42
|
+
|
|
43
|
+
This is necessary to have outside because ``phase`` is used in Source
|
|
44
|
+
and ``time`` is used in Model, and we want the method signatures to
|
|
45
|
+
have the right variable name.
|
|
46
|
+
"""
|
|
47
|
+
from sncosmo.magsystems import get_magsystem
|
|
48
|
+
from sncosmo.bandpasses import get_bandpass
|
|
49
|
+
|
|
50
|
+
if zp is not None and zpsys is None:
|
|
51
|
+
raise ValueError('zpsys must be given if zp is not None')
|
|
52
|
+
|
|
53
|
+
# broadcast arrays
|
|
54
|
+
if zp is None:
|
|
55
|
+
time_or_phase, band = np.broadcast_arrays(time_or_phase, band)
|
|
56
|
+
else:
|
|
57
|
+
time_or_phase, band, zp, zpsys = \
|
|
58
|
+
np.broadcast_arrays(time_or_phase, band, zp, zpsys)
|
|
59
|
+
|
|
60
|
+
# Convert all to 1-d arrays.
|
|
61
|
+
ndim = time_or_phase.ndim # Save input ndim for return val.
|
|
62
|
+
time_or_phase = np.atleast_1d(time_or_phase)
|
|
63
|
+
band = np.atleast_1d(band)
|
|
64
|
+
if zp is not None:
|
|
65
|
+
zp = np.atleast_1d(zp)
|
|
66
|
+
zpsys = np.atleast_1d(zpsys)
|
|
67
|
+
|
|
68
|
+
# initialize output arrays
|
|
69
|
+
bandflux = np.zeros(time_or_phase.shape, dtype=float)
|
|
70
|
+
|
|
71
|
+
# Loop over unique bands.
|
|
72
|
+
for b in set(band):
|
|
73
|
+
mask = band == b
|
|
74
|
+
b = get_bandpass(b)
|
|
75
|
+
|
|
76
|
+
fsum = _bandflux_single_redback(model, b, time_or_phase[mask])
|
|
77
|
+
|
|
78
|
+
if zp is not None:
|
|
79
|
+
zpnorm = 10. ** (0.4 * zp[mask])
|
|
80
|
+
bandzpsys = zpsys[mask]
|
|
81
|
+
for ms in set(bandzpsys):
|
|
82
|
+
mask2 = bandzpsys == ms
|
|
83
|
+
ms = get_magsystem(ms)
|
|
84
|
+
zpnorm[mask2] = zpnorm[mask2] / ms.zpbandflux(b)
|
|
85
|
+
fsum *= zpnorm
|
|
86
|
+
|
|
87
|
+
bandflux[mask] = fsum
|
|
88
|
+
|
|
89
|
+
if ndim == 0:
|
|
90
|
+
return bandflux[0]
|
|
91
|
+
return bandflux
|
|
92
|
+
|
|
93
|
+
def _bandmag_redback(model, band, magsys, time_or_phase):
|
|
94
|
+
"""
|
|
95
|
+
Support function for bandflux in Source and Model.
|
|
96
|
+
This is necessary to have outside the models because ``phase`` is used in
|
|
97
|
+
Source and ``time`` is used in Model.
|
|
98
|
+
"""
|
|
99
|
+
from sncosmo.magsystems import get_magsystem
|
|
100
|
+
|
|
101
|
+
bandflux = _bandflux_redback(model, band, time_or_phase, None, None)
|
|
102
|
+
band, magsys, bandflux = np.broadcast_arrays(band, magsys, bandflux)
|
|
103
|
+
return_scalar = (band.ndim == 0)
|
|
104
|
+
band = band.ravel()
|
|
105
|
+
magsys = magsys.ravel()
|
|
106
|
+
bandflux = bandflux.ravel()
|
|
107
|
+
|
|
108
|
+
result = np.empty(bandflux.shape, dtype=float)
|
|
109
|
+
for i, (b, ms, f) in enumerate(zip(band, magsys, bandflux)):
|
|
110
|
+
ms = get_magsystem(ms)
|
|
111
|
+
zpf = ms.zpbandflux(b)
|
|
112
|
+
result[i] = -2.5 * np.log10(f / zpf)
|
|
113
|
+
|
|
114
|
+
if return_scalar:
|
|
115
|
+
return result[0]
|
|
116
|
+
return result
|
|
117
|
+
|
|
118
|
+
class RedbackTimeSeriesSource(TimeSeriesSource):
|
|
119
|
+
def __init__(self, phase, wave, flux, **kwargs):
|
|
120
|
+
"""
|
|
121
|
+
RedbackTimeSeriesSource is a subclass of sncosmo.TimeSeriesSource that adds the ability to return the
|
|
122
|
+
flux density at a given time and wavelength, and changes
|
|
123
|
+
the behaviour of the _flux method to better handle models with very low flux values.
|
|
124
|
+
|
|
125
|
+
:param phase: phase/time array
|
|
126
|
+
:param wave: wavelength array in Angstrom
|
|
127
|
+
:param spectra: spectra in erg/cm^2/s/A evaluated at all times and frequencies; shape (len(times), len(frequency_array))
|
|
128
|
+
:param kwargs: additional arguments
|
|
129
|
+
"""
|
|
130
|
+
super(RedbackTimeSeriesSource, self).__init__(phase=phase, wave=wave, flux=flux, **kwargs)
|
|
131
|
+
|
|
132
|
+
def get_flux_density(self, time, wavelength):
|
|
133
|
+
"""
|
|
134
|
+
Get the flux density at a given time and wavelength.
|
|
135
|
+
|
|
136
|
+
:param time: time in days
|
|
137
|
+
:param wavelength: wavelength in Angstrom
|
|
138
|
+
:return: flux density in erg/cm^2/s/A
|
|
139
|
+
"""
|
|
140
|
+
return self._flux(time, wavelength)
|
|
141
|
+
|
|
142
|
+
def bandflux(self, band, phase, zp=None, zpsys=None):
|
|
143
|
+
"""
|
|
144
|
+
Flux through the given bandpass(es) at the given phase(s).
|
|
145
|
+
|
|
146
|
+
Default return value is flux in photons / s / cm^2. If zp and zpsys
|
|
147
|
+
are given, flux(es) are scaled to the requested zeropoints.
|
|
148
|
+
|
|
149
|
+
Parameters
|
|
150
|
+
----------
|
|
151
|
+
band : str or list_like
|
|
152
|
+
Name(s) of bandpass(es) in registry.
|
|
153
|
+
phase : float or list_like, optional
|
|
154
|
+
Phase(s) in days. Default is `None`, which corresponds to the full
|
|
155
|
+
native phase sampling of the model.
|
|
156
|
+
zp : float or list_like, optional
|
|
157
|
+
If given, zeropoint to scale flux to (must also supply ``zpsys``).
|
|
158
|
+
If not given, flux is not scaled.
|
|
159
|
+
zpsys : str or list_like, optional
|
|
160
|
+
Name of a magnitude system in the registry, specifying the system
|
|
161
|
+
that ``zp`` is in.
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
bandflux : float or `~numpy.ndarray`
|
|
166
|
+
Flux in photons / s /cm^2, unless `zp` and `zpsys` are
|
|
167
|
+
given, in which case flux is scaled so that it corresponds
|
|
168
|
+
to the requested zeropoint. Return value is `float` if all
|
|
169
|
+
input parameters are scalars, `~numpy.ndarray` otherwise.
|
|
170
|
+
"""
|
|
171
|
+
return _bandflux_redback(self, band, phase, zp, zpsys)
|
|
172
|
+
|
|
173
|
+
def bandmag(self, band, magsys, phase):
|
|
174
|
+
"""Magnitude at the given phase(s) through the given
|
|
175
|
+
bandpass(es), and for the given magnitude system(s).
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
band : str or list_like
|
|
180
|
+
Name(s) of bandpass in registry.
|
|
181
|
+
magsys : str or list_like
|
|
182
|
+
Name(s) of `~sncosmo.MagSystem` in registry.
|
|
183
|
+
phase : float or list_like
|
|
184
|
+
Phase(s) in days.
|
|
185
|
+
|
|
186
|
+
Returns
|
|
187
|
+
-------
|
|
188
|
+
mag : float or `~numpy.ndarray`
|
|
189
|
+
Magnitude for each item in band, magsys, phase.
|
|
190
|
+
The return value is a float if all parameters are not iterables.
|
|
191
|
+
The return value is an `~numpy.ndarray` if any are iterable.
|
|
192
|
+
"""
|
|
193
|
+
return _bandmag_redback(self, band, magsys, phase)
|
|
194
|
+
|
|
195
|
+
|
|
9
196
|
|
|
10
197
|
def blackbody_to_flux_density(temperature, r_photosphere, dl, frequency):
|
|
11
198
|
"""
|
|
@@ -298,13 +485,18 @@ def get_correct_output_format_from_spectra(time, time_eval, spectra, lambda_arra
|
|
|
298
485
|
:param time: times in observer frame in days to evaluate the model on
|
|
299
486
|
:param time_eval: times in observer frame where spectra are evaluated. A densely sampled array for accuracy
|
|
300
487
|
:param bands: band array - must be same length as time array or a single band
|
|
301
|
-
:param spectra: spectra in
|
|
488
|
+
:param spectra: spectra in erg/cm^2/s/A evaluated at all times and frequencies; shape (len(times), len(frequency_array))
|
|
302
489
|
:param lambda_array: wavelenth array in Angstrom in observer frame
|
|
303
490
|
:param kwargs: Additional parameters
|
|
304
491
|
:param output_format: 'flux', 'magnitude', 'sncosmo_source', 'flux_density'
|
|
305
492
|
:return: flux, magnitude or SNcosmo TimeSeries Source depending on output format kwarg
|
|
306
493
|
"""
|
|
307
|
-
|
|
494
|
+
# clean up spectrum to remove nonsensical values before creating sncosmo source
|
|
495
|
+
spectra = np.nan_to_num(spectra)
|
|
496
|
+
spectra[spectra.value == np.nan_to_num(np.inf)] = 1e-30 * np.mean(spectra[5])
|
|
497
|
+
spectra[spectra.value == 0.] = 1e-30 * np.mean(spectra[5])
|
|
498
|
+
|
|
499
|
+
source = RedbackTimeSeriesSource(phase=time_eval, wave=lambda_array, flux=spectra)
|
|
308
500
|
if kwargs['output_format'] == 'flux':
|
|
309
501
|
bands = kwargs['bands']
|
|
310
502
|
magnitude = source.bandmag(phase=time, band=bands, magsys='ab')
|
redback/simulate_transients.py
CHANGED
|
@@ -14,7 +14,7 @@ datadir = os.path.join(os.path.dirname(redback.__file__), 'tables')
|
|
|
14
14
|
|
|
15
15
|
class SimulateGenericTransient(object):
|
|
16
16
|
def __init__(self, model, parameters, times, model_kwargs, data_points,
|
|
17
|
-
seed=1234, multiwavelength_transient=False, noise_term=0.2):
|
|
17
|
+
seed=1234, multiwavelength_transient=False, noise_term=0.2, noise_type='gaussianmodel', extra_scatter=0.0):
|
|
18
18
|
"""
|
|
19
19
|
A generic interface to simulating transients
|
|
20
20
|
|
|
@@ -31,7 +31,12 @@ class SimulateGenericTransient(object):
|
|
|
31
31
|
and the data points are sampled in bands/frequency as well,
|
|
32
32
|
rather than just corresponding to one wavelength/filter.
|
|
33
33
|
This also allows the same time value to be sampled multiple times.
|
|
34
|
-
:param
|
|
34
|
+
:param noise_type: String. Type of noise to add to the model.
|
|
35
|
+
Default is 'gaussianmodel' where sigma is noise_term * model.
|
|
36
|
+
Another option is 'gaussian' i.e., a simple Gaussian noise with sigma = noise_term.
|
|
37
|
+
:param noise_term: Float. Factor which is multiplied by the model flux/magnitude to give the sigma
|
|
38
|
+
or is sigma itself for 'gaussian' noise.
|
|
39
|
+
:param extra_scatter: Float. Sigma of normal added to output for additional scatter.
|
|
35
40
|
"""
|
|
36
41
|
self.model = redback.model_library.all_models_dict[model]
|
|
37
42
|
self.parameters = parameters
|
|
@@ -44,20 +49,25 @@ class SimulateGenericTransient(object):
|
|
|
44
49
|
self.noise_term = noise_term
|
|
45
50
|
random.seed(self.seed)
|
|
46
51
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
raise ValueError('Must supply either bands or frequency to sample data points for an optical transient')
|
|
52
|
-
if self.all_bands is not None and self.all_frequency is None:
|
|
53
|
-
self.subset_bands = np.array(random.choices(self.all_bands, k=self.data_points))
|
|
54
|
-
if self.all_bands is None and self.all_frequency is not None:
|
|
55
|
-
self.subset_frequency = np.array(random.choices(self.all_frequency, k=self.data_points))
|
|
56
|
-
self.replacement = True
|
|
57
|
-
# allow times to be chosen repeatedly
|
|
52
|
+
self.all_bands = self.model_kwargs.get('bands', None)
|
|
53
|
+
self.all_frequency = self.model_kwargs.get('frequency', None)
|
|
54
|
+
if self.all_bands is None and self.all_frequency is None:
|
|
55
|
+
raise ValueError('Must supply either bands or frequency to sample data points for an optical transient')
|
|
58
56
|
else:
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
if multiwavelength_transient:
|
|
58
|
+
if self.all_bands is not None and self.all_frequency is None:
|
|
59
|
+
self.subset_bands = np.array(random.choices(self.all_bands, k=self.data_points))
|
|
60
|
+
if self.all_bands is None and self.all_frequency is not None:
|
|
61
|
+
self.subset_frequency = np.array(random.choices(self.all_frequency, k=self.data_points))
|
|
62
|
+
self.replacement = True
|
|
63
|
+
# allow times to be chosen repeatedly
|
|
64
|
+
else:
|
|
65
|
+
if self.all_bands is not None and self.all_frequency is None:
|
|
66
|
+
self.subset_bands = self.data_points * [self.all_bands]
|
|
67
|
+
if self.all_bands is None and self.all_frequency is not None:
|
|
68
|
+
self.subset_frequency = np.ones(self.data_points) * self.all_frequency
|
|
69
|
+
# allow times to be chosen only once.
|
|
70
|
+
self.replacement = False
|
|
61
71
|
self.subset_times = np.sort(np.random.choice(self.all_times, size=self.data_points, replace=self.replacement))
|
|
62
72
|
|
|
63
73
|
injection_kwargs = self.parameters.copy()
|
|
@@ -76,24 +86,43 @@ class SimulateGenericTransient(object):
|
|
|
76
86
|
if 'frequency' in model_kwargs.keys():
|
|
77
87
|
data['frequency'] = self.subset_frequency
|
|
78
88
|
data['true_output'] = true_output
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
|
|
90
|
+
if noise_type == 'gaussianmodel':
|
|
91
|
+
noise = np.random.normal(0, self.noise_term * true_output, len(true_output))
|
|
92
|
+
output = true_output + noise
|
|
93
|
+
output_error = self.noise_term * true_output
|
|
94
|
+
elif noise_type == 'gaussian':
|
|
95
|
+
noise = np.random.normal(0, self.noise_term, len(true_output))
|
|
96
|
+
output = true_output + noise
|
|
97
|
+
output_error = self.noise_term
|
|
98
|
+
else:
|
|
99
|
+
logger.warning(f"noise_type {noise_type} not implemented.")
|
|
100
|
+
raise ValueError('noise_type must be either gaussianmodel or gaussian')
|
|
101
|
+
|
|
102
|
+
if extra_scatter > 0:
|
|
103
|
+
extra_noise = np.random.normal(0, extra_scatter, len(true_output))
|
|
104
|
+
output = output + extra_noise
|
|
105
|
+
output_error = np.sqrt(output_error**2 + extra_noise**2)
|
|
106
|
+
|
|
107
|
+
data['output'] = output
|
|
108
|
+
data['output_error'] = output_error
|
|
81
109
|
self.data = data
|
|
82
110
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
111
|
+
def save_transient(self, name):
|
|
112
|
+
"""
|
|
113
|
+
Save the transient observations to a csv file.
|
|
114
|
+
This will save the full observational dataframe including non-detections etc.
|
|
115
|
+
This will save the data to a folder called 'simulated'
|
|
116
|
+
with the name of the transient and a csv file of the injection parameters
|
|
117
|
+
|
|
118
|
+
:param name: name to save transient.
|
|
119
|
+
"""
|
|
120
|
+
bilby.utils.check_directory_exists_and_if_not_mkdir('simulated')
|
|
121
|
+
path = 'simulated/' + name + '.csv'
|
|
122
|
+
injection_path = 'simulated/' + name + '_injection_parameters.csv'
|
|
123
|
+
self.data.to_csv(path, index=False)
|
|
124
|
+
self.parameters=pd.DataFrame.from_dict([self.parameters])
|
|
125
|
+
self.parameters.to_csv(injection_path, index=False)
|
|
97
126
|
|
|
98
127
|
class SimulateOpticalTransient(object):
|
|
99
128
|
def __init__(self, model, parameters, pointings_database=None,
|
|
@@ -415,7 +444,7 @@ class SimulateOpticalTransient(object):
|
|
|
415
444
|
Convert the circular field of view to a radius in radians.
|
|
416
445
|
:return: survey_radius in radians
|
|
417
446
|
"""
|
|
418
|
-
survey_fov_sqrad = self.survey_fov_sqdeg*(np.pi/180.0)
|
|
447
|
+
survey_fov_sqrad = self.survey_fov_sqdeg*(np.pi/180.0)**2
|
|
419
448
|
survey_radius = np.sqrt(survey_fov_sqrad/np.pi)
|
|
420
449
|
# survey_radius = np.sqrt(self.survey_fov_sqdeg*((np.pi/180.0)**2.0)/np.pi)
|
|
421
450
|
return survey_radius
|
redback/tables/filters.csv
CHANGED
|
@@ -212,7 +212,7 @@ f2100w,1.443e+13,207950.05,black,1.122e-07,f2100w,MIRI/F2100W
|
|
|
212
212
|
f2300c,1.325e+13,226446.44,black,9.225e-08,f2300c,MIRI/F2300C
|
|
213
213
|
f2550w,1.183e+13,253640.02,black,6.601e-08,f2550w,MIRI/F2550W
|
|
214
214
|
G,4.799e+14,6251.50,black,1.321e-05,gaia::G,Gaia/G
|
|
215
|
-
gaia::
|
|
215
|
+
gaia::g,4.799e+14,6251.50,black,1.321e-05,gaia::g,Gaia/G
|
|
216
216
|
y',3.116e+14,9627.79,black,7.517e-07,ps1::y,PS1/y
|
|
217
217
|
y,3.116e+14,9627.79,black,7.517e-07,ps1::y,PS1/y
|
|
218
218
|
Y,3.116e+14,9627.79,black,7.517e-07,ps1::y,PS1/y
|
|
@@ -238,3 +238,17 @@ euclid::VIS,4.223e+14,7103.37,black,7.577e-06,euclid::VIS,EUCLID/VIS
|
|
|
238
238
|
efosc2::g,5.866e+14,5114.66,black,3.302e-06,efosc2::g,EFOSC2/g
|
|
239
239
|
efosc2::r,4.493e+14,6677.40,black,2.342e-06,efosc2::r,EFOSC2/r
|
|
240
240
|
efosc2::i,3.758e+14,7983.20,black,2.435e-06,efosc2::i,EFOSC2/i
|
|
241
|
+
desg,6.2390e+14,4808.49,black,4.781e-06,desg,DES/g
|
|
242
|
+
desr,4.6746e+14,6417.65,black,3.409e-06,desr,DES/r
|
|
243
|
+
desi,3.8390e+14,7814.58,black,2.300e-06,desi,DES/i
|
|
244
|
+
desz,3.2719e+14,9168.85,black,1.679e-06,desz,DES/z
|
|
245
|
+
desy,3.0315e+14,9896.11,black,7.511e-07,desy,DES/y
|
|
246
|
+
tess,3.8973e+14,7697.6,black,7.658e-06,tess,TESS
|
|
247
|
+
gaia::gbp,5.8712e+14,5109.71,black,9.421e-06,gaia::gbp,GAIA/Gbp
|
|
248
|
+
gaia::g,4.799e+14,6217.59,black,1.278e-05,gaia::g,GAIA/G
|
|
249
|
+
gaia::grp,3.8615e+14,7769.02,black,5.472e-06,gaia::grp,GAIA/Grp
|
|
250
|
+
gaia::grvs,3.4970e+14,8578.76,black,3.481e-07,gaia::grvs,GAIA/Grvs
|
|
251
|
+
gotob,6.4895e+14,4622.88,black,3.771e-06,gotob,GOTO/B
|
|
252
|
+
gotog,5.5819e+14,5374.54,black,3.255e-06,gotog,GOTO/G
|
|
253
|
+
gotol,5.4311e+14,5523.78,black,8.027e-06,gotol,GOTO/L
|
|
254
|
+
gotor,4.6679e+14,6426.84,black,2.510e-06,gotor,GOTO/R
|
redback/tables/ztf.tar.gz
CHANGED
|
Binary file
|
redback/transient/afterglow.py
CHANGED
|
@@ -57,7 +57,7 @@ class Afterglow(Transient):
|
|
|
57
57
|
:type flux: np.ndarray, optional
|
|
58
58
|
:type flux_err: np.ndarray, optional
|
|
59
59
|
:param flux_err: Flux error values.
|
|
60
|
-
:param flux_density:Flux density values.
|
|
60
|
+
:param flux_density: Flux density values.
|
|
61
61
|
:type flux_density: np.ndarray, optional
|
|
62
62
|
:param flux_density_err: Flux density error values.
|
|
63
63
|
:type flux_density_err: np.ndarray, optional
|
|
@@ -244,7 +244,8 @@ class Afterglow(Transient):
|
|
|
244
244
|
'BAT Photon Index (15-150 keV) (PL = simple power-law, CPL = cutoff power-law)'].fillna(0)
|
|
245
245
|
self.meta_data = meta_data
|
|
246
246
|
except FileNotFoundError:
|
|
247
|
-
logger.
|
|
247
|
+
logger.info("Metadata does not exist for this event.")
|
|
248
|
+
logger.info("Setting metadata to None. This is not an error, but a warning that no metadata could be found online.")
|
|
248
249
|
self.meta_data = None
|
|
249
250
|
|
|
250
251
|
def _set_photon_index(self) -> None:
|
redback/transient/kilonova.py
CHANGED
|
@@ -50,7 +50,7 @@ class Kilonova(OpticalTransient):
|
|
|
50
50
|
:type flux: np.ndarray, optional
|
|
51
51
|
:type flux_err: np.ndarray, optional
|
|
52
52
|
:param flux_err: Flux error values.
|
|
53
|
-
:param flux_density:Flux density values.
|
|
53
|
+
:param flux_density: Flux density values.
|
|
54
54
|
:type flux_density: np.ndarray, optional
|
|
55
55
|
:param flux_density_err: Flux density error values.
|
|
56
56
|
:type flux_density_err: np.ndarray, optional
|
redback/transient/supernova.py
CHANGED
|
@@ -45,7 +45,7 @@ class Supernova(OpticalTransient):
|
|
|
45
45
|
:type flux: np.ndarray, optional
|
|
46
46
|
:type flux_err: np.ndarray, optional
|
|
47
47
|
:param flux_err: Flux error values.
|
|
48
|
-
:param flux_density:Flux density values.
|
|
48
|
+
:param flux_density: Flux density values.
|
|
49
49
|
:type flux_density: np.ndarray, optional
|
|
50
50
|
:param flux_density_err: Flux density error values.
|
|
51
51
|
:type flux_density_err: np.ndarray, optional
|
redback/transient/tde.py
CHANGED
|
@@ -42,7 +42,7 @@ class TDE(OpticalTransient):
|
|
|
42
42
|
:type flux: np.ndarray, optional
|
|
43
43
|
:type flux_err: np.ndarray, optional
|
|
44
44
|
:param flux_err: Flux error values.
|
|
45
|
-
:param flux_density:Flux density values.
|
|
45
|
+
:param flux_density: Flux density values.
|
|
46
46
|
:type flux_density: np.ndarray, optional
|
|
47
47
|
:param flux_density_err: Flux density error values.
|
|
48
48
|
:type flux_density_err: np.ndarray, optional
|
redback/transient/transient.py
CHANGED
|
@@ -137,7 +137,7 @@ class Transient(object):
|
|
|
137
137
|
self.system = system
|
|
138
138
|
self.data_mode = data_mode
|
|
139
139
|
self.active_bands = active_bands
|
|
140
|
-
self.sncosmo_bands = redback.utils.sncosmo_bandname_from_band(self.bands
|
|
140
|
+
self.sncosmo_bands = redback.utils.sncosmo_bandname_from_band(self.bands)
|
|
141
141
|
self.redshift = redshift
|
|
142
142
|
self.name = name
|
|
143
143
|
self.use_phase_model = use_phase_model
|
|
@@ -906,7 +906,7 @@ class OpticalTransient(Transient):
|
|
|
906
906
|
meta_data = pd.read_csv(self.event_table, on_bad_lines='skip', delimiter=',', dtype='str')
|
|
907
907
|
except FileNotFoundError as e:
|
|
908
908
|
redback.utils.logger.warning(e)
|
|
909
|
-
redback.utils.logger.warning("Setting metadata to None")
|
|
909
|
+
redback.utils.logger.warning("Setting metadata to None. This is not an error, but a warning that no metadata could be found online.")
|
|
910
910
|
meta_data = None
|
|
911
911
|
self.meta_data = meta_data
|
|
912
912
|
|
|
@@ -2092,6 +2092,48 @@ def tophat(time, redshift, thv, loge0, thc, logn0, p, logepse, logepsb, ksin, g0
|
|
|
2092
2092
|
elif kwargs['output_format'] == 'magnitude':
|
|
2093
2093
|
return calc_ABmag_from_flux_density(flux_density).value
|
|
2094
2094
|
|
|
2095
|
+
|
|
2096
|
+
def tophat_from_emulator(time, redshift, thv, loge0, thc, logn0, p, logepse, logepsb, g0, **kwargs):
|
|
2097
|
+
"""
|
|
2098
|
+
Evaluate a tophat afterglow model using an mpl regressor. Note that this model predicts for a fixed redshift = 0.01 and fixed ksin = 1.
|
|
2099
|
+
This tophat model does not include all of the ususal kwargs
|
|
2100
|
+
|
|
2101
|
+
:param time: time in days in observer frame, should be in range 0.1 to 300
|
|
2102
|
+
:param redshift: source redshift
|
|
2103
|
+
:param thv: viewing angle in radians
|
|
2104
|
+
:param loge0: log10 on axis isotropic equivalent energy
|
|
2105
|
+
:param thc: half width of jet core/jet opening angle in radians
|
|
2106
|
+
:param logn0: log10 number density of ISM in cm^-3
|
|
2107
|
+
:param p: electron distribution power law index. Must be greater than 2.
|
|
2108
|
+
:param logepse: log10 fraction of thermal energy in electrons
|
|
2109
|
+
:param logepsb: log10 fraction of thermal energy in magnetic field
|
|
2110
|
+
:param g0: initial lorentz factor
|
|
2111
|
+
:param kwargs: Additional keyword arguments
|
|
2112
|
+
:param frequency: frequency of the band to view in- single number or same length as time array
|
|
2113
|
+
:param output_format: Whether to output flux density or AB mag, specified by 'flux_density' or 'magnitude'
|
|
2114
|
+
:return: flux density or AB mag predicted by emulator. Note this is going to give the monochromatic magnitude at the effective frequency for the band.
|
|
2115
|
+
For a proper calculation of the magntitude use the sed variant models
|
|
2116
|
+
"""
|
|
2117
|
+
|
|
2118
|
+
from redback_surrogates.afterglowmodels import tophat_emulator
|
|
2119
|
+
|
|
2120
|
+
z1=0.01
|
|
2121
|
+
z2= redshift
|
|
2122
|
+
frequency= np.log10(kwargs['frequency'])
|
|
2123
|
+
flux_density = tophat_emulator(new_time=time/(1+z2), thv=thv, loge0=loge0, thc=thc, logn0=logn0, p=p,
|
|
2124
|
+
logepse=logepse, logepsb=logepsb, g0=g0,frequency=frequency)
|
|
2125
|
+
|
|
2126
|
+
#scaling flux density with redshift
|
|
2127
|
+
dl1 = cosmo.luminosity_distance(z1)
|
|
2128
|
+
dl2 = cosmo.luminosity_distance(z2)
|
|
2129
|
+
scale_factor = ((dl1**2)*(1+z1)) / (dl2**2)
|
|
2130
|
+
flux_density=flux_density*scale_factor
|
|
2131
|
+
|
|
2132
|
+
if kwargs['output_format'] == 'flux_density':
|
|
2133
|
+
return flux_density
|
|
2134
|
+
elif kwargs['output_format'] == 'magnitude':
|
|
2135
|
+
return calc_ABmag_from_flux_density(flux_density).value
|
|
2136
|
+
|
|
2095
2137
|
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract')
|
|
2096
2138
|
def afterglow_models_with_energy_injection(time, **kwargs):
|
|
2097
2139
|
"""
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import redback.transient_models.extinction_models
|
|
2
|
-
|
|
1
|
+
import redback.transient_models.extinction_models as em
|
|
2
|
+
from redback.utils import citation_wrapper
|
|
3
|
+
|
|
4
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract, https://ui.adsabs.harvard.edu/abs/2020ApJ...891..152H/abstract')
|
|
5
|
+
def tophat_and_twolayerstratified(time, redshift, av, thv, loge0, thc, logn0, p, logepse,
|
|
6
|
+
logepsb, ksin, g0, mej, vej_1, vej_2, kappa, beta, **kwargs):
|
|
3
7
|
|
|
4
8
|
"""
|
|
5
9
|
function to combine the flux density signals of a tophat afterglow and a two layer stratified kilonova with extinction
|
|
@@ -36,18 +40,20 @@ def tophat_and_twolayerstratified(time, redshift, av, thv, loge0, thc, logn0, p,
|
|
|
36
40
|
"""
|
|
37
41
|
kwargs['output_format']='flux_density'
|
|
38
42
|
kwargs['base_model']='tophat'
|
|
39
|
-
afterglow =
|
|
43
|
+
afterglow = em.extinction_with_afterglow_base_model(time=time, redshift=redshift, av=av,
|
|
40
44
|
thv=thv, loge0=loge0 , thc= thc, logn0=logn0, p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0,
|
|
41
45
|
**kwargs)
|
|
42
46
|
kwargs['base_model']='two_layer_stratified_kilonova'
|
|
43
|
-
kilonova =
|
|
47
|
+
kilonova = em.extinction_with_kilonova_base_model(time=time, redshift=redshift, av=av,
|
|
44
48
|
mej=mej, vej_1=vej_1, vej_2=vej_2, kappa=kappa, beta=beta, **kwargs)
|
|
45
49
|
|
|
46
50
|
combined = afterglow+kilonova
|
|
47
51
|
return combined
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
def tophat_and_twocomponent(time, redshift, av, thv, loge0, thc, logn0,
|
|
53
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract, redback')
|
|
54
|
+
def tophat_and_twocomponent(time, redshift, av, thv, loge0, thc, logn0,
|
|
55
|
+
p, logepse, logepsb, ksin, g0, mej_1, vej_1,
|
|
56
|
+
temperature_floor_1, kappa_1, mej_2, vej_2, temperature_floor_2, kappa_2, **kwargs):
|
|
51
57
|
|
|
52
58
|
"""
|
|
53
59
|
function to combine the flux density signals of a tophat afterglow and a two component kilonova with extinction added
|
|
@@ -85,19 +91,21 @@ def tophat_and_twocomponent(time, redshift, av, thv, loge0, thc, logn0, p, logep
|
|
|
85
91
|
:return: flux density signal with extinction added
|
|
86
92
|
"""
|
|
87
93
|
|
|
88
|
-
kwargs['output_format']='flux_density'
|
|
89
|
-
kwargs['base_model']='tophat'
|
|
90
|
-
afterglow =
|
|
91
|
-
thv=thv, loge0=loge0
|
|
92
|
-
|
|
93
|
-
kwargs['base_model']='two_component_kilonova_model'
|
|
94
|
-
kilonova =
|
|
95
|
-
|
|
94
|
+
kwargs['output_format'] = 'flux_density'
|
|
95
|
+
kwargs['base_model'] = 'tophat'
|
|
96
|
+
afterglow = em.extinction_with_afterglow_base_model(time=time, redshift=redshift, av=av,
|
|
97
|
+
thv=thv, loge0=loge0, thc=thc, logn0=logn0, p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0,**kwargs)
|
|
98
|
+
|
|
99
|
+
kwargs['base_model'] = 'two_component_kilonova_model'
|
|
100
|
+
kilonova = em.extinction_with_kilonova_base_model(time=time, redshift=redshift, av=av,
|
|
101
|
+
mej_1=mej_1, vej_1=vej_1, temperature_floor_1=temperature_floor_1,
|
|
102
|
+
kappa_1=kappa_1, mej_2=mej_2, vej_2=vej_2,
|
|
103
|
+
temperature_floor_2=temperature_floor_2, kappa_2=kappa_2, **kwargs)
|
|
96
104
|
|
|
97
105
|
combined = afterglow + kilonova
|
|
98
106
|
return combined
|
|
99
107
|
|
|
100
|
-
|
|
108
|
+
@citation_wrapper('https://ui.adsabs.harvard.edu/abs/2020ApJ...896..166R/abstract, https://ui.adsabs.harvard.edu/abs/1982ApJ...253..785A/abstract')
|
|
101
109
|
def tophat_and_arnett(time, av, redshift, thv, loge0, thc, logn0, p, logepse, logepsb, ksin, g0, f_nickel, mej, **kwargs):
|
|
102
110
|
|
|
103
111
|
"""
|
|
@@ -137,19 +145,20 @@ def tophat_and_arnett(time, av, redshift, thv, loge0, thc, logn0, p, logepse, lo
|
|
|
137
145
|
:return: flux density with extinction added
|
|
138
146
|
"""
|
|
139
147
|
|
|
140
|
-
kwargs['output_format']='flux_density'
|
|
141
|
-
kwargs['base_model']='tophat'
|
|
142
|
-
afterglow =
|
|
143
|
-
thv=thv, loge0=loge0
|
|
148
|
+
kwargs['output_format'] = 'flux_density'
|
|
149
|
+
kwargs['base_model'] = 'tophat'
|
|
150
|
+
afterglow = em.extinction_with_afterglow_base_model(time=time, redshift=redshift, av=av,
|
|
151
|
+
thv=thv, loge0=loge0, thc=thc, logn0=logn0, p=p, logepse=logepse, logepsb=logepsb, ksin=ksin, g0=g0,
|
|
144
152
|
**kwargs)
|
|
145
|
-
kwargs['base_model']='arnett'
|
|
146
|
-
supernova =
|
|
153
|
+
kwargs['base_model'] = 'arnett'
|
|
154
|
+
supernova = em.extinction_with_supernova_base_model(time=time, redshift=redshift, av=av,
|
|
147
155
|
f_nickel=f_nickel, mej=mej, **kwargs)
|
|
148
156
|
|
|
149
157
|
combined = afterglow + supernova
|
|
150
158
|
return combined
|
|
151
159
|
|
|
152
|
-
|
|
160
|
+
@citation_wrapper('redback, and any citations for the specific model you use')
|
|
161
|
+
def afterglow_and_optical(time, redshift, av, **model_kwargs):
|
|
153
162
|
|
|
154
163
|
"""
|
|
155
164
|
function to combine the signals of any afterglow and any other optical transient with extinction added
|
|
@@ -157,26 +166,32 @@ def afterglow_and_optical(time, redshift, av, model_type, afterglow_kwargs, opti
|
|
|
157
166
|
:param time: time in days in observer frame
|
|
158
167
|
:param redshift: source redshift
|
|
159
168
|
:param av: absolute mag extinction
|
|
169
|
+
:param model_kwargs: kwargs shared by models e.g. output_format, frequency, bands, r_v (extinction paramater defaults to 3.1)
|
|
160
170
|
:param model_type: specify type of optical transient model- 'supernova', 'tde', 'kilonova', 'magnetar_driven', 'shock_powered'
|
|
161
171
|
:param afterglow_kwargs: dictionary of parameters required by the afterglow transient model specified by 'base_model'
|
|
162
172
|
and any additional keyword arguments. Refer to model documentation for details.
|
|
163
173
|
:param optical_kwargs: dictionary of parameters required by the optical transient model specifed by 'base_model'
|
|
164
174
|
and any additional keyword arguments. Note the base model must correspond to the given model type. Refer to model documentation
|
|
165
175
|
for details.
|
|
166
|
-
:param shared_kwargs: kwargs shared by models e.g. output_format, frequency, bands, r_v (extinction paramater defaults to 3.1)
|
|
167
176
|
:return: set by shared_kwargs output format - 'flux_density' or 'magnitude' with extinction added
|
|
168
177
|
note that only afterglow_models_sed allow for magnitude outputs
|
|
169
178
|
"""
|
|
179
|
+
|
|
180
|
+
optical_kwargs = model_kwargs['optical_kwargs']
|
|
181
|
+
afterglow_kwargs = model_kwargs['afterglow_kwargs']
|
|
182
|
+
|
|
183
|
+
_afterglow_kwargs = afterglow_kwargs.copy()
|
|
184
|
+
_afterglow_kwargs.update(model_kwargs)
|
|
185
|
+
_afterglow_kwargs.pop('model_type')
|
|
186
|
+
|
|
187
|
+
_optical_kwargs = optical_kwargs.copy()
|
|
188
|
+
_optical_kwargs.update(model_kwargs)
|
|
189
|
+
|
|
190
|
+
afterglow = em._evaluate_extinction_model(time=time, redshift=redshift, av=av,model_type='afterglow',
|
|
191
|
+
**_afterglow_kwargs)
|
|
170
192
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
afterglow = redback.transient_models.extinction_models._evaluate_extinction_model(time=time, redshift=redshift, av=av,
|
|
175
|
-
model_type='afterglow', **afterglow_kwargs)
|
|
176
|
-
|
|
177
|
-
optical= redback.transient_models.extinction_models._evaluate_extinction_model(time=time, redshift=redshift, av=av,
|
|
178
|
-
model_type=model_type, **optical_kwargs)
|
|
179
|
-
|
|
193
|
+
optical = em._evaluate_extinction_model(time=time, redshift=redshift, av=av, **_optical_kwargs)
|
|
194
|
+
|
|
180
195
|
combined= afterglow + optical
|
|
181
196
|
return combined
|
|
182
197
|
|