Estimate noise model parameters#

Objects from thztools: noisefit, NoiseModel, NoiseModel.noise_amp, NoiseModel.noise_sim,scaleshift, timebase, wave.

[1]:
from matplotlib import pyplot as plt
import numpy as np

import thztools as thz

Set the simulation parameters#

[2]:
n = 256  # Number of samples
m = 50  # Number of simulated waveforms
dt = 0.05  # Sampling time [ps]

sigma_alpha = 1e-4  # Additive noise amplitude [signal units]
sigma_beta = 1e-2  # Multiplicative noise amplitude [dimensionless]
sigma_tau = 1e-3  # Time base noise amplitude [ps]

Simulate an input waveform#

[3]:
t = thz.timebase(n, dt=dt)
mu = thz.wave(n, dt=dt)

Simulate measurements#

Define amplitude drift parameters a and delay drift parameters eta, each with length m - 1. Use the numpy.repeat function to generate an array of m copies of mu, then use scaleshift to rescale and shift all but the first of them by the elements a and eta, respectively. Use the transpose operation to orient the array so that the waveforms are arranged columnwise.

Next, create an instance of the NoiseModel class and use the noise_sim method to add simulated noise to each waveform.

[4]:
rng = np.random.default_rng(0)
a = 1.0 + 1e-2 * rng.standard_normal(m - 1)
eta = 1e-3 * rng.standard_normal(m - 1)

z = thz.scaleshift(
    np.repeat(np.atleast_2d(mu), m, axis=0),
    dt=dt,
    a=np.insert(a, 0, 1.0),
    eta=np.insert(eta, 0, 0.0)
).T

noise_model = thz.NoiseModel(
    sigma_alpha=sigma_alpha,
    sigma_beta=sigma_beta,
    sigma_tau=sigma_tau,
    dt=dt
)
x = z + noise_model.noise_sim(z, axis=0, seed=12345)

Fit a noise model to the simulated measurements#

[5]:
noise_res = thz.noisefit(
    x,
    sigma_alpha0=sigma_alpha,
    sigma_beta0=sigma_beta,
    sigma_tau0=sigma_tau,
    dt=dt
)
print(f"{noise_res.noise_model.sigma_alpha=}")
print(f"{noise_res.noise_model.sigma_beta=}")
print(f"{noise_res.noise_model.sigma_tau=}")
noise_res.noise_model.sigma_alpha=0.00010072985446306559
noise_res.noise_model.sigma_beta=0.009849777070777796
noise_res.noise_model.sigma_tau=0.0008994024169028506

Compare the fitted noise model with an empirical noise estimate#

Use the fitted values noise_res.a and noise_res.eta with scaleshift to correct for drift in x. Determine the standard deviation at each time point of the resulting x_corrected array. Compare this to the fitted noise model using the noise_amp method of noise_res.noise_model with noise_res.mu.

[6]:
x_corrected = thz.scaleshift(
    x, a=1 / noise_res.a, eta=-noise_res.eta, axis=0
)
plt.plot(t, np.std(x_corrected, axis=1), "-", label="Data")
plt.plot(t, noise_res.noise_model.noise_amp(noise_res.mu), "--", label="Fit")
plt.legend()
plt.xlabel("t (ps)")
plt.ylabel(r"$\sigma(t)$")
plt.show()
../_images/examples_estimate-noise_11_0.png