In [1]:
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
import sncosmo

Let us set up two different supernovae which are identical in all respects except that they are at different redshifts. Redshifts (often represented by a symbol $z$) are related to the how much the universe has expanded today since the time of an an event. For supernovae, the 'event' is the time when the supernovae exploded. If the average distance between far apart objects like galaxies at a particular time was $d_1$ and the average distance between those objects today is $d_0,$ then the redshift is defined to be $$ z = d_0 / d_1 - 1$$ (note $d_0 > d_1 $ as the universe has expanded since a past time)

The effect on a spectrum of an object emitting light from a certain redshift is a. The measured wavelengths (often denoted by $\lambda$ are different from the wavelengths emitted $$\lambda_{obs} / \lambda_{emit} = d_0 /d_1 = 1 + z $$

This is easy to measure from a spectrum, by measuring the wavelengths of a well known feature (either an emission or absorption feature) in which case you know the wavelength $\lambda_{emit}$ at time of emission. So, comparing $\lambda_{obs}$ from the observed spectrum to $\lambda_{emit}$ from the known values, you can find $z$.

Let us try to see this using the emperical model we will start with. We will have the same 'SN' and try to place it at different redshifts. Having the same SN amounts to using the same astrophysical source in our code.


In [2]:
model = sncosmo.Model(source='SALT2')
model2 = sncosmo.Model(source='SALT2')

In [3]:
# Define the model parameters
# Other parameters are set to default values
model.set(z=0.2)
model.set_source_peakabsmag(-19.5, 'bessellB', 'ab')
model2.set(z=0.5)
model2.set_source_peakabsmag(-19.5, 'bessellB', 'ab')

In [4]:
# z, t0, x0, x1, c are parameters of the model
print model


<Model at 0x1044d9510>
source:
  class      : SALT2Source
  name       : 'salt2'
  version    : 2.4
  phases     : [-20, .., 50] days
  wavelengths: [2000, .., 9200] Angstroms
parameters:
  z  = 0.20000000000000001
  t0 = 0.0
  x0 = 0.00010207029143804028
  x1 = 0.0
  c  = 0.0

In [5]:
print model2


<Model at 0x108127d50>
source:
  class      : SALT2Source
  name       : 'salt2'
  version    : 2.4
  phases     : [-20, .., 50] days
  wavelengths: [2000, .., 9200] Angstroms
parameters:
  z  = 0.5
  t0 = 0.0
  x0 = 1.215085033271297e-05
  x1 = 0.0
  c  = 0.0

The source used in either of these models can be accessed by model.source or model2.source and you can do this to see that they are the same


In [6]:
print model.source


class      : SALT2Source
name       : 'salt2'
version    : 2.4
phases     : [-20, .., 50] days
wavelengths: [2000, .., 9200] Angstroms
parameters:
  x0 = 0.00010207029143804028
  x1 = 0.0
  c  = 0.0

In [7]:
print model2.source


class      : SALT2Source
name       : 'salt2'
version    : 2.4
phases     : [-20, .., 50] days
wavelengths: [2000, .., 9200] Angstroms
parameters:
  x0 = 1.215085033271297e-05
  x1 = 0.0
  c  = 0.0

Redshift Dependence

Now we can study the effect of redshift on the spectrum at the time when it is brightest. To do this, we compare model spectrum that are smoother than usual spectral data (which are much more noisy). Here, on the left, we look at the source, and the spectrum from the same source placed at two different redshifts 0.2, and 0.5. We also highlight the position of a prominent absorption feature at a wavelength of '$\lambda = 6100 $ Angstrom'. On the right, we just repeat the spectrum at the highest redshift to show that it has the same features, which is hard to see on the left plot, simply because it is about 10 times dimmer.


In [8]:
wavelens = np.arange(4000., 9200., 10.)
z = model.get('z')
fig , (ax, ay) =  plt.subplots(1, 2)
ax.plot(wavelens, model.source.flux(wave=wavelens, phase=0.), '-k', label='source')
ax.axvline(6100, color='k')
ax.plot(wavelens, model.flux(wave=wavelens, time=0.), 'b', label='z=0.2')
ax.axvline(6100*(z +1.), color='b')
wavelens = np.arange(model2.minwave(), model2.maxwave(), 10.)
z = model2.get('z')
ax.plot(wavelens, model2.flux(wave=wavelens, time=0.), 'r')
ax.axvline(6100*(z +1.), color='r', label="z={0:.1f}".format(z))
ax.set_ylabel(r'$f_\lambda (ergs/cm^2/sec)$')
ax.set_xlabel(r'$\lambda (Ang)$')
ay.plot(wavelens, model2.flux(wave=wavelens, time=0.), 'r')
ax.axvline(6100*(z +1.), color='r', label="z={0:.1f}".format(z))
ay.axvline(6100*(z +1.), color='r', label="z={0:.1f}".format(z))
ay.set_xlabel(r'$\lambda (Ang)$')
fig.autofmt_xdate()
plt.legend(loc='best')
fig.set_size_inches(12, 6)


We can see two main effects. The spectrum is smaller for the same source at higher redshift (which we don't want to use for finding redshift, that is dependent on the cosmology, and here we have assumed a very specific case) and (b) the feature shifts linearly with redshift.

However, as we have discussed, we are not going to have these spectra. Rather we are going to have light curves with uncertainties. But since the light curves are binned versions of these spectra, they have less information than the spectra, but they do still have some of this information. As an example, let us look at the the light curves (without uncertainties) for these same two models.

As was shown in the introductory talk, the light curves are observations in time over filters that bin the light over wavelength ranges. We can look at the actual way that we binned the light (this is really done by putting a filter in front of a camera, just like one may put a UV filter over a digital SLR to reduce the impact of a bright sun). Let us first take a look at bands used in SDSS


In [9]:
filtfig, filtax = plt.subplots()
filternames = ['sdssu', 'sdssg', 'sdssr', 'sdssi', 'sdssz']
for band in filternames:
    b = sncosmo.get_bandpass(band)
    filtax.plot(b.wave, b.trans, label=band)
plt.legend(loc='best')
filtax.set_xlabel(r'$\lambda (\AA$)')
filtax.set_ylabel(r'num photons transmitted/ num photons incident')


Out[9]:
<matplotlib.text.Text at 0x108e21210>

In [10]:
times = np.arange(-20.,50., 5.0)
figlc, axlc = plt.subplots(2,3, sharex=True, sharey=True)
for i, band in enumerate(filternames):
    try:
        figlc.axes[i].set_title(band)
        figlc.axes[i].plot(times, model.bandflux(time=times, band=band, zpsys='ab', zp=25.),'ko', label='z=0.2')
        figlc.axes[i].plot(times, model2.bandflux(time=times, band=band, zpsys='ab', zp=25.), 'r+', label='z=0.5')
        figlc.axes[i].set_title(band)
    except:
        pass
    figlc.axes[i].grid(True)
figlc.axes[0].set_ylabel('flux (zp=25.)')
figlc.axes[3].set_ylabel('flux (zp=25.)')
figlc.autofmt_xdate()
figlc.axes[3].set_xlabel('time from peak (days)')
figlc.axes[4].set_xlabel('time from peak (days)')
figlc.axes[5].set_xlabel('time from peak (days)')


Out[10]:
<matplotlib.text.Text at 0x109924f10>

Some bands do not have any values in the plots because the spectra do not overlap with the bands. We have not accounted for observations here, which would have uncertainties, but these are only fluxes in bandpass filters as a function of times. As you can see while the dimness is easy to see, but other features are harder to notice. This becomes harder if we don't have the same SN model parameters (identical sources).