Skip to content

Recordings saved out of order

Acquisition systems store channels in the order of their amplifier inputs, not the order of the electrodes, so neighbouring electrodes end up anywhere in the file. A channel map puts them back, written as pairs (like a hardware channel mapper): “stored channel from is electrode to”, with an optional name. Inputs left out are dropped; base = 1 reads 1-based numbers (TDT, MATLAB). Maps are TOML or JSON files ([remap]), and the same file works in Python, in pipeline specs, in the CLI (--channel-map) and in the app.

from pathlib import Path
import tempfile
import numpy as np
import dspk
from dspk.ops import layout
from plating import signals
work = Path(tempfile.mkdtemp(prefix="dspk-playground-"))
s = signals.synthetic(channels=16, lfp_uv=20.0, spread_channels=1.5)
spikes_band = dspk.ops.filter.iir(s.data, s.sample_rate, "highpass", 300.0)
# The amplifier wired electrode e to input wiring[e]: the file stores them in input order
rng = np.random.default_rng(4)
wiring = rng.permutation(s.channels)
stored = np.empty_like(spikes_band)
stored[wiring] = spikes_band
# The map: stored input wiring[e] is electrode e (1-based here, as a TDT export would be)
pairs = [{"from": int(wiring[e]) + 1, "to": e + 1, "name": f"E{e + 1:02d}"} for e in range(s.channels)]
layout.write_map({"base": 1, "pairs": pairs}, work / "map.toml")
print((work / "map.toml").read_text()[:200], "…")
ordered = layout.remap(stored, work / "map.toml")
order, names = layout.map_order(work / "map.toml")
print("back in electrode order:", np.array_equal(ordered, spikes_band))

Recordings saved out of order

The whole script is playground/07_channels/01_remap_with_pairs.py. Run it with uv run python playground/07_channels/01_remap_with_pairs.py.