Skip to content

dspk.io

Recordings: open files and read them into NumPy; write NumPy arrays as raw binary or Zarr.

Reads return scaled float32 values in each channel’s unit, shape (channels, samples). Generic formats only (raw binary with a JSON sidecar, Zarr /traces); neural formats come with the synapse bindings.

formats Names of the formats open recognizes, in the order they are tried.
open Opens a recording file.
sources Lists the sources of a file, reading only its metadata.
write_raw Writes a recording as raw binary with a JSON sidecar.
write_zarr Writes a recording as a Zarr store (/traces, float32).
Recording A recording opened from a file, read in pieces.
Source One source of a file.
ZarrWriter A Zarr store (/traces, float32) written block by block.
formats() -> list[str]

Names of the formats open recognizes, in the order they are tried.

Returns

  • list of str
open(
path: str | PathLike | Path,
source: str | None = None,
) -> Recording

Opens a recording file.

The format is detected from the file (see formats). Only metadata is read here; samples are read with Recording.read.

Parameters

  • path : str or os.PathLike
    The recording: a file, or a folder for stores such as Zarr.
  • source : str, default None
    Which source to open, an id from sources(path); by default the file’s default source.

Returns

  • Recording

Raises

  • OSError: When the file cannot be read.
  • ValueError: When the format is not recognized or source is not in the file.

Examples

>>> import dspk
>>> rec = dspk.io.open("session.zarr")
sources(path: str | PathLike | Path) -> list[Source]

Lists the sources of a file, reading only its metadata.

Parameters

  • path : str or os.PathLike
    The recording file or folder.

Returns

  • list of Source

Raises

  • OSError: When the file cannot be read.
  • ValueError: When the format is not recognized.

Examples

>>> import dspk
>>> for s in dspk.io.sources("session.nwb"):
... print(s.id, s.channel_count, s.sample_rate)
write_raw(
data,
path: str | PathLike,
sample_rate: float,
*,
format: str | None = None,
order: str = 'channel_major',
gain: float = 1.0,
unit: str = '',
chunk_samples: int = WRITE_CHUNK_SAMPLES,
) -> None

Writes a recording as raw binary with a JSON sidecar.

Integers are written as they are: an int16 array from an amplifier is stored as int16, its gain (units per bit) in the sidecar. Float values stored in an integer format become round(value / gain).

Parameters

  • data : array_like
    Samples (channels, samples): integer arrays are the stored integers (value = stored * gain), float arrays the values. NumPy arrays of a STORED_DTYPES dtype are written as they are; anything else becomes float32.
  • path : str or os.PathLike
    The binary file to write; the sidecar is written next to it.
  • sample_rate : float
    Sample rate in Hz.
  • format : str, default None
    Stored type ("int16", "float32", …); by default data’s dtype.
  • order : {"channel_major", "time_major"}, default 'channel_major'
    Sample layout in the file: each channel’s samples together, or each time step’s channels together.
  • gain : float, default 1.0
    Units per stored integer.
  • unit : str, default ''
    Unit symbol of the values: "V", "mV", "µV" (or "uV"), "A", …; "" for dimensionless.
  • chunk_samples : int, default WRITE_CHUNK_SAMPLES (65536)
    Samples per channel written at a time (bounds memory, not the result).

Raises

  • ValueError: When data is not 2-D or an option is invalid.
  • OSError: When the file cannot be written.

Examples

>>> import numpy as np
>>> import dspk
>>> counts = np.zeros((4, 30_000), dtype=np.int16)
>>> dspk.io.write_raw(counts, "session.bin", 30_000.0, gain=0.195, unit="µV")
write_zarr(
data,
path: str | PathLike,
sample_rate: float,
*,
unit: str = '',
chunk_samples: int = ZARR_CHUNK_SAMPLES,
compression: str = 'zstd',
level: int | None = None,
parallel: bool = True,
) -> None

Writes a recording as a Zarr store (/traces, float32).

Chunks of chunk_samples (all channels) are compressed and stored on several threads.

Parameters

  • data : array_like
    Values (channels, samples).
  • path : str or os.PathLike
    The store (a folder) to create.
  • sample_rate : float
    Sample rate in Hz.
  • unit : str, default ''
    Unit symbol of the values ("" for dimensionless).
  • chunk_samples : int, default ZARR_CHUNK_SAMPLES (5000)
    Samples per Zarr chunk.
  • compression : {"zstd", "blosc_lz4", "none"}, default 'zstd'
    How chunks are compressed.
  • level : int, default None
    Compression level: zstd’s (default 3) or blosc’s 0–9 (default 5); "none" takes none.
  • parallel : bool, default True
    Compress and store on several threads; False uses one.

