Basic Usage Tutorial#

This tutorial will walk you through the basic workflow of using Neurodent for rodent EEG analysis.

Overview#

Neurodent provides a streamlined workflow for:

  1. Loading EEG recordings from various formats

  2. Extracting features from continuous data (Windowed Analysis)

  3. Visualizing and analyzing results

Let’s get started!

1. Installation and Setup#

First, ensure you have Neurodent installed. See the Installation Guide for detailed instructions.

pip install neurodent

Or with uv:

uv init yourprojectname
cd yourprojectname
uv add neurodent

2. Import Required Modules#

Let’s import the necessary modules from Neurodent:

Tip: To see detailed progress information during processing, check out the Configuration Guide to learn how to enable logging.

from pathlib import Path
import matplotlib.pyplot as plt

from neurodent import core, visualization, constants

3. Configure Temporary Directory (Optional)#

Neurodent uses a temporary directory for intermediate files during processing. You can set this to a location with sufficient space:

# Set temporary directory for intermediate files
# core.set_temp_directory("/path/to/your/temp/dir")

# Or use the default temp directory
print(f"Using temp directory: {core.get_temp_directory()}")

4. Load EEG Data#

Neurodent supports multiple data formats:

  • Binary files (.bin)

  • SpikeInterface recordings

  • MNE objects

  • Neuroscope/Neuralynx (.dat, .eeg)

  • Open Ephys (.continuous)

  • NWB files (.nwb)

Let’s load data using LongRecordingOrganizer:

# Example: Loading from binary files
# Replace with your actual data path
data_path = Path("/path/to/your/data/folder")
animal_id = "your_animal_id"

# Create LongRecordingOrganizer
# mode options: 'bin', 'si' (SpikeInterface), 'mne', etc.
lro = core.LongRecordingOrganizer(
    base_folder=data_path,
    animal_id=animal_id,
    mode="bin",  # Change based on your data format
)

print(f"Loaded recordings for {animal_id}")
print(f"Number of recordings: {len(lro.recordings)}")

5. Create Animal Organizer#

The AnimalOrganizer wraps the LongRecordingOrganizer and provides methods for computing features:

# Create AnimalOrganizer from LongRecordingOrganizer
ao = visualization.AnimalOrganizer(lro)

print(f"Animal Organizer created for {ao.animal_id}")

6. Compute Windowed Analysis Results (WAR)#

Now we can compute features from the EEG data. Neurodent extracts features in time windows:

Available Features:#

Linear Features (per channel):

  • rms: RMS amplitude

  • logrms: Log RMS amplitude

  • ampvar: Amplitude variance

  • logampvar: Log amplitude variance

  • psdtotal: Total PSD power

  • logpsdtotal: Log total PSD power

  • psdslope: PSD slope

  • nspike: Number of spikes detected

  • lognspike: Log number of spikes

Band Features (per frequency band: delta, theta, alpha, beta, gamma):

  • psdband: Band power

  • logpsdband: Log band power

  • psdfrac: Fractional band power

  • logpsdfrac: Log fractional band power

Connectivity/Matrix Features (between channels):

  • cohere: Coherence

  • zcohere: Z-scored coherence

  • imcoh: Imaginary coherence

  • zimcoh: Z-scored imaginary coherence

  • pcorr: Pearson correlation

  • zpcorr: Z-scored Pearson correlation

Spectral Features:

  • psd: Full power spectral density

# Compute windowed analysis with selected features
# You can specify 'all' or list specific features
features = ['rms', 'psdband', 'cohere']

war = ao.compute_windowed_analysis(
    features=features,
    multiprocess_mode='serial'  # Options: 'serial', 'multiprocess', 'dask'
)

print(f"Windowed analysis completed!")
print(f"Features computed: {features}")

7. Filter and Clean Data#

Neurodent provides filtering methods to remove artifacts and outliers:

# Apply filtering using method chaining
war_filtered = (
    war
    .filter_logrms_range(z_range=3)  # Remove outliers based on log RMS
    .filter_high_rms(max_rms=500)     # Remove high amplitude artifacts
    .filter_low_rms(min_rms=50)       # Remove low amplitude periods
    .filter_reject_channels_by_session()  # Reject bad channels
)

print("Filtering completed!")

8. Basic Visualization#

Single Animal Plots#

Use AnimalPlotter to visualize data over time from a single animal. Note: Do NOT aggregate time windows before plotting - the plotter needs the temporal data intact:

# Create plotter for single animal
ap = visualization.AnimalPlotter(war_filtered)

# Plot RMS over time
fig = ap.plot_linear_temporal(features=['rms'])
plt.show()

# Plot PSD band powers
fig = ap.plot_psd_spectrogram()
plt.show()

9. Aggregate Time Windows (Optional)#

You can flatten all windows into a single value by averaging across time. This saves memory and gives you a summary statistic across an entire session.

Note: You should not aggregate before plotting time-series data with AnimalPlotter, as this removes the temporal information needed for over-time visualizations.

# Example: Aggregate for summary statistics
# Only do this if you need a single value per animal/session
war_aggregated = war_filtered.copy()
war_aggregated.aggregate_time_windows()

Multi-Animal Comparison#

To compare across multiple animals, use ExperimentPlotter. You can use either the temporal data (war_filtered) or aggregated data (war_aggregated) depending on your analysis needs:

# If you have multiple WARs (from multiple animals)
wars = [war_filtered]  # In practice, you'd load multiple animals

# Create experiment plotter
ep = visualization.ExperimentPlotter(
    wars,
    exclude=['nspike', 'lognspike']  # Features to exclude from plots
)

# Create categorical plot grouped by genotype
g = ep.plot_catplot(
    'rms',
    groupby='genotype',
    kind='box',
    catplot_params={'showfliers': False}
)
plt.show()

# Plot PSD band powers grouped by genotype
g = ep.plot_catplot(
    'psdband',
    groupby='genotype',
    x='genotype',
    hue='band',
    kind='box',
    collapse_channels=True,
    catplot_params={'showfliers': False}
)
plt.show()

10. Save Results#

You can save your WAR objects for later analysis:

# Save WAR to disk
output_path = Path("./output") / animal_id
output_path.mkdir(parents=True, exist_ok=True)

war_filtered.to_pickle_and_json(output_path)
print(f"WAR saved to {output_path}")

# Load WAR from disk
war_loaded = visualization.WindowAnalysisResult.load_pickle_and_json(output_path)
print(f"WAR loaded from {output_path}")

Summary#

In this tutorial, you learned how to:

  1. Import and configure Neurodent

  2. Load EEG data using LongRecordingOrganizer

  3. Create an AnimalOrganizer for feature extraction

  4. Compute windowed analysis features (WindowAnalysisResult)

  5. Filter and clean data

  6. (Optionally) Aggregate time windows for summary statistics

  7. Visualize results using AnimalPlotter and ExperimentPlotter

  8. Save and load results

Next Steps#