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)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ndx_rate_maps-0.1.0.tar.gz | 20.5 kB | Without provenance | Details for ndx_rate_maps-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ndx_rate_maps-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for ndx_rate_maps-0.1.0-py3-none-any.whl |
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
|
Security for ndx-rate-maps 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.