Skip to content

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

No unreleased changes.

[0.0.9] - 2026-10-02

Several additions need a recent Radiens server. With an older one, a method may raise CapabilityError, or a new option, field or metric may be ignored or unavailable. KPI values depend on the connected server; see SNR and NOISE_UV under Changed.

Added

  • get_signals() on both clients accepts TimeRangeSpec.to_head(), TimeRangeSpec.lookback(), TimeRangeSpec.full(), and open-ended ranges such as [t, inf], with a recent Radiens server.
  • VidereClient.spike_sort(): launches a sort and waits until its output can be read.
  • VidereClient.get_units() and the Unit model: one entry per sorted cell, merging the per-site listings that get_neurons() returns.
  • VidereClient.get_provenance(): the operations that produced a dataset. Models are in radiens_core.models.provenance.
  • VidereClient.get_spectral(), get_batch_spectral(), and get_spectral_info(): periodogram, Welch, and STFT analysis. Models are in radiens_core.models.spectral.
  • VidereClient.get_channel_metadata().
  • set_selected_channels(), select_channels(), deselect_channels(), and set_channel_groups() on AllegoClient and VidereClient, and the COLOR_GROUP_UNSET constant.
  • apply_dsp argument on get_signals() for both clients, returning the stage-2 filtered signal. Defaults to False. An older server raises CapabilityError when it is set.
  • SpikeSorterState.phase and the SpikeSorterPhase enum.
  • neighbor_radius_um, max_num_site_neighbors, and seed on SpikeSorterLaunchParams. The two neighborhood options are also accepted by spike_sorter_command() with cmd="init".
  • SpikeDetectParams.spike_width_sec: the [min, max] spike width kept for clustering, used with the WFM and WFM_POS feature types.
  • SpikeDetectParams.is_set_weak_thr: whether the artifact-rejection threshold (weak_thr) is armed. Reported by get_detect_params() and applied by update_detect_params().
  • family and ripple_db on DSPParams for Chebyshev-I filters, with FilterFamily, FilterFamilyStr, and FlexFilterFamily.
  • req_num_neighbors, neighborhood_radius_um, and per-site thresholds (sites, SpikesSiteSpec) on SpikesSpec.
  • KpiMetric.EVENT_MEAN_MAX_ABS: the mean absolute peak of the events in a window, in µV.
  • RadiensFileType members SPIKEGLX, NCS, NCS_SESSION, EDF, and RHS.
  • site_ntv_chan_idx on ChannelSpikeData and NeuronSpikeData, and NeuronSpikeData.detect_ntv_chan_idx: the channel of each waveform site, and the channel that detected each spike.
  • SignalArrays.time_range: the range the returned samples cover. It is shorter than the request when the server holds less, for example past the end of a recording or aged out of the live cache.
  • radiens_core.models exports FileInfo, FlexDataset, FlexTimeRange, FreqSpecBand, Impedance, ImpedanceValue, and the provenance and spectral models.
  • update_detect_params() on AllegoClient and VidereClient.
  • VidereClient.get_spikes_ids(): the spikes fileset IDs for a dataset.
  • ChannelMetadata.ntv_indices_for_sites(): the channels of given sites on one probe, named by port and the probe's position on it. ChannelInfo gains port and probe_idx, ChannelMetadata gains ports and probe_idxs, and SITE_NUM_UNSET marks a channel with no probe connected.
  • VidereClient.get_kpi_metrics_series(): per-channel KPI metrics per time window. Returns KpiMetricsSeriesResult. window_dur_sec=None uses the native KPI packet duration.
  • VidereClient.get_kpi_bundle_stats(): cross-channel KPI summaries over time, such as mean RMS or channel yield. Returns KpiBundleStatsResult.
  • service_mode and stream_lookback_sec arguments on get_kpi_metrics(). Results carry answered_mode. AllegoClient defaults to KpiServiceMode.STREAM, since RANGE is not available on a live stream.
  • KpiServiceMode, ChannelReduction, BundleStatId, KpiMetricsWindow, KpiBundleStatsWindow, and the matching Flex* input types.
  • FlexKpiMetricId accepts a KpiMetric member.
  • live= argument on link_data_file() for a recording that is still being written. Required for KPI to follow a growing file.
  • VidereClient.get_tailing_state(), with the TailingState model and LivenessState enum.
  • BackboneMode.SMARTBOX_SIM_GEN_BROADBAND.
  • Homepage and Documentation project URLs and an MIT license classifier in the package metadata.

