codex/rna-relaxation-instrument-response.py

rna-relaxation-instrument-response.py
"""Original causal-response illustration. Tested with Python 3.14.4, NumPy 2.3.5,
Matplotlib 3.10.7. Run from _media; writes the PNG to the current directory.
"""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

molecular_time = 10.0  # microseconds
instrument_time = 5.0
sample_time = np.linspace(0, 60, 1201)
ideal = np.exp(-sample_time / molecular_time)
measured = molecular_time / (molecular_time - instrument_time) * (
    ideal - np.exp(-sample_time / instrument_time)
)
peak_time = molecular_time * instrument_time / (
    molecular_time - instrument_time
) * np.log(molecular_time / instrument_time)
peak_signal = molecular_time / (molecular_time - instrument_time) * (
    np.exp(-peak_time / molecular_time) - np.exp(-peak_time / instrument_time)
)
with plt.rc_context({'font.size': 11, 'axes.spines.top': False,
                     'axes.spines.right': False, 'savefig.facecolor': 'white'}):
    figure, axes = plt.subplots(figsize=(8, 4.5), dpi=100, facecolor='white')
    axes.set_facecolor('white')
    axes.plot(sample_time, ideal, color='#0072B2', linestyle='--', linewidth=2.1,
              label='Molecular signal: exponential decay')
    axes.plot(sample_time, measured, color='#D55E00', linewidth=2.5,
              label='Signal after detector response')
    axes.scatter([peak_time], [peak_signal], color='#D55E00', s=28, zorder=4)
    axes.annotate('Peak at 6.93 μs\nheight 0.50 A', (peak_time, peak_signal),
                  xytext=(17, .67), arrowprops={'arrowstyle': '->', 'color': '#555555'},
                  fontsize=10)
    axes.text(33, .58, 'Original model\nMolecular time: 10 μs\nDetector time: 5 μs\n\nMean arrival time:\n10 μs → 15 μs',
              fontsize=10, va='top', bbox={'facecolor': '#F5F5F5', 'edgecolor': '#DDDDDD', 'pad': 7})
    axes.set(xlim=(0, 60), ylim=(-.02, 1.06), xlabel='Time after excitation (μs)',
              ylabel='Signal / A', title='Detector response changes an RNA relaxation trace')
    axes.grid(alpha=.18)
    axes.legend(loc='upper right', frameon=False, fontsize=10)
    figure.tight_layout()
    figure.savefig(Path('rna-relaxation-instrument-response.png'), dpi=100)
    plt.close(figure)