Creating a new Source class¶
Extending sncosmo with a custom type of Source.
Source is something that specifies a spectral timeseries as
a function of an arbitrary number of parameters. For example, the SALT2
model has three parameters (
c) that determine a
unique spectrum as a function of phase. The
SALT2Source class implements
the behavior of the model: how the spectral time series depends on those
If you have a spectral timeseries model that follows the behavior of one of
the existing classes, such as
TimeSeriesSource, great! There’s no need to
write a custom class. However, suppose you want to implement a model that
has some new parameterization. In this case, you need a new class that
implements the behavior.
In this example, we implement a new type of source model. Our model is a linear
combination of two spectral time series, with a parameter
determines the relative weight of the models.
import numpy as np from scipy.interpolate import RectBivariateSpline import sncosmo class ComboSource(sncosmo.Source): _param_names = ['amplitude', 'w'] param_names_latex = ['A', 'w'] # used in plotting display def __init__(self, phase, wave, flux1, flux2, name=None, version=None): self.name = name self.version = version self._phase = phase self._wave = wave # ensure that fluxes are on the same scale flux2 = flux1.max() / flux2.max() * flux2 self._model_flux1 = RectBivariateSpline(phase, wave, flux1, kx=3, ky=3) self._model_flux2 = RectBivariateSpline(phase, wave, flux2, kx=3, ky=3) self._parameters = np.array([1., 0.5]) # initial parameters def _flux(self, phase, wave): amplitude, w = self._parameters return amplitude * ((1.0 - w) * self._model_flux1(phase, wave) + w * self._model_flux2(phase, wave))
… and that’s all that we need to define!: A couple class attributes
_flux method. The
_flux method is guaranteed to be passed
numpy arrays for phase and wavelength.
We can now initialize an instance of this source from two spectral time series:
#Just as an example, we'll use some undocumented functionality in # sncosmo to download the Nugent Ia and 2p templates. Don't rely on this # the `DATADIR` object, or these paths in your code though, as these are # subject to change between version of sncosmo! from sncosmo.builtins import DATADIR phase1, wave1, flux1 = sncosmo.read_griddata_ascii( DATADIR.abspath('models/nugent/sn1a_flux.v1.2.dat')) phase2, wave2, flux2 = sncosmo.read_griddata_ascii( DATADIR.abspath('models/nugent/sn2p_flux.v1.2.dat')) # In our __init__ method we defined above, the two fluxes need to be on # the same grid, so interpolate the second onto the first: flux2_interp = RectBivariateSpline(phase2, wave2, flux2)(phase1, wave1) source = ComboSource(phase1, wave1, flux1, flux2_interp, name='sn1a+sn2p')
Downloading http://c3.lbl.gov/nugent/templates/sn1a_flux.v1.2.dat.gz [Done] Downloading http://c3.lbl.gov/nugent/templates/sn2p_flux.v1.2.dat.gz [Done]
We can get a summary of the Source we created:
class : ComboSource name : 'sn1a+sn2p' version : None phases : [0, .., 90] days wavelengths: [1000, .., 25000] Angstroms parameters: amplitude = 1.0 w = 0.5
Get a spectrum at phase 10 for different parameters:
The w=0 spectrum is that of the Ia model, the w=1 spectrum is that of the IIp model, while intermediate spectra are weighted combinations.
We can even fit the model to some data!
<Figure size 780x670 with 8 Axes>
The fact that the fitted value of w is closer to 0 than 1 indicates that the light curve looks more like the Ia template than the IIp template. This is generally what we expected since the example data here was generated from a Ia template (although not the Nugent template!).
Total running time of the script: ( 0 minutes 3.065 seconds)