Changed

  • ChannelSpikeData.waveforms and NeuronSpikeData.waveforms have shape (N, n_sites, waveform_n_points): each spike on its detecting site and that site's neighbors. site_ntv_chan_idx names the channel of each site.
  • AllegoClient.get_signals() returns unfiltered wideband by default, matching VidereClient. Pass apply_dsp=True for the previous behavior.
  • DSPParams.port is required. A filter without one was always rejected before it reached the server.
  • Dataset arguments reflect the server's current state, so changes made in the desktop apps or by another script show up immediately. A path not yet linked is linked on first use, and an ID linked by another client is accepted.
  • time_range=None, TimeRangeSpec.full(), and open-ended ranges such as [t, inf] are resolved by the server against the data it holds when the call runs, so get_signals(), the KPI reads, the spike reads, and get_neurons() read a growing recording up to its current end. Previously None meant the extent when the server first loaded the file, which is still the behavior with an older Radiens server.
  • AllegoClient.get_signals() raises CapabilityError instead of ValueError for a lookback with an older Radiens server.
  • A time range that starts after the dataset's linked end no longer raises ValueError, so a growing recording can be read up to get_tailing_state().available_time_range. Only a range ending before the dataset starts raises. time_range on the result reports what was read. With an older Radiens server, an OE_DAT recording is read only up to its extent when linked.
  • Inferring a file type from an unrecognized suffix raises ValueError instead of assuming XDAT. This applies to link_data_file(), the *_data_source_file() methods, the transform outputs, and file paths passed as datasets.
  • SpikeSorterFeatureParams.feature_type defaults to WFM_POS, matching the server.
  • set_dsp_group() raises ValueError for a filter with zero_phase=True. Zero-phase filtering is not supported; such filters were applied causally.
  • SignalSelectionError is also a ValueError, so except ValueError catches a bad channel index from any method.
  • ChannelInfo.color_group_idx defaults to COLOR_GROUP_UNSET instead of group 0.
  • Building ChannelMetadata directly requires ports and probe_idxs.
  • DSPParams.target_ntv_chan_idx is an int. A whole-number float such as 4.0 is still accepted; a fractional one raises ValidationError.
  • StimParams rejects a StimKeypressIndex trigger when trigger_source_is_keypress is False. The server read that index as a channel and triggered off it.
  • get_kpi_metrics() on VidereClient raises SignalSelectionError for a channel index the dataset does not have.
  • VidereClient KPI metric reads time out after 30 s instead of hanging.
  • A KPI read over a range the server has no KPI data for raises TimeRangeError.
  • KPI reads over a full recording are faster.
  • KPI methods require a server with the current KPI metric set and raise CapabilityError against an older one.
  • KpiMetric member values are no longer stable across releases. Refer to metrics by name.
  • VidereClient.list_directory() no longer supports older servers and raises CapabilityError against them.
  • TimeRangeSpec.subset() raises ValueError when it does not overlap the dataset at all, instead of returning empty data.
  • With a recent Radiens server:
  • AllegoClient.set_dsp_group() raises ServerCommunicationError for a hardware or stage-1 change while recording.
  • Linking a recording restores the stage-2 filter chain that was in force when recording started.
  • KpiMetric.SNR is the mean event peak over noise instead of the maximum, so it no longer grows with window length. Values are typically lower. A window with no events reports NaN instead of 0.0.
  • KpiMetric.NOISE_UV is the spike detector's noise estimate. Values are lower on channels with undetected activity.
  • The first KPI read of a recording analyzed by an older server takes longer while its metrics are recomputed.
  • Cross-channel reductions in get_kpi_bundle_stats() skip infinite values as well as NaN.

Deprecated

  • set_detect_params() on both clients: use update_detect_params(), which takes the same arguments. Removed in 0.1.0.
  • The notch_freq= keyword of VidereClient.bulk_notch(): use frequency=, matching notch(). Removed in 0.1.0.
  • VidereClient.get_spike_sorter_ids(): use get_spikes_ids(). It now returns spikes fileset IDs, the same sorted list as DatasetMetadata.associated_spikes_ids, instead of active spike sorter IDs. Removed in 0.1.0.
  • notch_frequency on TransformNode.notch() and NotchParams: use frequency, matching the other filter nodes. Removed in 0.1.0.
  • AllegoClient.set_kpi_packet_dur() and AllegoClient.set_kpi_update_period(): no Allego server implements them, so every call fails. The VidereClient methods of the same names are unaffected. Removed in 0.1.0.
  • ChannelMetadata.sys_indices_for_site_nums(): use ntv_indices_for_sites(). A site number is unique only within one probe on one port. Removed in 0.1.0.
  • KpiMode, KpiMetricId.mode, and the (mode, name) form of FlexKpiMetricId. Use service_mode on get_kpi_metrics(). Removed in 0.1.0.

