Skip to main content

ndx-rate-maps Extension for NWB

NWB extension for storing rate maps (spatial firing rate maps, tuning curves).

RateMapTable is a DynamicTable where each row holds a rate map for one unit. It supports both 1D tuning curves (e.g., head direction) and 2D spatial rate maps (e.g., place cells). All maps in a table share the same binning. For multiple conditions, create separate table instances.

Installation

pip install ndx-rate-maps

For development:

git clone https://github.com/catalystneuro/ndx-rate-maps.git
cd ndx-rate-maps
pip install -e .

Usage

2D spatial rate maps

import numpy as np
from datetime import datetime
from zoneinfo import ZoneInfo
from pynwb import NWBFile, NWBHDF5IO
from pynwb.behavior import Position, SpatialSeries
from hdmf.common import DynamicTableRegion, VectorData
from ndx_rate_maps import RateMapTable

# Create NWBFile and add units
nwbfile = NWBFile(
    session_description="session",
    identifier="id",
    session_start_time=datetime.now(ZoneInfo("UTC")),
)
nwbfile.add_unit_column("location", "brain region")
for i in range(3):
    nwbfile.add_unit(spike_times=np.array([1.0, 2.0, 3.0]) + i, location="CA1")

# Create rate map table
num_units = 3
num_bins_x, num_bins_y = 50, 50

rate_maps = RateMapTable(
    name="place_rate_maps",
    description="2D spatial rate maps, 2cm bins, gaussian-smoothed",
    bin_edges_dim0=np.linspace(0, 100, num_bins_x + 1),  # x bin edges in cm
    dim0_label="x_position",
    dim0_unit="cm",
    bin_edges_dim1=np.linspace(0, 100, num_bins_y + 1),  # y bin edges in cm
    dim1_label="y_position",
    dim1_unit="cm",
    smoothing_kernel="gaussian",
    smoothing_kernel_width=3.0,  # in cm (same units as bin edges)
    units=DynamicTableRegion(
        name="units",
        data=list(range(num_units)),
        description="units for each rate map",
        table=nwbfile.units,
    ),
    rate_map=VectorData(
        name="rate_map",
        description="Rate map values in Hz",
        data=np.random.rand(num_units, num_bins_x, num_bins_y),
    ),
    occupancy_map=VectorData(
        name="occupancy_map",
        description="Time spent per bin in seconds",
        data=np.random.rand(num_units, num_bins_x, num_bins_y),
    ),
)

# Add to processing module
module = nwbfile.create_processing_module("behavior", "Behavioral data")
module.add(rate_maps)

# Write
with NWBHDF5IO("example.nwb", "w") as io:
    io.write(nwbfile)

# Read
with NWBHDF5IO("example.nwb", "r") as io:
    read_nwb = io.read()
    read_table = read_nwb.processing["behavior"]["place_rate_maps"]
    print(read_table.unit_of_measurement)  # "Hz"
    print(read_table["rate_map"][0].shape)  # (50, 50)

1D head direction tuning curves

num_bins = 60

hd_maps = RateMapTable(
    name="hd_tuning_curves",
    description="Head direction tuning curves, 6-degree bins",
    bin_edges_dim0=np.linspace(0, 2 * np.pi, num_bins + 1),  # radians
    dim0_label="head_direction",
    dim0_unit="radians",
    units=DynamicTableRegion(
        name="units",
        data=list(range(num_units)),
        description="units for each tuning curve",
        table=nwbfile.units,
    ),
    rate_map=VectorData(
        name="rate_map",
        description="Rate map values in Hz",
        data=np.random.rand(num_units, num_bins),
    ),
)

Time support

Link the rate maps to the time intervals over which they were computed:

from pynwb.epoch import TimeIntervals

# Create intervals for the run epochs used to compute rate maps
time_support = TimeIntervals(name="time_support", description="run epochs")
time_support.add_interval(start_time=0.0, stop_time=120.0)
time_support.add_interval(start_time=200.0, stop_time=350.0)

module.add(time_support)

rate_maps.time_support = time_support

This also works with nwbfile.trials, nwbfile.epochs, or any TimeIntervals table.

Multiple conditions

Create separate tables for each condition:

left_trials = RateMapTable(
    name="rate_maps_left_trials",
    description="Rate maps for left-choice trials",
    # ... same structure as above
)
right_trials = RateMapTable(
    name="rate_maps_right_trials",
    description="Rate maps for right-choice trials",
    # ... same structure as above
)

Schema

RateMapTable (extends DynamicTable)

Field Type Required Description
unit_of_measurement text (fixed: "Hz") Yes Unit for rate values
smoothing_kernel text No Smoothing kernel type (e.g., "gaussian")
smoothing_kernel_width float64 No Kernel width, in same units as bin edges
dim0_label text Yes Label for the first dimension (e.g., "x_position")
dim0_unit text Yes Unit of measurement for the first dimension (e.g., "cm")
dim1_label text No Label for the second dimension (2D only)
dim1_unit text No Unit of measurement for the second dimension (2D only)
bin_edges_dim0 float64 array Yes Bin edges along first dimension
bin_edges_dim1 float64 array No Bin edges along second dimension (2D only)
units DynamicTableRegion Yes Reference to Units table
rate_map VectorData (float64) Yes Rate map values in Hz
occupancy_map VectorData (float64) No Time spent per bin in seconds
spike_count_map VectorData (float64) No Spike count per bin
source_timeseries link to TimeSeries No Source behavioral timeseries
time_support link to TimeIntervals No Time intervals over which rate maps were computed

This extension was created using ndx-template.

Metadata

Release files for ndx-rate-maps 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ndx-rate-maps 0.1.0
File Size Uploaded
ndx_rate_maps-0.1.0.tar.gz 20.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ndx-rate-maps 0.1.0
File Interpreter ABI Platform
ndx_rate_maps-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 28.8 kB

Release files / ndx_rate_maps-0.1.0.tar.gz

Download URL ndx_rate_maps-0.1.0.tar.gz
Size 20.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5f08beb4fc30131ec224b750af7dff256438aabb4d0414f6e3f59710b0f24b77
BLAKE2b-256 checksum
How to use checksums
e9f785a8584c90bed15808ec7c8ded6c35f4d5c2f6816e82fa43dc959eca7861
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / ndx_rate_maps-0.1.0-py3-none-any.whl

Download URL ndx_rate_maps-0.1.0-py3-none-any.whl
Size 8.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a03a2bc57e80ad30e741dbe8cde726c808c96c8127af6267191dda2c98c451d0
BLAKE2b-256 checksum
How to use checksums
6709137a6b2fdca50d9c65b04a202e6270ee197d3ca9507d7eacf6cefec122a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page