NWB extension for the Guppy fiber photometry processing tool
Project description
ndx-guppy Extension for NWB
This is an NWB extension for storing the derived outputs of the GuPPy (Guided Photometry Analysis in Python) fiber-photometry processing tool.
GuPPy is a processing tool, not an acquisition system. This extension represents only the products GuPPy
computes — normalized traces, detected transients, peri-event PSTHs, cross-correlations, and the parameters
used — for a single session. Raw signal/control traces and behavioral events remain owned by the acquisition
and events interfaces (e.g. ndx-fiber-photometry and
pyNWB's core EventsTable).
The design turns GuPPy's organizing features into structured, queryable NWB features:
- recording_site and event are entities, so they live as rows in registry tables
(
GuppyRecordingSitesTable,GuppyEventsTable) and are referenced byDynamicTableRegion. Recording-site and event identity is defined once and referenced everywhere — no free-text strings to keep in sync. - trace_type is a closed category (
control_fit/dff/z_score), so it is a plain enumerated text attribute stamped directly on each object. - event is the one unbounded axis (you can align to arbitrarily many behavioral events), so the
event-bearing products (
GuppyPSTH,GuppyPeakAUC,GuppyCrossCorrelation) emit one object per condition and concatenate every event's trials inside it — keeping the object count independent of how many events a session has.
Cross-extension dependencies are quarantined: products reference ndx-guppy's own registry tables, and any
outward link to the acquisition FiberPhotometryTable or to a behavioral-events object is an optional
column on a registry. A GuPPy file can therefore stand alone or be fully wired to acquisition/events.
Neurodata Types
Registries
GuppyRecordingSitesTable(extendsDynamicTable) — one row per GuPPy recording site (e.g.dms). A recording site is a signal channel paired with its optional isosbestic control. A slim registry: therecording_sitename plus an optional raggedfiber_photometry_table_regionDTR linking each recording site to its signal + isosbestic fiber rows in the acquisitionFiberPhotometryTable(anatomy is reached through this link, not duplicated). The fiber link is populated at conversion time by a converter that owns the acquisition side.GuppyEventsTable(extendsDynamicTable) — one row per behavioral event GuPPy aligned to (e.g.port_entries). A slim registry: theevent_nameplus an optional raggedeventsDTR selecting this event type's occurrence rows in the mergedpynwb.event.EventsTable(innwbfile.events). The events link is populated at conversion time by a converter that merges every event type into oneEventsTable.
Derived traces
GuppyDerivedResponseSeries(extendsndx_fiber_photometry.FiberPhotometryResponseSeries) — a derived continuous trace (control_fit,dff, orz_score) for one recording site. Adds atrace_typeattribute and arecording_sitereference intoGuppyRecordingSitesTable; the physical fiber provenance is reached through that recording-site row (itsfiber_photometry_table_region), so the inherited per-seriesfiber_photometry_table_regionis left unpopulated.
Analysis products
-
GuppyTransientsTable(extendsDynamicTable) — detected transient peaks for one (recording_site, trace_type); columnstimestamp,amplitude; attributestrace_type,unit. -
GuppyTransientSummaryTable(extendsDynamicTable) — per-session summary, one row per (recording_site, trace_type); columnsrecording_site,trace_type,frequency_per_min,mean_amplitude. -
GuppyPSTH(extendsNWBDataInterface) — peri-event PSTH for one (recording_site, trace_type) condition, with every event's trials concatenated along the trials axis: a(num_samples, num_trials)tracesmatrix labeled by a per-trialeventreference,mean/errorof shape(num_samples, num_events)labeled by asummary_eventreference, and optional binning concatenated across events with abin_eventreference. -
GuppyCrossCorrelation(extendsNWBDataInterface) — peri-event cross-correlation for one (trace_type, recording-site-pair) condition, concatenated across events: a(num_lags, num_trials)trialsmatrix with per-trialevent,mean/errorof shape(num_lags, num_events)withsummary_event, and optional binning withbin_event. -
GuppyPeakAUC(extendsNWBDataInterface) — peak/area summary of a PSTH for one (recording_site, trace_type) condition, concatenated across events. GuPPy computespeak_positive/peak_negative/area_under_curvefor every trial, every bin, and the across-trial mean within each peak window, so each per-trial metric is a(num_windows, num_trials)matrix (per-trialevent), each mean metric is(num_windows, num_events)(summary_event), and the optional per-bin metrics carry abin_eventreference. -
GuppyValidSignalIntervals(extendsTimeIntervals) — the[start, stop]windows GuPPy retained as valid signal (not removed as artifacts) during preprocessing, one row per interval with arecording_siteDynamicTableRegionintoGuppyRecordingSitesTable. The removal method is recorded once onGuppyParameters.artifacts_removal_method.
Parameters
GuppyParameters(extendsLabMetaData) — one per session: typed GuPPy processing parameters (version, z-score method, baseline windows, transient thresholds, PSTH windows, etc.) fromGuPPyParamtersUsed.json.
Installation
pip install ndx-guppy
Or, for development, from a clone of this repository:
pip install -e .
Usage
import numpy as np
from datetime import datetime
from dateutil.tz import tzlocal
from hdmf.common.table import DynamicTableRegion
from pynwb import NWBFile, NWBHDF5IO
from ndx_guppy import (
GuppyRecordingSitesTable,
GuppyEventsTable,
GuppyParameters,
GuppyDerivedResponseSeries,
GuppyTransientsTable,
GuppyPSTH,
GuppyCrossCorrelation,
)
nwbfile = NWBFile(
session_description="A GuPPy-processed fiber photometry session.",
identifier="guppy-session-0",
session_start_time=datetime.now(tzlocal()),
)
# Typed session parameters live in /general.
nwbfile.add_lab_meta_data(
GuppyParameters(
name="guppy_parameters",
guppy_version="2.0.0a7",
zscore_method="standard",
baseline_window_start=0.0,
baseline_window_end=30.0,
transients_thresh=2.0,
)
)
# A processing module holds the registries and all derived products.
module = nwbfile.create_processing_module(name="guppy", description="GuPPy-derived outputs")
# Registries: recording-site and event identity, defined once. Slim by design — the fiber and event
# links are populated at conversion time by a converter that owns the acquisition and events tables.
recording_sites = GuppyRecordingSitesTable(name="recording_sites", description="GuPPy recording sites")
recording_sites.add_row(recording_site="dms")
recording_sites.add_row(recording_site="dls")
events = GuppyEventsTable(name="events", description="GuPPy behavioral events")
events.add_row(event_name="port_entries")
module.add(recording_sites)
module.add(events)
# A derived trace: trace_type stamped, recording_site referenced.
z_score_dms = GuppyDerivedResponseSeries(
name="z_score_dms",
data=np.random.randn(1000),
unit="a.u.",
trace_type="z_score",
recording_site=DynamicTableRegion(name="recording_site", data=[0], description="dms", table=recording_sites),
rate=30.0,
)
module.add(z_score_dms)
# Transient peaks for one (recording_site, trace_type). recording_site is a per-row DynamicTableRegion column.
transients = GuppyTransientsTable(
name="transients_dms_z_score",
description="GuPPy-detected z_score transients in dms",
trace_type="z_score",
unit="a.u.",
target_tables={"recording_site": recording_sites},
)
transients.add_row(recording_site=0, timestamp=1.5, amplitude=2.3)
transients.add_row(recording_site=0, timestamp=4.2, amplitude=1.8)
module.add(transients)
# A peri-event PSTH for the (dms, z_score) condition. Trials from every event are concatenated along
# the trials axis: `event` labels each trial, `summary_event` labels each mean/error column. Here all
# three trials happen to be the same event, so num_events = 1.
psth = GuppyPSTH(
name="psth_dms_z_score",
description="Peri-event PSTH for the (dms, z_score) condition.",
trace_type="z_score",
baseline_corrected=True,
unit="a.u.",
recording_site=DynamicTableRegion(name="recording_site", data=[0], description="dms", table=recording_sites),
event=DynamicTableRegion(name="event", data=[0, 0, 0], description="per-trial event", table=events),
summary_event=DynamicTableRegion(name="summary_event", data=[0], description="per-event column", table=events),
peri_event_time=np.linspace(-1.0, 2.0, 90),
trial_onset_times=np.array([10.0, 20.0, 30.0]),
traces=np.random.randn(90, 3), # (num_samples, num_trials)
mean=np.zeros((90, 1)), # (num_samples, num_events)
error=np.zeros((90, 1)),
)
module.add(psth)
# A cross-correlation for the (z_score, dms-dls) condition: recording_site references two rows, trials are
# concatenated across events just like the PSTH.
cross_correlation = GuppyCrossCorrelation(
name="xcorr_z_score_dms_dls",
description="Cross-correlation for the (z_score, dms-dls) condition.",
trace_type="z_score",
unit="a.u.",
recording_site=DynamicTableRegion(name="recording_site", data=[0, 1], description="dms, dls", table=recording_sites),
event=DynamicTableRegion(name="event", data=[0, 0, 0], description="per-trial event", table=events),
summary_event=DynamicTableRegion(name="summary_event", data=[0], description="per-event column", table=events),
lag=np.linspace(-1.0, 1.0, 101),
trial_onset_times=np.array([10.0, 20.0, 30.0]),
trials=np.random.randn(101, 3), # (num_lags, num_trials)
mean=np.zeros((101, 1)), # (num_lags, num_events)
error=np.zeros((101, 1)),
)
module.add(cross_correlation)
with NWBHDF5IO("guppy_session.nwb", mode="w") as io:
io.write(nwbfile)
with NWBHDF5IO("guppy_session.nwb", mode="r", load_namespaces=True) as io:
read_nwbfile = io.read()
guppy = read_nwbfile.processing["guppy"]
print(guppy["z_score_dms"].trace_type) # "z_score"
print(guppy["psth_dms_z_score"].traces.shape) # (90, 3) -> (num_samples, num_trials)
print(read_nwbfile.lab_meta_data["guppy_parameters"].zscore_method) # "standard"
Extension Diagram
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#ffffff', 'lineColor': '#333'}}}%%
classDiagram
direction LR
class FiberPhotometryResponseSeries {
<<ndx-fiber-photometry>>
}
class FiberPhotometryTable {
<<ndx-fiber-photometry>>
}
class GuppyDerivedResponseSeries {
<<ndx-guppy>>
--
attribute trace_type : text
DynamicTableRegion recording_site
}
FiberPhotometryResponseSeries <|-- GuppyDerivedResponseSeries
class GuppyRecordingSitesTable {
<<ndx-guppy>>
--
VectorData recording_site
DynamicTableRegion fiber_photometry_table_region [optional, ragged]
}
class GuppyEventsTable {
<<ndx-guppy>>
--
VectorData event_name
DynamicTableRegion events [optional, ragged]
}
class GuppyValidSignalIntervals {
<<ndx-guppy>>
TimeIntervals
--
DynamicTableRegion recording_site
}
class GuppyTransientsTable {
<<ndx-guppy>>
--
attribute trace_type, unit : text
DynamicTableRegion recording_site
VectorData timestamp, amplitude
}
class GuppyTransientSummaryTable {
<<ndx-guppy>>
--
DynamicTableRegion recording_site
VectorData trace_type, frequency_per_min, mean_amplitude
}
class GuppyPSTH {
<<ndx-guppy>>
--
attribute description, trace_type, unit : text
attribute baseline_corrected : bool
DynamicTableRegion recording_site
DynamicTableRegion event, summary_event, bin_event
dataset traces (num_samples, num_trials)
dataset mean (num_samples, num_events)
}
class GuppyCrossCorrelation {
<<ndx-guppy>>
--
attribute description, trace_type, unit : text
DynamicTableRegion recording_site (2)
DynamicTableRegion event, summary_event, bin_event
dataset trials (num_lags, num_trials)
dataset mean (num_lags, num_events)
}
class GuppyPeakAUC {
<<ndx-guppy>>
--
attribute description, trace_type, unit : text
DynamicTableRegion recording_site
DynamicTableRegion event, summary_event, bin_event
dataset peak_positive (num_windows, num_trials)
dataset mean_peak_positive (num_windows, num_events)
}
class GuppyParameters {
<<ndx-guppy>>
LabMetaData
}
GuppyDerivedResponseSeries ..> GuppyRecordingSitesTable : recording_site
GuppyTransientsTable ..> GuppyRecordingSitesTable : recording_site
GuppyTransientSummaryTable ..> GuppyRecordingSitesTable : recording_site
GuppyPSTH ..> GuppyRecordingSitesTable : recording_site
GuppyPSTH ..> GuppyEventsTable : event
GuppyCrossCorrelation ..> GuppyRecordingSitesTable : recording_site (2)
GuppyCrossCorrelation ..> GuppyEventsTable : event
GuppyPeakAUC ..> GuppyRecordingSitesTable : recording_site
GuppyPeakAUC ..> GuppyEventsTable : event
GuppyValidSignalIntervals ..> GuppyRecordingSitesTable : recording_site
GuppyRecordingSitesTable ..> FiberPhotometryTable : optional outward link (ragged)
GuppyEventsTable ..> EventsTable : optional outward link (ragged)
This extension was created using ndx-template.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ndx_guppy-0.1.0.tar.gz.
File metadata
- Download URL: ndx_guppy-0.1.0.tar.gz
- Upload date:
- Size: 35.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4ebf9cbad3109a16f20a0ab5820ae8600aba814a76b305b35df7aeff9c47103
|
|
| MD5 |
f7e97f559735321fb81389cba1ef4847
|
|
| BLAKE2b-256 |
edabbedded6541314f09d2e5aa09f1b1bb7be9384f5790ac6301ad6efadae0b3
|
Provenance
The following attestation bundles were made for ndx_guppy-0.1.0.tar.gz:
Publisher:
auto-publish.yml on catalystneuro/ndx-guppy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ndx_guppy-0.1.0.tar.gz -
Subject digest:
c4ebf9cbad3109a16f20a0ab5820ae8600aba814a76b305b35df7aeff9c47103 - Sigstore transparency entry: 2187885353
- Sigstore integration time:
-
Permalink:
catalystneuro/ndx-guppy@0404ab5fe5b5e70486543de9547b43e795fc647a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/catalystneuro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
auto-publish.yml@0404ab5fe5b5e70486543de9547b43e795fc647a -
Trigger Event:
release
-
Statement type:
File details
Details for the file ndx_guppy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ndx_guppy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
349f6f732bf6c31f81dbf35dd9f53c7d5088c266aff12f80e5aa0b8d4b02516c
|
|
| MD5 |
bb3528cda6b095cde729548175043dbc
|
|
| BLAKE2b-256 |
499a90a406ce636773119fb063bd001aa23faaac8b2c2fd4ec6bc710bbbee37b
|
Provenance
The following attestation bundles were made for ndx_guppy-0.1.0-py3-none-any.whl:
Publisher:
auto-publish.yml on catalystneuro/ndx-guppy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ndx_guppy-0.1.0-py3-none-any.whl -
Subject digest:
349f6f732bf6c31f81dbf35dd9f53c7d5088c266aff12f80e5aa0b8d4b02516c - Sigstore transparency entry: 2187885354
- Sigstore integration time:
-
Permalink:
catalystneuro/ndx-guppy@0404ab5fe5b5e70486543de9547b43e795fc647a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/catalystneuro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
auto-publish.yml@0404ab5fe5b5e70486543de9547b43e795fc647a -
Trigger Event:
release
-
Statement type: