codex/heterodyne-gain-cancellation.py

heterodyne-gain-cancellation.py
"""Deterministic readout-scale effects on a normalized heterodyne amplitude."""
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np


def main():
    beat, arm1, arm2 = 6.0, 2.0, 8.0
    scale = np.linspace(.8, 1.2, 201)
    nominal = beat/(2*np.sqrt(arm1*arm2))
    shared = scale*beat/(2*np.sqrt(scale*arm1*scale*arm2))
    separate = scale*beat/(2*np.sqrt(arm1*arm2))
    mismatch = scale*beat/(2*np.sqrt(scale**.95*arm1*scale**.95*arm2))
    assert np.allclose(shared, nominal)
    assert np.allclose(mismatch, nominal*scale**.05)
    v_d = (.05*.03)**2 + .01**2 + 2*(.5*.004)**2
    assert np.isclose(np.sqrt(v_d), .0105)
    assert np.isclose(nominal*np.exp(v_d/2), .750041344889558)
    fig, ax = plt.subplots(figsize=(7.4, 3.7), dpi=100, layout="constrained")
    fig.set_facecolor("white")
    ax.plot(scale, separate, color="#b94b16", lw=2, label="Scale only the beat reading")
    ax.plot(scale, mismatch, "--", color="#4c8b23", lw=2,
            label="Beat sensitivity 1; arm sensitivities 0.95")
    ax.plot(scale, shared, color="#1558a0", lw=2,
            label="Exactly shared scale: complete cancellation")
    ax.scatter([1], [nominal], color="#1558a0", zorder=4)
    ax.set(xlabel="Positive readout scale g", ylabel="Normalized beat amplitude",
           title="A ratio cancels shared scaling, not every calibration error",
           xlim=(.8, 1.2), ylim=(.57, .93))
    ax.legend(loc="upper left", fontsize=9)
    ax.grid(alpha=.2)
    fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white")
    plt.close(fig)


if __name__ == "__main__":
    main()