This repository contains all of the necessary code to take a survey simulation file from David Rubin (repo to be shared soon) to a simulated supernova survey using SNEMO as the underlying SED model. Comments, issues, and pull requests are welcome!
Setup a conda environment and activate it with
conda env create -f environment.yml
conda activate snemo_gen
Then install the package with
python setup.py install
An example input simulation file can be found here. You must download this file and move it to the data directory to be able to run roman_sims.py.
The KDE files and extended SNEMO models are included in snemo_gen/data and are automatically included when installing the snemo_gen package.
There are three scripts to reproduce this work:
generate_KDE.py: Models the underlying distribution of the SNEMO coefficientsv0_extension.py: Extends the wavelength range of the modelroman_sims.py: Creates light-curves and spectra using the signal-to-noise ratios produced in David's code
Steps 1 and 2 only need to be run once. Step 3 can then be rerun for any new survey simulation file. The outputs of steps 1 and 2 (i.e. the KDE files and extended SNEMO templates) can be used for other analyses using the snemo_gen package.
The KDE files model the distribution of coefficients for each SNEMO version. There are some tricky parts to using these files because the KDEs are fit in a rotated and rescaled space and we estimate the distribution of the absolute magnitudes rather than the generate_KDE.py are a list of 4 elements:
kde: the trained scikit-learnKernelDensityestimatorv: unitary matrix used in the whitening transformation applied to the data before fitting the KDEl: singular values of the SVD transformationgrid: the scikit-learnGridSearchCVobject produced in the hyperparameter determination
Sampling directly from the KDE gives a vector of coefficients in the rotated and rescaled coefficient space. Applying the inverse transform to the samples gives the coefficient vector:
unscaled_samples = kde.sample(n_samples)
samples = (np.diag(1./np.sqrt(l)) @ vinv @ unscaled_samples.T).T
This vector gives the values of the following coefficients (note the order):
-
$M_B + 19.1$ : the peak absolute Bessell$B$ -band magnitude, plus an arbitrary offset of 19.1 -
$A_s$ : the color parameter -
$c_i$ ,$i>0$ : the SNEMO coefficients (not including$c_0$ , since this is captured by$M_B + 19.1$ )
In order to produce an sncosmo.Model object with coefficients corresponding to a sampled vector, we would use:
sample = samples[i] # Select one sample from the samples produced above
# This would use the components released with Saunders et al. 2018
# See https://snfactory.lbl.gov/snemo/
# Below section details how to use the extended wavelength version
model = sncosmo.Model(source='snemo15')
# Set the redshift and time of max
model.set(z=z, t0=t0)
# Set all coefficients *except* the scaling
param_dict = dict(zip(model.source.param_names[1:], sample[1:]))
model.set(**param_dict)
# Set the scaling parameter
model.set_source_peakabsmag(sample[0]-19.1, 'bessellb', 'ab')
This functionality is wrapped in snemo_gen.kde.sample_snemo_kde and snemo_gen.kde.MB_to_c0.
The extended SNEMO templates produced by v0_extension.py can be used in sncosmo just like any other templates. We can create a source object and use that source within a Model with
snemo_source = sncosmo.models.SNEMOSource('extended_models/ext_snemo15.dat')
snemo_ext = sncosmo.Model(source=snemo_source)
You can replace ext_snemo15.dat with ext_snemo7.dat or ext_snemo2.dat depending on which version of SNEMO you'd like to use.
roman_sim.py produces one pickle file for each object in the survey in a subdirectory of data with the same name as the input file. Each of these pickle files contains a dictionary with the following keys:
z: (float) redshift of objectt0: (float) time of maximumcoef_orig: (np.arrayof length 16) describing model coefficientslc_time: (np.arrayof lengthn) observer-frame times that the light curve was observedtrue_lc_flux: (np.arrayof lengthn) true flux in the light curve at each observationlc_flux: (np.arrayof lengthn) observed flux in the light curve at each observationlc_flux_err: (np.arrayof lengthn) error in observed fluxband: (np.arrayof lengthn) bandpasses of the observationszp: (np.arrayof lengthn) always set to 25.zpsys: (np.arrayof lengthn) AB magnitudes are usedprism_wave: (np.arrayof lengthw) observer-frame wavelength of the prismprism_ts_time: (np.arrayof lengtht) observer-frame times that a prism spectrum was takenprism_ts_true_flux: (t x w np.array) true flux from the prism at each timeprism_ts_flux: (t x w np.array) observed flux from the prism at each timeprism_ts_flux_err: (t x w np.array) error on observed fluxstacked_prism_time: (float) time of observation of the single stacked near-max prismstacked_prism_true_flux: (arrayof length w) true fluxstacked_prism_flux: (arrayof length w) observed, noisy fluxstacked_prism_flux_err: (arrayof length w) error on observed flux
Note: coef_orig is the vector sampled from the KDE, not the sncosmo model parameter vector. The only difference is in the scaling parameter; the sncosmo model parameter vector is equivalent to the