Raises

  • ValueError: When data is not 2-D or an option is invalid.
  • OSError: When the store cannot be written.

Examples

>>> import numpy as np
>>> import dspk
>>> x = np.random.default_rng(0).standard_normal((4, 30_000)).astype(np.float32)
>>> dspk.io.write_zarr(x, "session.zarr", 30_000.0, unit="µV")

A recording opened from a file, read in pieces.

Opening reads only the metadata; read returns the samples you ask for, scaled to each channel’s unit, as float32. Make one with open.

Examples

>>> import dspk
>>> rec = dspk.io.open("session.zarr")
>>> rec.channel_count, rec.sample_rate
(32, 30000.0)
>>> first_second = rec.read(start=0, stop=30_000)

Properties

Name Type Description
name str Name of the recording, from the file or its source.
channel_count int Number of channels.
samples int Samples per channel.
sample_rate float Sampling rate in Hz.
duration float Duration in seconds.
format str Stored sample type ("int16", "float32", …).
channel_names list[str] Name of each channel.
units list[str] Unit symbol of each channel’s values ("µV", "mV", …; "" when dimensionless).
read(
channels: Sequence[int] | None = None,
start: int = 0,
stop: int | None = None,
) -> NDArray[np.float32]

Reads samples into memory.

Parameters

  • channels : sequence of int, default None
    Channel indices, in the order wanted; by default all.
  • start : int, default 0
    First sample.
  • stop : int, default None
    The sample after the last; by default the end.

Returns

  • np.ndarray — (len(channels), stop - start), float32, in each channel’s unit.

Raises

  • IndexError: When a channel or the sample range is outside the recording.
  • OSError: When the file cannot be read.

One source of a file: what sources lists and open(path, source=...) opens.

Most files have one; containers such as NWB have several (one per electrical series).

Properties

Name Type Description
id str Id to pass to open(path, source=...).
name str Name of the source.
channel_count int Number of channels.
samples int Samples per channel.
sample_rate float Sampling rate in Hz.
format str Stored sample type ("int16", "float32", …).
unit str Unit symbol of the values ("" when dimensionless).
ZarrWriter(
path: str | PathLike | Path,
channels: int,
samples: int,
sample_rate: float,
*,
unit: str = '',
chunk_samples: int = 5000,
compression: str = 'zstd',
level: int | None = None,
parallel: bool = True,
channel_names: Sequence[str] | None = None,
) -> ZarrWriter

A Zarr store (/traces, float32) written block by block.

For data that does not fit in memory at once, such as a recording processed window by window: create the store for its full size, push blocks in order until every sample is written, then finish.

Examples

>>> import numpy as np
>>> import dspk
>>> w = dspk.io.ZarrWriter("out.zarr", 4, 60_000, 30_000.0, unit="µV")
>>> for _ in range(2):
... w.push(np.zeros((4, 30_000), dtype=np.float32))
>>> w.finish()

Parameters

  • path : str or os.PathLike
    The store (a folder) to create.
  • channels : int
    Number of channels.
  • samples : int
    Samples per channel, in total.
  • sample_rate : float
    Sample rate in Hz.
  • unit : str, default ''
    Unit symbol of the values ("" for dimensionless).
  • chunk_samples : int, default 5000
    Samples per Zarr chunk.
  • compression : zstd, blosc_lz4, none, default 'zstd'
    How chunks are compressed.
  • level : int, default None
    Compression level: zstd’s (default 3) or blosc’s 0–9 (default 5); "none" takes none.
  • parallel : bool, default True
    Compress and store on several threads; False uses one.
  • channel_names : list of str, default None
    A name per channel.
push(block: NDArray[np.float32]) -> None

Writes the next block of samples.

Parameters

  • block : numpy.ndarray
    The next n samples, (channels, n) float32.

Raises

  • ValueError: When block has another channel count, goes past the store’s samples, or the writer is finished.
  • OSError: When the store cannot be written.
finish() -> None

Closes the store, after checking that every sample was written.

Raises

  • ValueError: When samples are missing or the writer is already finished.
  • OSError: When the store cannot be closed.
Name Type Value Description
STORED_DTYPES ('int8', 'int16', 'uint16', 'int32', 'float32', 'float64')
WRITE_CHUNK_SAMPLES int 65536
ZARR_CHUNK_SAMPLES int 5000