AnimalAnalyzer#

class neurodent.analysis.AnimalAnalyzer(ao)[source]#

Bases: object

Runs analysis on a loaded AnimalOrganizer, owning the results.

Analysis state (bad_channels_dict, features_df, window_analysis_result, frequency_domain_spike_analysis_results) is stored on the instance, so reuse a single AnimalAnalyzer(ao) across compute_bad_channels / compute_windowed_analysis / compute_frequency_domain_spike_analysis. Computing bad channels on one instance and windowed analysis on a separate AnimalAnalyzer(ao) will yield a result with empty bad channels on the second instance.

Parameters:

ao (AnimalOrganizer) – A loaded organizer whose recordings are analyzed.

__init__(ao)[source]#
compute_bad_channels(
lof_threshold: float | None = None,
force_recompute: bool = False,
lof_chunk_duration_s: float = 60,
)[source]#

Compute bad channels using LOF analysis for all recordings.

Parameters:
  • lof_threshold (float, optional) – Threshold for determining bad channels from LOF scores. If None, only computes/loads scores without setting bad_channel_names.

  • force_recompute (bool) – Whether to recompute LOF scores even if they exist.

  • lof_chunk_duration_s (float) – Duration in seconds of each chunk used for the pairwise-distance computation in LOF. Defaults to 60.

apply_lof_threshold(lof_threshold: float)[source]#

Apply threshold to existing LOF scores to determine bad channels for all recordings.

Parameters:

lof_threshold (float) – Threshold for determining bad channels.

get_all_lof_scores() → dict[source]#

Get LOF scores for all recordings.

Returns:

Dictionary mapping animal days to LOF score dictionaries.

Return type:

dict

compute_windowed_analysis(
features: list[str],
exclude: list[str] = [],
window_s=5,
multiprocess_mode: Literal['dask', 'serial'] = 'serial',
suppress_short_interval_error=False,
apply_notch_filter=True,
chunk_duration_s: float | None = 3600,
**kwargs,
) → WindowAnalysisResult[source]#

Computes windowed analysis of animal recordings. The data is divided into windows (time bins), then features are extracted from each window. The result is formatted to a Dataframe and wrapped into a WindowAnalysisResult object.

Parameters:
  • features (list[str]) – List of features to compute. See individual compute_...() functions for output format

  • exclude (list[str], optional) – List of features to ignore. Will override the features parameter. Defaults to [].

  • window_s (int, optional) – Length of each window in seconds. Note that some features break with very short window times. Defaults to 5.

  • multiprocess_mode (Literal["dask", "serial"], optional) – Whether to compute windows in parallel with Dask, one task per window, or serially. Process-level parallelism requires an active dask.distributed Client. The Dask path drops the last fragment unconditionally, even when it is a full window, so it yields one fewer window than “serial”. Defaults to “serial”.

  • suppress_short_interval_error (bool, optional) – If True, suppress ValueError for short intervals between timestamps in resulting WindowAnalysisResult. Useful for aggregated WARs. Defaults to False.

  • apply_notch_filter (bool, optional) – Whether to apply notch filtering to remove line noise. Uses constants.LINE_FREQ. Defaults to True.

  • chunk_duration_s (float, optional) – Duration in seconds of data to hold in memory at once during the Dask processing path. Internally converted to a number of fragments via int(chunk_duration_s / window_s). When None, all fragments are loaded into a single NumPy array before being written to the intermediate zarr store — the original behavior, which maximizes throughput but requires enough RAM to hold the entire recording at once. When set to a positive value, only the corresponding number of fragments are buffered at a time, streaming them to zarr incrementally; use a small value (e.g. 250) on memory-constrained machines and a larger value (e.g. 2500+) on high-memory nodes for maximum throughput. Only has an effect when multiprocess_mode="dask". Defaults to 3600.

Raises:

AttributeError – If a feature’s compute_...() function was not implemented, this error will be raised.

Returns:

A WindowAnalysisResult object containing extracted features for all recordings

Return type:

WindowAnalysisResult

compute_frequency_domain_spike_analysis(
detection_params: dict | None = None,
chunk_duration_s: float = 3600,
multiprocess_mode: Literal['dask', 'serial'] = 'serial',
)[source]#

Compute frequency-domain spike detection on all long recordings.

Parameters:
  • detection_params (dict, optional) – Detection parameters. Uses defaults if None.

  • chunk_duration_s (float) – Duration in seconds of each processing chunk. Defaults to 3600 (1 hour). The full recording is always analysed; this parameter controls peak RAM by processing in overlapping chunks. None loads the full recording at once (fastest).

  • multiprocess_mode (Literal["dask", "serial"]) – Whether to detect spikes in parallel with Dask or serially. Defaults to “serial”.

Returns:

Results for each recording session

Return type:

list[FrequencyDomainSpikeAnalysisResult]

Raises:

ImportError – If SpikeInterface is not available