Hands-on: Unbinned maximum likelihood fit

A set of measurements is assumed to follow the normalized probability density function

$$ f(t) = r \frac{1}{\tau_1} \exp(-t/\tau_1) + (1-r) \frac{1}{\tau_2} \exp(-t/\tau_2)$$

where $t \ge 0$. The variable $r$ with $0 \le r \le 1$ defines the relative contribution of the two components with decay times $\tau_1$ and $\tau_2$, respectively. The data are read from the file double_exp_data.npy below.

Determine the parameters $r$, $\tau_1$, and $\tau_2$ from an unbinned maximum likelihood fit.

In [3]:
import numpy as np
import matplotlib.pyplot as plt
from iminuit import Minuit
In [4]:
# read data
x = np.load("../data/double_exp_data.npy")
In [5]:
# plot data
plt.yscale('log')
plt.hist(x, bins=1000, density=True, histtype='step');
In [6]:
# define probability density function
def f(t, tau1, tau2, r):
    c1 = 1./tau1 * np.exp(-t/tau1)
    c2 = 1./tau2 * np.exp(-t/tau2)
    return r * c1 + (1-r) * c2

a) Define a function that calculates the negative log likelihood

In [7]:
# your code here

# def negative_log_likelihood(tau1, tau2, r):
# ...

b) Define an iminuit object and perform the unbinned maximum likelihood fit

In [10]:
# your code here
# m = Minuit(negative_log_likelihood, ...)

c) Plot the total probability density function along with individual components on top of the data

In [9]:
# your code here
plt.hist(x, bins=1000, density=True, histtype='step');

plt.xlim(0., 100.)
plt.ylim(0.0001, 0.1)
plt.yscale('log')

# your code here

# tau1 = m.values['tau1']
# tau2 = m.values['tau2']
# r = m.values['r']
# ...