Skip to main content

parse_tof_sidecar_text

Function parse_tof_sidecar_text 

Source
pub fn parse_tof_sidecar_text(
    text: &str,
    n_frames: Option<usize>,
) -> Result<Vec<f64>, IoError>
Expand description

Parse VENUS *_Spectra.txt sidecar text into TOF bin edges (µs).

Format: CSV shutter_time,counts where column 0 is the frame start time in seconds — one row per TOF frame. Comment lines (#), blank lines, and a single header row are tolerated (the parse_spectrum_text rules).

Processing:

  1. start times must be finite, the first must be >= 0, and the sequence must be strictly increasing;
  2. values are converted to microseconds (MICROSECONDS_PER_SECOND);
  3. the closing edge of the last frame is synthesized by extrapolating the last frame width (last + (last − prev)), yielding N+1 ascending edges for N rows.

Bin uniformity is deliberately not enforced: VENUS MCP shutter segments change the frame width mid-run, so a sidecar with several distinct widths is valid. The last-segment-width extrapolation is exact whenever the final two frames belong to the same shutter segment (always the case in practice — segments are many frames long).

§shutter_time is the frame START (left bin edge) — evidence

Verified on measured IPTS-37432 VENUS autoreduce output (OB run 19385, chunk id 116): the sidecar holds 4053 rows (exactly one per TIFF frame), starting at 1.12 µs — not zero; the autoreduce already drops the pre-trigger bins — in uniform 160 ns steps, and every time value is an exact integer multiple of the 160 ns bin width (1.12 µs = 7 × 0.16 µs). Bin centers would sit at half-multiples, so shutter_time is definitively the frame start / left bin edge. PLEIADES’s sidecar helper instead uses the values directly as frame TOFs, which differs from the true bin centers by half a bin width; NEREIDS uses edges here plus geometric-mean centers (crate::tof::tof_edges_to_energy_centers). A constant offset of this kind is absorbed by the fitted t₀ in the energy-scale fit.

§First edge exactly 0

A sidecar whose first start time is exactly 0 s parses successfully (0 is a valid TOF edge), but that edge cannot be energy-converted — E is undefined at t = 0. Crop the first frame from both the stack and the edges (stack[1:], edges[1:]) before conversion. Real autoreduce sidecars start after the pre-trigger bins, so this only arises for hand-made files.

The returned edges plug directly into crate::tof::tof_edges_to_energy_centers.

§Errors

IoError::InvalidParameter on fewer than 2 rows, non-finite or unparseable values, a negative first start time, a non-increasing sequence, or (when n_frames is Some) an edge/frame count mismatch.