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 acceptsTimeRangeSpec.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 theUnitmodel: one entry per sorted cell, merging the per-site listings thatget_neurons()returns.VidereClient.get_provenance(): the operations that produced a dataset. Models are inradiens_core.models.provenance.VidereClient.get_spectral(),get_batch_spectral(), andget_spectral_info(): periodogram, Welch, and STFT analysis. Models are inradiens_core.models.spectral.VidereClient.get_channel_metadata().set_selected_channels(),select_channels(),deselect_channels(), andset_channel_groups()onAllegoClientandVidereClient, and theCOLOR_GROUP_UNSETconstant.apply_dspargument onget_signals()for both clients, returning the stage-2 filtered signal. Defaults toFalse. An older server raisesCapabilityErrorwhen it is set.SpikeSorterState.phaseand theSpikeSorterPhaseenum.neighbor_radius_um,max_num_site_neighbors, andseedonSpikeSorterLaunchParams. The two neighborhood options are also accepted byspike_sorter_command()withcmd="init".SpikeDetectParams.spike_width_sec: the[min, max]spike width kept for clustering, used with theWFMandWFM_POSfeature types.SpikeDetectParams.is_set_weak_thr: whether the artifact-rejection threshold (weak_thr) is armed. Reported byget_detect_params()and applied byupdate_detect_params().familyandripple_dbonDSPParamsfor Chebyshev-I filters, withFilterFamily,FilterFamilyStr, andFlexFilterFamily.req_num_neighbors,neighborhood_radius_um, and per-site thresholds (sites,SpikesSiteSpec) onSpikesSpec.KpiMetric.EVENT_MEAN_MAX_ABS: the mean absolute peak of the events in a window, in µV.RadiensFileTypemembersSPIKEGLX,NCS,NCS_SESSION,EDF, andRHS.site_ntv_chan_idxonChannelSpikeDataandNeuronSpikeData, andNeuronSpikeData.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.modelsexportsFileInfo,FlexDataset,FlexTimeRange,FreqSpecBand,Impedance,ImpedanceValue, and the provenance and spectral models.update_detect_params()onAllegoClientandVidereClient.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.ChannelInfogainsportandprobe_idx,ChannelMetadatagainsportsandprobe_idxs, andSITE_NUM_UNSETmarks a channel with no probe connected.VidereClient.get_kpi_metrics_series(): per-channel KPI metrics per time window. ReturnsKpiMetricsSeriesResult.window_dur_sec=Noneuses the native KPI packet duration.VidereClient.get_kpi_bundle_stats(): cross-channel KPI summaries over time, such as mean RMS or channel yield. ReturnsKpiBundleStatsResult.service_modeandstream_lookback_secarguments onget_kpi_metrics(). Results carryanswered_mode.AllegoClientdefaults toKpiServiceMode.STREAM, sinceRANGEis not available on a live stream.KpiServiceMode,ChannelReduction,BundleStatId,KpiMetricsWindow,KpiBundleStatsWindow, and the matchingFlex*input types.FlexKpiMetricIdaccepts aKpiMetricmember.live=argument onlink_data_file()for a recording that is still being written. Required for KPI to follow a growing file.VidereClient.get_tailing_state(), with theTailingStatemodel andLivenessStateenum.BackboneMode.SMARTBOX_SIM_GEN_BROADBAND.HomepageandDocumentationproject URLs and an MIT license classifier in the package metadata.
Changed
ChannelSpikeData.waveformsandNeuronSpikeData.waveformshave shape(N, n_sites, waveform_n_points): each spike on its detecting site and that site's neighbors.site_ntv_chan_idxnames the channel of each site.AllegoClient.get_signals()returns unfiltered wideband by default, matchingVidereClient. Passapply_dsp=Truefor the previous behavior.DSPParams.portis 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, soget_signals(), the KPI reads, the spike reads, andget_neurons()read a growing recording up to its current end. PreviouslyNonemeant the extent when the server first loaded the file, which is still the behavior with an older Radiens server.AllegoClient.get_signals()raisesCapabilityErrorinstead ofValueErrorfor 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 toget_tailing_state().available_time_range. Only a range ending before the dataset starts raises.time_rangeon the result reports what was read. With an older Radiens server, anOE_DATrecording is read only up to its extent when linked. - Inferring a file type from an unrecognized suffix raises
ValueErrorinstead of assuming XDAT. This applies tolink_data_file(), the*_data_source_file()methods, the transform outputs, and file paths passed as datasets. SpikeSorterFeatureParams.feature_typedefaults toWFM_POS, matching the server.set_dsp_group()raisesValueErrorfor a filter withzero_phase=True. Zero-phase filtering is not supported; such filters were applied causally.SignalSelectionErroris also aValueError, soexcept ValueErrorcatches a bad channel index from any method.ChannelInfo.color_group_idxdefaults toCOLOR_GROUP_UNSETinstead of group 0.- Building
ChannelMetadatadirectly requiresportsandprobe_idxs. DSPParams.target_ntv_chan_idxis anint. A whole-number float such as4.0is still accepted; a fractional one raisesValidationError.StimParamsrejects aStimKeypressIndextrigger whentrigger_source_is_keypressis False. The server read that index as a channel and triggered off it.get_kpi_metrics()onVidereClientraisesSignalSelectionErrorfor a channel index the dataset does not have.VidereClientKPI 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
CapabilityErroragainst an older one. KpiMetricmember values are no longer stable across releases. Refer to metrics by name.VidereClient.list_directory()no longer supports older servers and raisesCapabilityErroragainst them.TimeRangeSpec.subset()raisesValueErrorwhen it does not overlap the dataset at all, instead of returning empty data.- With a recent Radiens server:
AllegoClient.set_dsp_group()raisesServerCommunicationErrorfor 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.SNRis 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 reportsNaNinstead of0.0.KpiMetric.NOISE_UVis 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 asNaN.
Deprecated
set_detect_params()on both clients: useupdate_detect_params(), which takes the same arguments. Removed in 0.1.0.- The
notch_freq=keyword ofVidereClient.bulk_notch(): usefrequency=, matchingnotch(). Removed in 0.1.0. VidereClient.get_spike_sorter_ids(): useget_spikes_ids(). It now returns spikes fileset IDs, the same sorted list asDatasetMetadata.associated_spikes_ids, instead of active spike sorter IDs. Removed in 0.1.0.notch_frequencyonTransformNode.notch()andNotchParams: usefrequency, matching the other filter nodes. Removed in 0.1.0.AllegoClient.set_kpi_packet_dur()andAllegoClient.set_kpi_update_period(): no Allego server implements them, so every call fails. TheVidereClientmethods of the same names are unaffected. Removed in 0.1.0.ChannelMetadata.sys_indices_for_site_nums(): usentv_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 ofFlexKpiMetricId. Useservice_modeonget_kpi_metrics(). Removed in 0.1.0.
Removed
DSPGroup.spike_sorterandFilterStage.SPIKE_SORTER. The spike sorter detects on stage 2.SpikeSorterLaunchParams.sink_dsrc_id,discover_noise, andis_auto_on. The server assigns the output ID.- The
time_rangeargument ofAllegoClient.get_kpi_metrics(). A live stream does not support it. DatasetMetadata.probe_uidandDatasetMetadata.parent_dsource_id.probe_uidheld the dataset UID, whichchannel_metadata.dataset_uidcarries, andparent_dsource_idwas never set.RestartRequest,StimStepRequest,SetTriggerStateRequest, andStimParamsPartial. No method accepted them.ClientType, from bothradiens_core.modelsandradiens_core.models.common.KpiStatus.is_tracking_signal_cache.KpiMetricmembers 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, andMAX_MIN_DIFF_ABS_AMPLIFIED.BackboneMode.SMARTBOX_SIM_GEN_SINE_MAPPED,SMARTBOX_SIM_GEN_SINE_HIGH_FREQ, andSMARTBOX_SIM_GEN_SINE_MULTI_BAND.
Fixed
- A notch filter with a
notch_bandwidththat was unset, zero or negative crashed an older Radiens server.set_dsp_group(),notch(),bulk_notch()andTransformNode.notch()now raiseValueErrorfor it. set_dsp_group()sent a paired reference with notarget_ntv_chan_idx, or an aux filter with noaux_chan_idx, and the server crashed on it. It also dropped all but one offreq,freq_spec_bandandref_ntv_chan_idxwhen several were set. It now raisesValueErrorfor each.healthcheck(service=...)failed withServerCommunicationErrorfor 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 asALLEGO_KPIonVidereClient, raisesValueError.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 raisesValueError.AllegoClient.get_kpi_metrics()silently left out channel indices the live stream does not have. It now raisesSignalSelectionError, asVidereClientdoes.- A
signalsargument given as a tuple of channel indices was rejected. Any sequence of ints is now accepted. StimParams.biphasic()failed validation unlesstrigger_source_idxwas passed as an override. It now takestrigger_source_idxand setstrigger_source_is_keypresswhen the trigger is aStimKeypressIndex.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 raisesDatasetErrorfor such a site.get_spikes_by_channel()andget_spikes_by_neuron()withinclude_waveforms=Truereturned the same waveform for every spike on a channel.get_spikes_by_neuron()withinclude_waveforms=Truereturned 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, matchingtimestamps, all on the same sites. An older server raisesCapabilityError.ChannelSpikeData.labelsheld the channel index instead of the neuron label. It is nowNonewhen waveforms are not requested.get_spikes_by_channel(),get_spikes_by_neuron(), andget_neurons()withtime_range=Nonereturned nothing for a recording whose time range does not start at zero.DatasetMetadata.associated_spikes_idslisted 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, andChannelMetadata.ntv_from_dset()returned the wrong index under a non-default channel sort. With an older Radiens server,dsetreports 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_pathin the transform methods,output_dirin thebulk_*methods, thepathof sink nodes passed toset_protocol(), anddest_pathinexport_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.xdator_timestamp.xdatfile, 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.jsonfile:out_data.xdatwroteout_data_data.xdat, whichlink_data_file()on the same path could not find. TimeRangeSpec.to_array()on ato_head()spec returned an array thatfrom_list()read back as a lookback.- A
TimeRangeSpecsubset ending atinf, including the array fromto_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.valueswas decoded incorrectly.VidereClient.kpi_calculate()returned before computation finished.- The
*Strtype aliases behind theFlex*input types include lowercase spellings, so type checkers accept calls such asDSPParams(type="highpass", ...).
[0.0.8] - 2026-06-04
Added
ProtocolSpecis exported fromradiens_core.models.
Changed
VidereClientincludes all transform and curation methods previously onCurateClient: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 thebulk_*variants.- Transform methods accept
str | Pathforoutput_pathandoutput_dir.
Deprecated
CurateClient: replaceCurateClient()withVidereClient(). Removed in 0.1.0.
Removed
SpikeSorterLaunchParams.nbr_pattern.ClientType.CURATE.
[0.0.7] - 2026-05-20
Added
ChannelInfo.site_numandChannelInfo.color_group_idx, with the parallelChannelMetadata.site_numsandChannelMetadata.color_group_idxs.ChannelMetadata.sys_indices_for_site_nums()andChannelMetadata.sys_indices_for_color_groups().
Fixed
StimParams.trigger_source_idxaccepts enum names such as"KEYPRESS_1".
[0.0.6] - 2026-05-15
Added
CapabilityError, raised when a method needs a newer server version.server_versionproperty on all clients.
Changed
- Deprecated
AllegoClientmethods emit aDeprecationWarningnaming the removal version and the replacement.
Fixed
StimParams.refractory_periodwas 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 optionalspike_sorter_id, defaulting to the active sorter.get_signals()on both clients requires an exact[start, end]range. Lookback ranges raiseValueError.
[0.0.4] - 2026-04-21
Added
- Flexible enum, string, and int inputs for the main
AllegoClientandVidereClientmethods and for enum fields onStimParams,RecordingConfig,DSPParams,SpikeSorterFeatureParams, andSpikeSorterDynamicCriteria. - Shorthand inputs: metric name strings for
FlexKpiMetricId, and typed dicts forFlexDSPParams.
Changed
- The top-level
radiens_corepackage exports onlyAllegoClient,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(), andflash_sinaps(). start_streaming(),stop_streaming(),start_recording(),stop_recording(),set_stim_trigger(), andtoggle_stim_trigger().update_recording_config()andupdate_core_config().enable_trigger(),disable_trigger(), anddisable_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(), andset_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(), andset_detect_params().
Models
SinapsStatusRegistersand the spike sorter models and enums.FlexDataset(DatasetMetadata | str | Path) for dataset arguments.ChannelInfofieldsname,ntv_name,is_selected,probe_id,headstage_id,sensor_id, and site position and geometry fields, withhas_position,bounding_box_size,bounding_box_center, andget_area().ChannelMetadatafieldschan_names,ntv_chan_names,probe_ids,headstage_ids, andsensor_ids.DatasetMetadata.base_path.TimeRangeSpecandSignalSpecare exported fromradiens_core.models.
Changed
AllegoClient.restart()takesmode: BackboneModeinstead of aRestartRequest.AllegoClient.set_stim_step()takesstep: StimStepinstead of aStimStepRequest.VidereClient.set_dsp_group()takesstageandparamsas keyword-only arguments.get_signals()andget_kpi_metrics()on both clients default to all amplifier channels. OnVidereClient, they also default to the full recording.VidereClient.get_spikes_by_channel(),get_spikes_by_neuron(), andget_neurons()acceptchannelsaslist[int],SignalSpec, or"all", and default to the full recording.CurateClient.notch()andbulk_notch()no longer takeorder.ChannelInfo.site_positionis a computed property.
Deprecated
AllegoClient.set_stream_state(): usestart_streaming()orstop_streaming().AllegoClient.set_record_state(): usestart_recording()orstop_recording().AllegoClient.manual_stim_trigger(): useset_stim_trigger().AllegoClient.manual_stim_trigger_toggle(): usetoggle_stim_trigger().AllegoClient.set_recording_config(): useupdate_recording_config().AllegoClient.set_core_config(): useupdate_core_config().AllegoClient.set_trigger_state(): useenable_trigger(),disable_trigger(), ordisable_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(), andget_neurons().SpikesSpec,ChannelSpikeData,NeuronSpikeData,NeuronsResult, andNeuronInfo.DatasetMetadata.associated_spikes_ids.
Changed
link_data_file()also registers any.spikesfile 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(), andrestart().get_signals()andget_channel_metadata().get_stim_params(),set_stim_params(), andset_trigger_control().get_recording_config(),get_dsp_group(),set_dsp_group(),get_core_config(), andset_core_config().get_intan_impedance()andscan_ports().- DAC control:
get_dac_reg(),set_dac_gain(),set_dac_stream(),set_dac_off(), andset_dac_highpass(). - Digital output control:
get_dio_reg(),set_dio_events(),set_dio_manual(),set_dio_gated(), andset_dio_pulse(). - KPI signal-quality metrics:
get_kpi_metrics(),get_kpi_status(),set_kpi_packet_dur(), andset_kpi_update_period().
VidereClient (offline analysis)
link_data_file()andget_signals().get_dsp_group()andset_dsp_group().list_data_sources(),list_data_source_ids(),clear_data_sources(), andexport_data_source().get_kpi_metrics(),get_kpi_status(),kpi_calculate(),kpi_clear(), andset_kpi_packet_dur().
CurateClient (data curation)
slice_time(),slice_channels(), anddownsample().highpass(),lowpass(),bandpass(),bandstop(), andnotch().car(),virtual_ref(), andpaired_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.