Removed

  • DSPGroup.spike_sorter and FilterStage.SPIKE_SORTER. The spike sorter detects on stage 2.
  • SpikeSorterLaunchParams.sink_dsrc_id, discover_noise, and is_auto_on. The server assigns the output ID.
  • The time_range argument of AllegoClient.get_kpi_metrics(). A live stream does not support it.
  • DatasetMetadata.probe_uid and DatasetMetadata.parent_dsource_id. probe_uid held the dataset UID, which channel_metadata.dataset_uid carries, and parent_dsource_id was never set.
  • RestartRequest, StimStepRequest, SetTriggerStateRequest, and StimParamsPartial. No method accepted them.
  • ClientType, from both radiens_core.models and radiens_core.models.common.
  • KpiStatus.is_tracking_signal_cache.
  • KpiMetric members the server no longer computes: MIN_ISI, MAX_ISI, MAX_ABS_ISI, MAX_MIN_DIFF_ABS_ISI, SD_ISI, VAR_ISI, RMS_ISI, VAR, TIMESTAMP_MIN, TIMESTAMP_MAX, NUM_EVENTS, EVENT_TIMESTAMP_MIN, EVENT_TIMESTAMP_MAX, EVENT_TIMESTAMP_MAX_ABS, EVENT_TIMESTAMP_MAX_MIN_DIFF_ABS, MEAN_MAX, MEAN_MIN, MEAN_MAX_ABS, and MAX_MIN_DIFF_ABS_AMPLIFIED.
  • BackboneMode.SMARTBOX_SIM_GEN_SINE_MAPPED, SMARTBOX_SIM_GEN_SINE_HIGH_FREQ, and SMARTBOX_SIM_GEN_SINE_MULTI_BAND.

Fixed

  • A notch filter with a notch_bandwidth that was unset, zero or negative crashed an older Radiens server. set_dsp_group(), notch(), bulk_notch() and TransformNode.notch() now raise ValueError for it.
  • set_dsp_group() sent a paired reference with no target_ntv_chan_idx, or an aux filter with no aux_chan_idx, and the server crashed on it. It also dropped all but one of freq, freq_spec_band and ref_ntv_chan_idx when several were set. It now raises ValueError for each.
  • healthcheck(service=...) failed with ServerCommunicationError for every service but the lifecycle and core ones, though the service was up. Each service now gets its own health check, and a service the client's server doesn't have, such as ALLEGO_KPI on VidereClient, raises ValueError.
  • list_directory() sent ~ and relative paths to the server as written. They are now resolved on this machine, as for the other file methods.
  • VidereClient.spike_sorter_delete("") deleted every spike sorter on the server, including the Radiens app's. It now raises ValueError.
  • AllegoClient.get_kpi_metrics() silently left out channel indices the live stream does not have. It now raises SignalSelectionError, as VidereClient does.
  • A signals argument given as a tuple of channel indices was rejected. Any sequence of ints is now accepted.
  • StimParams.biphasic() failed validation unless trigger_source_idx was passed as an override. It now takes trigger_source_idx and sets trigger_source_is_keypress when the trigger is a StimKeypressIndex.
  • ChannelMetadata.sys_indices_for_site_nums() returned one arbitrary channel for a site number found on more than one port or probe, including channels with no probe connected. It now raises DatasetError for such a site.
  • get_spikes_by_channel() and get_spikes_by_neuron() with include_waveforms=True returned the same waveform for every spike on a channel.
  • get_spikes_by_neuron() with include_waveforms=True returned every waveform on the neuron's main channel, including other neurons' spikes, and missed its spikes detected on other channels. It now returns one row per spike of the neuron, matching timestamps, all on the same sites. An older server raises CapabilityError.
  • ChannelSpikeData.labels held the channel index instead of the neuron label. It is now None when waveforms are not requested.
  • get_spikes_by_channel(), get_spikes_by_neuron(), and get_neurons() with time_range=None returned nothing for a recording whose time range does not start at zero.
  • DatasetMetadata.associated_spikes_ids listed only the spikes file found at link time, missing sorts run since or from the desktop apps, in no stable order.
  • KeyIdxs.dset, ChannelInfo.dset_idx, and ChannelMetadata.ntv_from_dset() returned the wrong index under a non-default channel sort. With an older Radiens server, dset reports the native index, which is correct only for an unsliced recording.
  • Paths starting with ~ were not expanded.
  • Relative output paths resolved against the server's working directory instead of the caller's: output_path in the transform methods, output_dir in the bulk_* methods, the path of sink nodes passed to set_protocol(), and dest_path in export_data_source().
  • On Windows, a dataset string written with forward slashes was taken as a dataset ID instead of a path.
  • link_data_file() failed on an XDAT recording given by its _data.xdat or _timestamp.xdat file, and did not infer Blackrock (.ns1–.ns6) or TDT (.tsq) files from their suffix.
  • remove_data_source_file() failed on every call.
  • The transform methods and export_data_source() misnamed an XDAT output given by its _data.xdat, _timestamp.xdat, or .xdat.json file: out_data.xdat wrote out_data_data.xdat, which link_data_file() on the same path could not find.
  • TimeRangeSpec.to_array() on a to_head() spec returned an array that from_list() read back as a lookback.
  • A TimeRangeSpec subset ending at inf, including the array from to_head().to_array(), was treated as the full range and ignored its start. from_list() accepted an end before the start. resolve() reported the dataset's start wall time for a subset that starts later.
  • get_kpi_metrics() failed on every call with a serialization error.
  • KpiMetricsResult.values was decoded incorrectly.
  • VidereClient.kpi_calculate() returned before computation finished.
  • The *Str type aliases behind the Flex* input types include lowercase spellings, so type checkers accept calls such as DSPParams(type="highpass", ...).

