Create a new Transient class

Create a new Transient class#

skysurvey provides pre-built classes for different transients. These classes rely on the sncosmo for spectral modeling. However, since sncosmo does not contain templates for every existing transient type, you may want to implement a new class to use a custom spectral template grid.


Depending on the templates used, you’ll have to format them into sncosmo.TimeSeriesSource objects so that skysurvey can use them as templates when simulating transient light curves.

To create a new Transient class you will need to:

  • Convert your spectral data into an sncosmo source object (e.g., sncosmo.TimeSeriesSource) if needed.

  • Subclass a skysurvey base class (like Transient or MultiTemplateTSTransient) and set the required attributes (_TEMPLATE or _SOURCES, _RATE, _MODEL, etc.).

Peculiar SNeIa (SNeIax) example#

Let’s create a new class, SNeIax, using Type Iax SNe templates (SIMSED.SNIax.tar.gz) coming from PLAsTiCC (Zenodo DOI: 10.5281/zenodo.6672739).

The collection of PLAsTiCC SNIax templates, containing 1000 templates, are provided as ASCII files (SED-Iax-****.dat), with each file containing the full SED for one template. The data is arranged in three columns: phase, wavelength, and the corresponding flux value.

As sncosmo.TimeSeriesSource requires three arrays to define a spectral template source:

  • a 1D array of phase (in days relative to maximum light)

  • a 1D array of wavelength (in Angstrom)

  • a 2D array of flux values (in erg/s/cm²/Angstrom), where the shape must be (number of unique phases,number of unique wavelengths).

We must reshape the 1D flux columnn of each file into the required 2D flux grid to be able to use those templates with skysurvey.

First, let’s construct the list of .dat files that store the spectral templates:

import numpy as np
import sncosmo
from skysurvey.target.timeserie import MultiTemplateTSTransient

dirpath_Iax = '*/*/SIMSED.SNIax/' # file path
 
files_Iax = []
for i in range (1001):
    files_Iax.append('SED-Iax-'+"%04d" % (i,)+'.dat')

We then extract the unique phase and wavelength values, and reshape the flux accordingly:

# Registering each spectral series from PLAsTiCC as a sncosmo source

sources_Iax = []
for file in files_Iax:
    SED = np.loadtxt(dirpath_Iax+file)
    source = sncosmo.TimeSeriesSource(np.unique(SED[:,0]), np.unique(SED[:,1]), 
                                  SED[:,2].reshape(len(np.unique(SED[:,0])), len(np.unique(SED[:,1]))), name=file)
    sources_Iax.append(source)

Now, we can provide them as sources to either directly define the new SNeIax class that inherits the multi-template handling from MultiTemplateTSTransient:

class SNeIax( MultiTemplateTSTransient ):
    
    _SOURCES = sources_Iax
    _TEMPLATES = "complex"
    _RATE = 5.4e4 # CC 1e5 * (0.75 *0.72) for Type II. 
    _MAGABS = (-15.872, 1.761)

    @property
    def template(self):
        """ """
        if not hasattr(self,"_template") or self._template is None: 
            self.set_template(self._SOURCES)
        return self._template

This defines a new transient type SNeIax that skysurvey can treat like any built-in transient:

sneiax = SNeIax()

Or define a new transient class PeculiarIas, a base class for “peculiar Ia” behavior:

# Building on the skysurvey.target.timeserie.MultiTemplateTSTransient to create the peculiar Ias

class PeculiarIas( object ):
    """ Peculiar Ias based on spectral series files
    """
    _SOURCES = None
    _TEMPLATES = "complex"
    _RATE = 5.4e4 # CC 1e5 * (0.75 *0.72) for Type II. 

    @property
    def template(self):
        """ """
        if not hasattr(self,"_template") or self._template is None: 
            self.set_template(self._SOURCES)
        return self._template

And then the SNeIax class that inherist from PeculiarIas and the multi-template handling from MultiTemplateTSTransient:

class SNeIax( PeculiarIas, MultiTemplateTSTransient ):
    _SOURCES = sources_Iax
    _MAGABS = (-15.872, 1.761)

With the PeculiarIas class, each Ia-peculiar can be its own skysurvey target, by providing the sncosmo sources and the absolute magnitude.

You can easily access to the SNeIax templates, rate, or model as for any other transient class with:

sneiax.template.names

For example, the first 10 files:

sneiax.template.names[:10]
['SED-Iax-0000.dat',
 'SED-Iax-0001.dat',
 'SED-Iax-0002.dat',
 'SED-Iax-0003.dat',
 'SED-Iax-0004.dat',
 'SED-Iax-0005.dat',
 'SED-Iax-0006.dat',
 'SED-Iax-0007.dat',
 'SED-Iax-0008.dat',
 'SED-Iax-0009.dat']
sneiax.rate
54000.0
sneiax
{'redshift': {'kwargs': {'zmax': 0.05, 'rate': 54000.0}, 'as': 'z'},
 't0': {'func': <bound method Generator.uniform of Generator(PCG64) at 0x13B466180>,
        'kwargs': {'low': 56000, 'high': 56200}},
 'magabs': {'func': <bound method Generator.normal of Generator(PCG64) at 0x13B4660A0>,
            'kwargs': {'loc': -15.872, 'scale': 1.761}},
 'magobs': {'func': 'magabs_to_magobs',
            'kwargs': {'z': '@z', 'magabs': '@magabs'}},
 'amplitude': {'func': 'magobs_to_amplitude', 'kwargs': {'magobs': '@magobs'}},
 'radec': {'func': <function random_radec at 0x13833a980>,
           'as': ['ra', 'dec'],
           'kwargs': {}},
 'template': {'func': 'draw_template', 'kwargs': {'redshift': '@z'}}}