BPW34 optical sampling alias experiment

Requirements: Python 3.9 or later, standard library only.

Host demonstration with the two labeled synthetic captures:
  python3 optical_alias.py synthetic-open.csv synthetic-blocked.csv

Rerun the delivered CLI checks:
  python3 test_actual_program.py -v

For the unbuilt bench fixture, export simultaneous DRIVE and SENSE waveforms
from each frozen acquisition, then make normalized copies named open.csv and
blocked.csv. Preserve original sample order and every row. Remove vendor
metadata only, convert time to seconds and both voltage columns to volts,
and use the exact header time_s,drive_v,sense_v. Check units against the
scope screen. Retain an independent copy of each original scope export.

Leave the generator driving for both recordings. Block only the light path,
without moving the LED, detector, probe tips or cables. Use the same timebase
and depth. Inspect the traces for clipping and the bounds in the article.

  python3 optical_alias.py open.csv blocked.csv

Exit 0 prints a JSON report. Exit 2 rejects an incompatible capture and emits
the reason on standard error. The blocked-path metric is the larger
amplitude at the open detector peak and the predicted blocked-drive
frequency at that sample rate. Complete observations-blank.csv separately.
The program examines sampled values; it cannot verify wiring, bias, ground
references, light blocking, physical provenance or scope settings.

The two provided CSVs are generated models, not bench data. Their modeled
ambient term, higher harmonic and dark feedthrough are deliberate additions.
The editable SVGs and PNGs show the fixture and calculated sample positions.