[0.0.8] - 2026-06-04

Added

  • ProtocolSpec is exported from radiens_core.models.

Changed

  • VidereClient includes all transform and curation methods previously on CurateClient: slice_time, downsample, highpass, lowpass, bandpass, bandstop, notch, car, virtual_ref, paired_ref, slice_channels, set_protocol, apply_protocol, get_protocol, get_all_protocols, and the bulk_* variants.
  • Transform methods accept str | Path for output_path and output_dir.

Deprecated

  • CurateClient: replace CurateClient() with VidereClient(). Removed in 0.1.0.

Removed

  • SpikeSorterLaunchParams.nbr_pattern.
  • ClientType.CURATE.

[0.0.7] - 2026-05-20

Added

  • ChannelInfo.site_num and ChannelInfo.color_group_idx, with the parallel ChannelMetadata.site_nums and ChannelMetadata.color_group_idxs.
  • ChannelMetadata.sys_indices_for_site_nums() and ChannelMetadata.sys_indices_for_color_groups().

Fixed

  • StimParams.trigger_source_idx accepts enum names such as "KEYPRESS_1".

[0.0.6] - 2026-05-15

Added

  • CapabilityError, raised when a method needs a newer server version.
  • server_version property on all clients.

Changed

  • Deprecated AllegoClient methods emit a DeprecationWarning naming the removal version and the replacement.

Fixed

  • StimParams.refractory_period was sent 1000x too long.

[0.0.5] - 2026-05-06

Added

  • tutorials/closed_loop_streaming.py: incremental signal acquisition from a live stream.

Changed

  • AllegoClient.spike_sorter_command() takes an optional spike_sorter_id, defaulting to the active sorter.
  • get_signals() on both clients requires an exact [start, end] range. Lookback ranges raise ValueError.

[0.0.4] - 2026-04-21

Added

  • Flexible enum, string, and int inputs for the main AllegoClient and VidereClient methods and for enum fields on StimParams, RecordingConfig, DSPParams, SpikeSorterFeatureParams, and SpikeSorterDynamicCriteria.
  • Shorthand inputs: metric name strings for FlexKpiMetricId, and typed dicts for FlexDSPParams.

Changed

  • The top-level radiens_core package exports only AllegoClient, CurateClient, VidereClient, and __version__. Import everything else from its submodule.
  • String inputs for several enums use canonical names only; legacy aliases were removed.

[0.0.3] - 2026-04-07

Added

AllegoClient

  • Sinaps probe control: load_all_mosi(), transmit_mosi(), read_wire_out(), get_sinaps_status_registers(), and flash_sinaps().
  • start_streaming(), stop_streaming(), start_recording(), stop_recording(), set_stim_trigger(), and toggle_stim_trigger().
  • update_recording_config() and update_core_config().
  • enable_trigger(), disable_trigger(), and disable_all_triggers().
  • Spike sorter control: get_spike_sorter_ids(), get_default_spike_sorter_id(), get_spike_sorter_state(), spike_sorter_command(), get_spike_sorter_dashboard(), get_detect_params(), and set_detect_params().

