codex/ratiometric-resistance-excitation.py

ratiometric-resistance-excitation.py
"""Original ideal resistance-ratio calculation; outputs a white PNG in cwd."""
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt


def main():
    current = np.linspace(0.8, 1.2, 201)  # mA
    resistance, reference = 100.0, 2000.0
    sensor_v = current * 1e-3 * resistance
    reference_v = current * 1e-3 * reference
    ratio = sensor_v / reference_v
    np.testing.assert_allclose(ratio, 0.05)
    np.testing.assert_allclose(reference * ratio, resistance)
    np.testing.assert_allclose(sensor_v[[0, -1]] / 1e-3, [80, 120])
    assert np.isclose(100 / 1.001, 99.9000999001)
    assert np.isclose(1e-3 ** 2 * 100, 1e-4)
    fig, axes = plt.subplots(1, 2, figsize=(10, 4.2), dpi=100, facecolor='white')
    axes[0].plot(current, sensor_v / 0.1, lw=5, color='#2475ad', label='Sensor voltage / 0.1 V')
    axes[0].plot(current, reference_v / 2, lw=2, ls='--', color='#e58927', label='Reference voltage / 2 V')
    axes[0].set(ylabel='Voltage / nominal voltage', title='Same multiplicative current variation')
    axes[0].legend(fontsize=9)
    axes[1].plot(current, reference * ratio, lw=2.5, label='Shared-current reference', color='#2475ad')
    axes[1].plot(current, sensor_v / 1e-3, lw=2.5, label='Fixed independent reference', color='#e58927')
    axes[1].set(ylabel='Inferred resistance (Ω)', title='Shared excitation cancels in the ratio')
    axes[1].legend(fontsize=9, loc='upper left')
    for ax in axes:
        ax.set_xlabel('Excitation current (mA)')
        ax.grid(alpha=0.25)
    fig.suptitle('Ideal 100 Ω sensor and 2000 Ω reference · constructed calculation', fontsize=12)
    fig.tight_layout(rect=(0, 0, 1, 0.94))
    fig.savefig(Path.cwd() / (Path(__file__).stem + '.png'), facecolor='white')
    plt.close(fig)


if __name__ == '__main__':
    main()