Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
explore-for-students
GitHub Repository: explore-for-students/python-tutorials
Path: blob/main/Group exercises/Group Exercise 4.ipynb
968 views
Kernel: Python 3 (ipykernel)

Cosmology of an Accelerating Universe

Introductory background: Supernovae, Dark Energy, and the Accelerating Universe

References: For more information about the dataset used in this exercise, see the following.

Background

In this exercise, you will use data from supernovae to constrain the cosmology of the Universe. For each supernova, the main observables are:

  • Redshift zz, which tells the supernova's relative velocity to us.

  • The supernova light curve, i.e., how bright it is as a function of time. Type Ia supernova appear to be "standard candles" so that by measuring their brightness, one can infer how far away they are.

Analyzing the relationship between redshift vs distance, one can gain an understanding of the expansion of the Universe, which in turn is related to the amount of matter and dark energy, according to the following formula

dL(z)=dH(1+z)0zdzΩm(1+z)3+ΩΛ  ,(1)d_L(z) = d_H \, (1+z) \int_0^z \frac{dz^\prime}{\sqrt{\Omega_m (1+z^\prime)^3 + \Omega_\Lambda}} \; , \qquad (1)

where dLd_L is a measure of distance (luminosity distance), dHd_H is constant known as the Hubble length, Ωm\Omega_m and ΩΛ\Omega_\Lambda are the total fractions of matter and dark energy, respectively. Eq. (1) assumes that the Universe has a flat spatial geometry (inferred from observations of the cosmic microwave background), so we assume that ΩΛ=1Ωm\Omega_\Lambda = 1 - \Omega_m. The Hubble distance is related to the famous Hubble constant H0H_0 by

dH=cH03×109  parsecs×h1d_H = \frac{c}{H_0} \approx 3 \times 10^9 \; {\rm parsecs} \times h^{-1}

where cc is the speed of light. It is customary to parametrize H0H_0 in terms of a parameter hh, which is known to be around 0.7.

Hubble's analysis in 1929 considered Cepheid variable stars (another standard candle) in nearby galaxies, z0z \approx 0. In this limit

dL(z)dHz(2).d_L(z) \approx d_H z \qquad (2) \, .

Eq. (2) can be rearranged as

H0dLczv,H_0 d_L \approx c z \approx v \, ,

where vv is velocity (along the line of sight). Thus, vdLv \propto d_L and the constant of proportionality H0H_0 is named in honor of Hubble (although it was first determined by Lemaitre, whose similar work predated Hubble's by two years).

For distant objects, such as supernovae, dLd_L is given by a more complicated function in Eq. (1) and one can extract more information than just H0H_0. The goal of this Exercise is to determine ΩΛ\Omega_\Lambda, showing that dark energy does indeed exist by finding that ΩΛ>0\Omega_\Lambda > 0.

We will use the supernova dataset provided by Suzuki et al. (2011). The code below loads the dataset as a pandas dataframe. The columns provided are:

  • Name of the supernova ('name')

  • Redshift 'z'

  • Distance modulus ('mu')

  • Error on the distance modulus ('mu_err')

  • Last column is not important for this analysis

The distance modulus μ\mu is a way to express distance that is commonly used in astronomy. It is related to dLd_L by the formula

dL=(10  parsecs)×10μ/5.d_L = (10 \; {\rm parsecs}) \times 10^{\mu/5} \, .
import pandas as pd import numpy as np import matplotlib.pyplot as plt url = "https://supernova.lbl.gov/Union/figures/SCPUnion2.1_mu_vs_z.txt" data = pd.read_csv(url, header=None, skiprows=5, sep='\t', names=['name','z','mu','mu_err','NA'])

Part I: Plotting the data

It is always a good idea to look at your data before you try any analysis. Make an error bar plot of μ\mu as a function of zz. Use a log scale on the x-axis (and a linear scale on the y-axis).

On the same plot, plot Hubble's Law given in Eq. (2). (You will need to express Hubble's Law in terms of μ\mu.) Take h=0.738h=0.738, which comes from a recent analysis of Cepheid variable stars.

Include labels and a legend for your plot.

# Your code here

Part II: Calculate the distance

Create an array of redshifts according to the following:

z_grid = np.linspace(min(data['z']),max(data['z']))

For Ωm=0.3\Omega_m = 0.3, calculate an array distance moduli μ(z)\mu(z) for each zz in z_grid. Using your arrays for μ\mu and zz, create an interpolating function mu_interp as a function of zz.

Repeat your previous plot from Part I with an additional curve:

z = np.linspace(min(data['z']),max(data['z']),num=1000) plt.plot(z,mu_interp(z))

(Note: z has more points than z_grid so that the interpolation is actually doing something other than returning your original grid.)

# Your code here

Part III: Dark energy

Generalize your result from Part II as follows. Create a function chi_sq(Omega_Lambda) that takes ΩΛ\Omega_\Lambda as an input and does the following:

  • Sets Ωm=1ΩΛ\Omega_m = 1 - \Omega_\Lambda

  • Generates an interpolating function mu_interp(z), as in Part II.

  • Calculates the χ2\chi^2 χ2=i(μinterp(zi)μiδi)2\chi^2 = \sum_i \left(\frac{\mu_{\rm interp}(z_i) - \mu_i}{\delta_i}\right)^2 where the sum runs over the data points, labeled by ii, where ziz_i, μi\mu_i, δi\delta_i are the redshift, distance modulus, and error for each data point.

  • Make a grid in ΩΛ\Omega_\Lambda between [0,1] and (looping over your grid in ΩΛ\Omega_\Lambda), determine the χ2\chi^2 for each value of ΩΛ\Omega_\Lambda. Use your result to make a plot of χ2\chi^2 as a function of ΩΛ\Omega_\Lambda.

  • Determine the best-fitting value of ΩΛ\Omega_\Lambda, i.e., the value of ΩΛ\Omega_\Lambda that makes the χ2\chi^2 the smallest.

# Your code here