VidereClient

  • Offline spike sorter control: get_spike_sorter_ids(), spike_sorter_launch(), spike_sorter_command(), spike_sorter_cancel(), get_spike_sorter_state(), get_spike_sorter_dashboard(), spike_sorter_delete(), get_detect_params(), and set_detect_params().

Models

  • SinapsStatusRegisters and the spike sorter models and enums.
  • FlexDataset (DatasetMetadata | str | Path) for dataset arguments.
  • ChannelInfo fields name, ntv_name, is_selected, probe_id, headstage_id, sensor_id, and site position and geometry fields, with has_position, bounding_box_size, bounding_box_center, and get_area().
  • ChannelMetadata fields chan_names, ntv_chan_names, probe_ids, headstage_ids, and sensor_ids.
  • DatasetMetadata.base_path.
  • TimeRangeSpec and SignalSpec are exported from radiens_core.models.

Changed

  • AllegoClient.restart() takes mode: BackboneMode instead of a RestartRequest.
  • AllegoClient.set_stim_step() takes step: StimStep instead of a StimStepRequest.
  • VidereClient.set_dsp_group() takes stage and params as keyword-only arguments.
  • get_signals() and get_kpi_metrics() on both clients default to all amplifier channels. On VidereClient, they also default to the full recording.
  • VidereClient.get_spikes_by_channel(), get_spikes_by_neuron(), and get_neurons() accept channels as list[int], SignalSpec, or "all", and default to the full recording.
  • CurateClient.notch() and bulk_notch() no longer take order.
  • ChannelInfo.site_position is a computed property.

Deprecated

  • AllegoClient.set_stream_state(): use start_streaming() or stop_streaming().
  • AllegoClient.set_record_state(): use start_recording() or stop_recording().
  • AllegoClient.manual_stim_trigger(): use set_stim_trigger().
  • AllegoClient.manual_stim_trigger_toggle(): use toggle_stim_trigger().
  • AllegoClient.set_recording_config(): use update_recording_config().
  • AllegoClient.set_core_config(): use update_core_config().
  • AllegoClient.set_trigger_state(): use enable_trigger(), disable_trigger(), or disable_all_triggers().

Fixed

  • VidereClient.get_spikes_by_channel() ignored the channel filter.

[0.0.2] - 2026-03-25

Added

  • VidereClient.get_spikes_spec(), get_spikes_by_channel(), get_spikes_by_neuron(), and get_neurons().
  • SpikesSpec, ChannelSpikeData, NeuronSpikeData, NeuronsResult, and NeuronInfo.
  • DatasetMetadata.associated_spikes_ids.

Changed

  • link_data_file() also registers any .spikes file found next to the recording.

[0.0.1] - 2026-03-23

Initial stable release.

Added

AllegoClient (real-time acquisition)

  • healthcheck(), get_status(), set_stream_state(), set_record_state(), and restart().
  • get_signals() and get_channel_metadata().
  • get_stim_params(), set_stim_params(), and set_trigger_control().
  • get_recording_config(), get_dsp_group(), set_dsp_group(), get_core_config(), and set_core_config().
  • get_intan_impedance() and scan_ports().
  • DAC control: get_dac_reg(), set_dac_gain(), set_dac_stream(), set_dac_off(), and set_dac_highpass().
  • Digital output control: get_dio_reg(), set_dio_events(), set_dio_manual(), set_dio_gated(), and set_dio_pulse().
  • KPI signal-quality metrics: get_kpi_metrics(), get_kpi_status(), set_kpi_packet_dur(), and set_kpi_update_period().

VidereClient (offline analysis)

  • link_data_file() and get_signals().
  • get_dsp_group() and set_dsp_group().
  • list_data_sources(), list_data_source_ids(), clear_data_sources(), and export_data_source().
  • get_kpi_metrics(), get_kpi_status(), kpi_calculate(), kpi_clear(), and set_kpi_packet_dur().

CurateClient (data curation)

  • slice_time(), slice_channels(), and downsample().
  • highpass(), lowpass(), bandpass(), bandstop(), and notch().
  • car(), virtual_ref(), and paired_ref().
  • set_protocol() for multi-step transform graphs.

General

  • Automatic server discovery; clients take no constructor arguments.
  • Typed Pydantic models for all requests and results.