{ "cells": [ { "cell_type": "markdown", "id": "intro", "metadata": {}, "source": [ "# Two-Level: Two-Pulse Photon Echo\n", "\n", "In an inhomogeneously broadened two-level medium a pair of short pulses\n", "can generate a coherent burst — the **photon echo** — at time $t = +\\tau$\n", "after the second pulse, where $\\tau$ is the separation between the two pulses.\n", "\n", "## Physical mechanism\n", "\n", "1. **π/2 pulse** (at $t = -\\tau$): places all atoms in an equal superposition\n", " of ground and excited state. Each atom begins precessing at its own\n", " transition frequency $\\omega_j$ (set by its Doppler shift).\n", "\n", "2. **Free precession** ($-\\tau < t < 0$): atoms accumulate different phases\n", " $\\phi_j = \\omega_j \\tau$. The macroscopic polarisation\n", " $P \\propto \\sum_j \\rho_{10}^{(j)}$ rapidly *dephases* — the\n", " free-induction decay (FID).\n", "\n", "3. **π pulse** (at $t = 0$): inverts every Bloch vector, reversing the\n", " sense of accumulated phase: $\\phi_j \\to -\\phi_j$.\n", "\n", "4. **Rephasing** ($0 < t < \\tau$): atoms continue precessing in the same\n", " direction. Because the sign of the phase offset was flipped, after\n", " a further $\\tau$ all phase differences cancel simultaneously, giving a\n", " macroscopic polarisation revival — the **photon echo** at $t = +\\tau$.\n", "\n", "The echo amplitude decays as $e^{-2\\tau/T_2}$ where $T_2$ is the\n", "homogeneous coherence time.\n", "\n", "## Hard-pulse condition\n", "\n", "For the echo to form correctly every velocity class must be rotated by\n", "exactly π/2 (or π), regardless of its Doppler detuning. This requires\n", "\n", "$$\\Omega_{\\rm peak} \\gg \\Delta_{\\rm Doppler}$$\n", "\n", "i.e. the pulse must be short and strong enough that the detuning has\n", "negligible effect during the pulse. Here we use $T = 0.025\\,\\gamma^{-1}$,\n", "giving $\\Omega_{\\rm peak}^{(\\pi/2)} = 10\\,{\\rm rad}\\,\\gamma$ and\n", "$\\Omega_{\\rm peak}^{(\\pi)} = 20\\,{\\rm rad}\\,\\gamma$.\n", "The Gaussian Doppler distribution has $\\sigma \\approx 4.2\\,{\\rm rad}\\,\\gamma$\n", "(from `thermal_width = 0.15`; the solver convention is that the\n", "Hamiltonian detuning is $4\\pi^2 \\times$ the `thermal_delta` user value,\n", "so `thermal_width = 0.15` maps to $\\sigma \\approx 4.2\\,{\\rm rad}\\,\\gamma$).\n", "This gives $\\Omega_{\\rm peak}^{(\\pi/2)}/\\sigma \\approx 2.4$, satisfying\n", "the hard-pulse condition for all significantly-weighted velocity classes.\n", "\n", "## Level structure\n", "\n", "```\n", " |1⟩ ════════════════ (excited)\n", " │ decay rate 0.1 → T₂ ≈ 3.18 γ⁻¹\n", " Ω │ π/2 and π sech pulses (hard-pulse limit)\n", " │\n", " |0⟩ ════════════════ (ground)\n", "```\n", "\n", "Inhomogeneous broadening: Gaussian Doppler distribution,\n", "$\\sigma \\approx 4.2\\,{\\rm rad}\\,\\gamma$ (wider than the homogeneous\n", "linewidth $\\Gamma = 2\\pi \\times {\\rm rate} \\approx 0.63\\,\\gamma$, narrower\n", "than the pulse bandwidth $\\sim 1/T = 40\\,\\gamma$).\n", "\n", "## Parameters\n", "\n", "| Quantity | Value | Notes |\n", "|---|---|---|\n", "| Decay `rate` | $0.1$ | $\\Gamma = 2\\pi\\times0.1 \\approx 0.63\\,{\\rm rad}\\,\\gamma$; $T_2 = 2/\\Gamma \\approx 3.18\\,\\gamma^{-1}$ |\n", "| Doppler $\\sigma$ | $4.2\\,{\\rm rad}\\,\\gamma$ | 40 velocity classes over $\\pm 0.75$ (user units) |\n", "| Pulse delay | $\\tau = 1.0\\,\\gamma^{-1}$ | echo at $t = +\\tau = +1.0\\,\\gamma^{-1}$ |\n", "| Pulse width | $T = 0.025\\,\\gamma^{-1}$ | hard-pulse: $\\Omega_{\\rm peak}^{(\\pi/2)} = 10$, $\\Omega_{\\rm peak}^{(\\pi)} = 20\\,{\\rm rad}\\,\\gamma$ |\n", "| Echo amplitude | $e^{-2/3.18} \\approx 53\\%$ | $T_2$ decay at $\\tau = 1.0\\,\\gamma^{-1}$ |" ] }, { "cell_type": "code", "execution_count": 1, "id": "imports", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:24:47.155807Z", "iopub.status.busy": "2026-04-27T07:24:47.155684Z", "iopub.status.idle": "2026-04-27T07:24:47.989746Z", "shell.execute_reply": "2026-04-27T07:24:47.989181Z" } }, "outputs": [], "source": [ "import numpy as np\n", "import plotly.graph_objects as go\n", "from maxwellbloch import mb_solve, plot\n", "from maxwellbloch.plot import theme # register Plotly template" ] }, { "cell_type": "code", "execution_count": 2, "id": "solve-main", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:24:47.991479Z", "iopub.status.busy": "2026-04-27T07:24:47.991242Z", "iopub.status.idle": "2026-04-27T07:25:05.106168Z", "shell.execute_reply": "2026-04-27T07:25:05.105553Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/tpo/repos/maxwellbloch/.venv/lib/python3.14/site-packages/qutip/solver/solver_base.py:598: FutureWarning: e_ops will be keyword only from qutip 5.3 for all solver\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 2/20 (10%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 4/20 (20%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 6/20 (30%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 8/20 (40%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 10/20 (50%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 12/20 (60%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 14/20 (70%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 16/20 (80%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 18/20 (90%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Saving MBSolve to mbs-two-photon-echo.qu\n", "Done\n" ] } ], "source": [ "tau = 1.0 # delay: π/2 at t=-τ, π at t=0, echo at t=+τ\n", "T = 0.025 # sech half-width — short hard pulses, Ω_peak >> Δ_Doppler\n", "\n", "mb_solve_json = f\"\"\"\n", "{{\n", " \"atom\": {{\n", " \"num_states\": 2,\n", " \"decays\": [\n", " {{\"channels\": [[0, 1]], \"rate\": 0.1}}\n", " ],\n", " \"fields\": [\n", " {{\n", " \"label\": \"pi_half\",\n", " \"coupled_levels\": [[0, 1]],\n", " \"rabi_freq\": 1.0,\n", " \"rabi_freq_t_func\": \"sech\",\n", " \"rabi_freq_t_args\": {{\"n_pi\": 0.5, \"centre\": {-tau}, \"width\": {T}}}\n", " }},\n", " {{\n", " \"label\": \"pi\",\n", " \"coupled_levels\": [[0, 1]],\n", " \"rabi_freq\": 1.0,\n", " \"rabi_freq_t_func\": \"sech\",\n", " \"rabi_freq_t_args\": {{\"n_pi\": 1.0, \"centre\": 0.0, \"width\": {T}}}\n", " }}\n", " ]\n", " }},\n", " \"t_min\": -2.5,\n", " \"t_max\": 2.0,\n", " \"t_steps\": 900,\n", " \"z_min\": 0.0,\n", " \"z_max\": 1.0,\n", " \"z_steps\": 20,\n", " \"z_steps_inner\": 2,\n", " \"interaction_strengths\": [1.0, 1.0],\n", " \"velocity_classes\": {{\n", " \"thermal_width\": 0.15,\n", " \"thermal_delta_min\": -0.75,\n", " \"thermal_delta_max\": 0.75,\n", " \"thermal_delta_steps\": 40\n", " }},\n", " \"savefile\": \"mbs-two-photon-echo\"\n", "}}\n", "\"\"\"\n", "\n", "mbs = mb_solve.MBSolve().from_json_str(mb_solve_json)\n", "mbs.mbsolve(recalc=True)\n", "print(\"Done\")" ] }, { "cell_type": "markdown", "id": "output-section", "metadata": {}, "source": [ "## Output field: photon echo at $t = +\\tau$\n", "\n", "The total transmitted field\n", "$|\\Omega_{\\pi/2}(z_{\\rm max},t)| + |\\Omega_{\\pi}(z_{\\rm max},t)|$\n", "shows three features: the transmitted π/2 pulse (attenuated by Beer-Lambert\n", "absorption), the transmitted π pulse, and the **photon echo** at $t = +\\tau$." ] }, { "cell_type": "code", "execution_count": 3, "id": "plot-output-field", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:25:05.107734Z", "iopub.status.busy": "2026-04-27T07:25:05.107640Z", "iopub.status.idle": "2026-04-27T07:25:05.807336Z", "shell.execute_reply": "2026-04-27T07:25:05.806856Z" } }, "outputs": [ { "data": { "text/html": [ " \n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "t = mbs.tlist\n", "Omega_out = np.abs(mbs.Omegas_zt[0, -1, :]) + np.abs(mbs.Omegas_zt[1, -1, :])\n", "Omega_in = np.abs(mbs.Omegas_zt[0, 0, :]) + np.abs(mbs.Omegas_zt[1, 0, :])\n", "\n", "fig = go.Figure(layout=go.Layout(\n", " title=\"Photon echo: transmitted field at z = z_max\",\n", " xaxis_title=\"time (γ⁻¹)\",\n", " yaxis_title=\"|Ω| (γ)\",\n", " template=\"maxwellbloch\",\n", "))\n", "fig.add_trace(go.Scatter(x=t, y=Omega_in, name=\"input (z = 0)\", line=dict(dash=\"dot\")))\n", "fig.add_trace(go.Scatter(x=t, y=Omega_out, name=\"output (z = z_max)\"))\n", "fig.add_vline(x=-tau, line_dash=\"dash\", line_color=\"grey\",\n", " annotation_text=\"π/2\", annotation_position=\"top right\")\n", "fig.add_vline(x=0, line_dash=\"dash\", line_color=\"grey\",\n", " annotation_text=\"π\", annotation_position=\"top right\")\n", "fig.add_vline(x=tau, line_dash=\"dash\", line_color=\"red\",\n", " annotation_text=\"echo\", annotation_position=\"top right\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "coherence-section", "metadata": {}, "source": [ "## Macroscopic polarisation: dephasing and rephasing\n", "\n", "$\\mathrm{Im}[\\rho_{10}(z=0,t)]$ is the velocity-class-averaged polarisation.\n", "After the π/2 pulse it decays on the Doppler timescale\n", "$1/\\sigma \\approx 0.24\\,\\gamma^{-1}$ (FID). The polarisation is essentially\n", "zero by $t = 0$ (before the π pulse). After the π pulse it revives at\n", "$t = +\\tau$: the echo." ] }, { "cell_type": "code", "execution_count": 4, "id": "plot-coherence", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:25:05.808707Z", "iopub.status.busy": "2026-04-27T07:25:05.808542Z", "iopub.status.idle": "2026-04-27T07:25:05.833291Z", "shell.execute_reply": "2026-04-27T07:25:05.832779Z" } }, "outputs": [ { "data": { "text/html": [ " \n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plot.coherence(mbs, i=1, j=0, z_idx=0, component=\"imag\")\n", "fig.update_layout(\n", " title=\"Im[ρ₁₀(t)] at z = 0 — free-induction decay and rephasing\"\n", ")\n", "fig.add_vline(x=-tau, line_dash=\"dash\", line_color=\"grey\",\n", " annotation_text=\"π/2\", annotation_position=\"top right\")\n", "fig.add_vline(x=0, line_dash=\"dash\", line_color=\"grey\",\n", " annotation_text=\"π\", annotation_position=\"top right\")\n", "fig.add_vline(x=tau, line_dash=\"dash\", line_color=\"red\",\n", " annotation_text=\"echo\", annotation_position=\"top right\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "spacetime-section", "metadata": {}, "source": [ "## Spacetime: π/2 pulse and echo buildup\n", "\n", "The space-time plot of the π/2 field shows the input pulse propagating through\n", "the medium and being absorbed. At $t = +\\tau$ the rephasing polarisation drives\n", "the echo field, which grows from $z = 0$ towards $z_{\\rm max}$ as each\n", "successive slice adds to the coherent emission." ] }, { "cell_type": "code", "execution_count": 5, "id": "plot-spacetime", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:25:05.834767Z", "iopub.status.busy": "2026-04-27T07:25:05.834675Z", "iopub.status.idle": "2026-04-27T07:25:05.857101Z", "shell.execute_reply": "2026-04-27T07:25:05.856440Z" } }, "outputs": [ { "data": { "text/html": [ " \n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plot.field_spacetime(mbs, field_idx=0)\n", "fig.update_layout(title=\"|Ω_{π/2}(z, t)| — input pulse and photon echo\")\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "delay-section", "metadata": {}, "source": [ "## Echo amplitude vs delay: $T_2$ measurement\n", "\n", "Running the simulation for several delays $\\tau$ shows the exponential\n", "decay of the echo amplitude measured from $\\mathrm{Im}[\\rho_{10}(z=0,t)]$:\n", "\n", "$$\n", "A_{\\rm echo}(\\tau) \\propto e^{-2\\tau/T_2}, \\qquad\n", "T_2 = \\frac{2}{\\Gamma} = \\frac{2}{2\\pi\\times{\\rm rate}} \\approx 3.18\\,\\gamma^{-1}\n", "$$\n", "\n", "This allows $T_2$ to be extracted even when the absorption lineshape is\n", "completely dominated by inhomogeneous (Doppler) broadening." ] }, { "cell_type": "code", "execution_count": 6, "id": "echo-decay", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:25:05.858409Z", "iopub.status.busy": "2026-04-27T07:25:05.858331Z", "iopub.status.idle": "2026-04-27T07:26:02.524179Z", "shell.execute_reply": "2026-04-27T07:26:02.523644Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/tpo/repos/maxwellbloch/.venv/lib/python3.14/site-packages/qutip/solver/solver_base.py:598: FutureWarning: e_ops will be keyword only from qutip 5.3 for all solver\n", " warnings.warn(\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 2/20 (10%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 4/20 (20%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 6/20 (30%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 8/20 (40%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 10/20 (50%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 12/20 (60%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 14/20 (70%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 16/20 (80%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 18/20 (90%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Saving MBSolve to mbs-two-photon-echo-tau0.5.qu\n", "τ = 0.50 γ⁻¹ — echo Im[ρ₁₀]: 0.3284\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 2/20 (10%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 4/20 (20%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 6/20 (30%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 8/20 (40%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 10/20 (50%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 12/20 (60%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 14/20 (70%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 16/20 (80%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 18/20 (90%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Saving MBSolve to mbs-two-photon-echo-tau0.75.qu\n", "τ = 0.75 γ⁻¹ — echo Im[ρ₁₀]: 0.2813\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 2/20 (10%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 4/20 (20%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 6/20 (30%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 8/20 (40%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 10/20 (50%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 12/20 (60%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 14/20 (70%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 16/20 (80%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 18/20 (90%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Saving MBSolve to mbs-two-photon-echo-tau1.0.qu\n", "τ = 1.00 γ⁻¹ — echo Im[ρ₁₀]: 0.2326\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 2/20 (10%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 4/20 (20%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 6/20 (30%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 8/20 (40%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 10/20 (50%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 12/20 (60%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 14/20 (70%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 16/20 (80%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 18/20 (90%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Saving MBSolve to mbs-two-photon-echo-tau1.25.qu\n", "τ = 1.25 γ⁻¹ — echo Im[ρ₁₀]: 0.2015\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 2/20 (10%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 4/20 (20%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 6/20 (30%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 8/20 (40%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 10/20 (50%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 12/20 (60%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 14/20 (70%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 16/20 (80%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ " z-step 18/20 (90%)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Saving MBSolve to mbs-two-photon-echo-tau1.5.qu\n", "τ = 1.50 γ⁻¹ — echo Im[ρ₁₀]: 0.1756\n" ] } ], "source": [ "import math\n", "\n", "T = 0.025\n", "rate = 0.1\n", "T2 = 2.0 / (2 * math.pi * rate) # ≈ 3.18 γ⁻¹\n", "\n", "tau_values = [0.5, 0.75, 1.0, 1.25, 1.5]\n", "echo_amps = []\n", "\n", "for tau_val in tau_values:\n", " j = f\"\"\"\n", "{{\n", " \"atom\": {{\n", " \"num_states\": 2,\n", " \"decays\": [{{\"channels\": [[0, 1]], \"rate\": {rate}}}],\n", " \"fields\": [\n", " {{\"label\":\"pi_half\",\"coupled_levels\":[[0,1]],\"rabi_freq\":1.0,\n", " \"rabi_freq_t_func\":\"sech\",\n", " \"rabi_freq_t_args\":{{\"n_pi\":0.5,\"centre\":{-tau_val},\"width\":{T}}}}},\n", " {{\"label\":\"pi\",\"coupled_levels\":[[0,1]],\"rabi_freq\":1.0,\n", " \"rabi_freq_t_func\":\"sech\",\n", " \"rabi_freq_t_args\":{{\"n_pi\":1.0,\"centre\":0.0,\"width\":{T}}}}}\n", " ]\n", " }},\n", " \"t_min\": {-(tau_val + 1.5)},\n", " \"t_max\": {tau_val + 1.0},\n", " \"t_steps\": 500,\n", " \"z_min\": 0.0, \"z_max\": 1.0, \"z_steps\": 20, \"z_steps_inner\": 2,\n", " \"interaction_strengths\": [1.0, 1.0],\n", " \"velocity_classes\": {{\n", " \"thermal_width\": 0.15,\n", " \"thermal_delta_min\": -0.75,\n", " \"thermal_delta_max\": 0.75,\n", " \"thermal_delta_steps\": 40\n", " }},\n", " \"savefile\": \"mbs-two-photon-echo-tau{tau_val}\"\n", "}}\n", "\"\"\"\n", " m = mb_solve.MBSolve().from_json_str(j)\n", " m.mbsolve(recalc=True)\n", " t_arr = m.tlist\n", " # Echo amplitude from Im[ρ₁₀] at z=0 in a window around t=+τ\n", " rho10 = m.states_zt[0, :, 1, 0]\n", " mask = (t_arr > tau_val - 5*T) & (t_arr < tau_val + 5*T)\n", " echo_amp = float(rho10[mask].imag.max()) if mask.any() else 0.0\n", " echo_amps.append(echo_amp)\n", " print(f\"τ = {tau_val:.2f} γ⁻¹ — echo Im[ρ₁₀]: {echo_amp:.4f}\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "plot-echo-decay", "metadata": { "execution": { "iopub.execute_input": "2026-04-27T07:26:02.525395Z", "iopub.status.busy": "2026-04-27T07:26:02.525314Z", "iopub.status.idle": "2026-04-27T07:26:02.542656Z", "shell.execute_reply": "2026-04-27T07:26:02.542184Z" } }, "outputs": [ { "data": { "text/html": [ " \n", " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "tau_arr = np.array(tau_values)\n", "\n", "fig = go.Figure(layout=go.Layout(\n", " title=f\"Echo amplitude vs delay τ — T₂ measurement (T₂ = {T2:.2f} γ⁻¹)\",\n", " xaxis_title=\"τ (γ⁻¹)\",\n", " yaxis_title=\"Im[ρ₁₀] echo amplitude\",\n", " template=\"maxwellbloch\",\n", "))\n", "fig.add_trace(go.Scatter(\n", " x=tau_arr, y=echo_amps, mode=\"markers+lines\", name=\"simulation\"\n", "))\n", "# Analytic fit normalised to first data point\n", "t_fine = np.linspace(tau_arr[0], tau_arr[-1], 100)\n", "analytic = echo_amps[0] * np.exp(-(t_fine - tau_arr[0]) * 2 / T2)\n", "fig.add_trace(go.Scatter(\n", " x=t_fine, y=analytic, mode=\"lines\",\n", " name=f\"e^(−2τ/T₂), T₂ = {T2:.2f} γ⁻¹\", line=dict(dash=\"dash\")\n", "))\n", "fig.show(renderer='notebook_connected')" ] }, { "cell_type": "markdown", "id": "summary", "metadata": {}, "source": [ "## Summary\n", "\n", "- **π/2 pulse** creates superposition; the macroscopic polarisation\n", " free-induction decays on the Doppler timescale $1/\\sigma$.\n", "- **π pulse** reverses all accumulated phases — each atom's precession\n", " direction is effectively time-reversed.\n", "- **Photon echo** at $t = +\\tau$: all velocity classes rephase\n", " simultaneously and the medium emits a coherent echo pulse.\n", "- The echo amplitude $\\propto e^{-2\\tau/T_2}$ gives a direct measurement\n", " of the **homogeneous** coherence time $T_2$ in a medium dominated by\n", " inhomogeneous (Doppler) broadening.\n", "\n", "Photon echoes are the time-domain counterpart of spin echoes in NMR and\n", "are used to characterise quantum memories, cold-atom ensembles, and\n", "rare-earth-doped crystals.\n", "\n", "## References\n", "\n", "1. E. L. Hahn, *Spin Echoes*, Phys. Rev. **80**, 580 (1950).\n", " Original NMR spin echo.\n", "2. N. A. Kurnit, I. D. Abella, S. R. Hartmann, *Observation of a Photon\n", " Echo*, PRL **13**, 567 (1964). First optical photon echo.\n", "3. L. Allen, J. H. Eberly, *Optical Resonance and Two-Level Atoms*\n", " (Dover, 1987), Ch. 9. Bloch-vector derivation.\n", "4. M. O. Scully, M. S. Zubairy, *Quantum Optics* (Cambridge, 1997), Ch. 7." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.14.4" } }, "nbformat": 4, "nbformat_minor": 5 }