codexpast-exam-of-the-laser-science-and-quantum-information-processing-course-of-the-university-of-oxford2016-mode-locked-gaussian-pulses.py
past-exam-of-the-laser-science-and-quantum-information-processing-course-of-the-university-of-oxford/2016-mode-locked-gaussian-pulses.py
"""Original pulse-train illustration; tested with Python 3.14, NumPy 2.3.5,
Matplotlib 3.10.7. Run from the desired PNG output directory.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
def main():
plt.rcParams.update({"font.size": 12, "axes.spines.top": False,
"axes.spines.right": False, "figure.facecolor": "white"})
spacing = 1.0
period = 2 * np.pi / spacing
delta = 8 * spacing
omega_ce = 0.15 * spacing
omega0 = 24.15 * spacing
phases = -np.arange(3) * omega_ce * period
blue, orange = "#126782", "#b55d15"
fig = plt.figure(figsize=(11.4, 7.2))
grid = fig.add_gridspec(2, 3, height_ratios=(1.05, 1), hspace=0.65)
train = fig.add_subplot(grid[0, :])
time = np.linspace(-0.3, 2.3, 16000)
field = np.zeros_like(time)
upper = np.zeros_like(time)
for j, phase in enumerate(phases):
tau = (time - j) * period
envelope = np.exp(-(delta * tau / 2) ** 2)
field += envelope * np.cos(omega0 * tau - phase)
upper += envelope
train.plot(time, field, color=blue, lw=1.3, label="Real electric field")
train.plot(time, upper, color=orange, lw=1.5, ls="--", label=r"Envelope $\pm A$")
train.plot(time, -upper, color=orange, lw=1.5, ls="--")
train.axhline(0, color="#c7ccd0", lw=0.6, zorder=0)
for j, label in enumerate((r"$\phi_0=0$", r"$\phi_1=-0.3\pi$", r"$\phi_2=-0.6\pi$")):
train.text(j, 1.15, label, ha="center", fontsize=13)
train.axvline(j, color="#c7ccd0", ls=":", lw=0.7, zorder=0)
for start in (0, 1):
train.annotate("", (start, 1.65), (start + 1, 1.65),
arrowprops={"arrowstyle": "<->", "color": "#38434d"})
train.text(start + 0.5, 1.72, r"$T=2\pi/\Delta\Omega$", ha="center")
train.set(xlim=(-0.3, 2.3), ylim=(-1.2, 2.05), xticks=(0, 1, 2),
yticks=(-1, 0, 1), xlabel=r"Time $t/T$", ylabel="Normalized field")
train.legend(loc="upper center", bbox_to_anchor=(0.5, -0.28),
ncol=2, frameon=False, fontsize=10)
local = np.linspace(-0.115, 0.115, 1600)
tau = local * period
envelope = np.exp(-(delta * tau / 2) ** 2)
for j, phase in enumerate(phases):
ax = fig.add_subplot(grid[1, j])
ax.plot(local, envelope * np.cos(omega0 * tau - phase), color=blue, lw=1.8)
ax.plot(local, envelope, color=orange, ls="--", lw=1.4)
ax.plot(local, -envelope, color=orange, ls="--", lw=1.4)
ax.axvline(0, color="#9aa3aa", lw=0.8, ls=":")
ax.axhline(0, color="#c7ccd0", lw=0.6)
ax.scatter([0], [np.cos(phase)], color=blue, s=30, zorder=4)
ax.set(xlim=(-0.115, 0.115), ylim=(-1.15, 1.15),
xticks=(-0.1, 0, 0.1), yticks=(-1, 0, 1),
xlabel=r"Local time $\tau/T=(t-jT)/T$",
title=rf"Pulse $j={j}$: $\phi_j={phase / np.pi:.1f}\pi$")
if j == 0:
ax.set_ylabel("Normalized field")
fig.suptitle("Mode locking: identical envelopes, advancing carrier phase", fontsize=17, y=0.98)
fig.text(0.5, 0.055,
r"$E_j(\tau)=A(\tau)e^{-i\omega_0\tau+i\phi_j}$, "
r"$A(\tau)=e^{-(\delta\tau/2)^2}$, "
r"$\phi_j=\phi_0-j\omega_{\rm ce}T$", ha="center", fontsize=13)
fig.text(0.5, 0.018,
r"$\omega_{\rm ce}=0.15\Delta\Omega$, $\delta=8\Delta\Omega$, "
r"$\omega_0=24.15\Delta\Omega$; phase step $=-0.3\pi$ per pulse.",
ha="center", fontsize=11)
fig.subplots_adjust(left=0.075, right=0.975, bottom=0.19, top=0.9, wspace=0.28)
fig.savefig(Path.cwd() / Path(__file__).with_suffix(".png").name,
dpi=140, facecolor="white", transparent=False,
metadata={"Software": "Matplotlib"})
plt.close(fig)
if __name__ == "__main__":
main()