From ad019e4d811d4f2cc935c9457aa38a4f32ed05a9 Mon Sep 17 00:00:00 2001 From: "!git for-each-ref --format='%(refname:short)' `git symbolic-ref HEAD`" Date: Tue, 15 Oct 2019 19:41:56 -0400 Subject: [PATCH 1/6] Created new extension --- ndx-ecog/README.md | 65 ++++++++++++++++++++++++++++++++++++++++++ ndx-ecog/ndx-meta.yaml | 8 ++++++ 2 files changed, 73 insertions(+) create mode 100644 ndx-ecog/README.md create mode 100644 ndx-ecog/ndx-meta.yaml diff --git a/ndx-ecog/README.md b/ndx-ecog/README.md new file mode 100644 index 0000000..39e508a --- /dev/null +++ b/ndx-ecog/README.md @@ -0,0 +1,65 @@ +# ndx-ecog Extension for NWB:N + +Author: Ben Dichter + +There are three data types, `Surface`, `CorticalSurfaces`, and `ECoGSubject`. `CorticalSurfaces` is simply a group (like a folder) to put `Surface` objects into. `Surface` holds surface mesh data (vertices and triangular faces) for sections of cortex. `ECoGSubject` is an extension of `Subject` that allows you to add the `CorticalSurfaces` object to `/general/subject`. + +## Usage + +### python + +install: +```bash +pip install ndx_ecog +``` + +write: +```python +import pynwb +from ndx_ecog import CorticalSurfaces, ECoGSubject + +nwbfile = pynwb.NWBFile(...) + +... + +cortical_surfaces = CorticalSurfaces() +## loop me + cortical_surfaces.create_surface(name=name, faces=faces, vertices=veritices) +## +nwbfile.subject = ECoGSubject(cortical_surfaces=cortical_surfaces) +``` + +You can optionally attach images of the subject's brain: +```python +from pynwb.base import Images +from pynwb.image import GrayscaleImage + +subject.images = Images(name='subject images', images=[GrayscaleImage('image1', data=image_data)]) +``` + +read: +```python +import nwbext_ecog +from pynwb import NWBHDF5IO +io = NWBHDF5IO('path_to_file.nwb','r') +nwb = io.read() +nwb.subject.cortical_surfaces +``` + +### MATLAB +install: +```matlab +generateExtension('/path/to/ndx-ecog/spec/ndx-ecog.namespace.yaml'); +``` + +write: +```matlab +cortical_surfaces = types.ecog.CorticalSurfaces; + +%%% loop me + surf = types.ecog.Surface('faces', faces, 'vertices', vertices); + cortical_surfaces.surface.set(surface_name, surf); +%%% + +file.subject = types.ecog.ECoGSubject(name, cortical_surfaces); +``` diff --git a/ndx-ecog/ndx-meta.yaml b/ndx-ecog/ndx-meta.yaml new file mode 100644 index 0000000..34808c0 --- /dev/null +++ b/ndx-ecog/ndx-meta.yaml @@ -0,0 +1,8 @@ +name: ndx-ecog +version: 0.1.0 +src: https://github.com/ben-dichter-consulting/ndx-ecog +pip: https://pypi.org/project/ndx-ecog/ +license: BSD +maintainers: + - bendichter + From b17e4b8dc4ed3e169b205c001cc2ff6ccfc73b63 Mon Sep 17 00:00:00 2001 From: Ryan Ly Date: Tue, 15 Oct 2019 19:06:13 -0700 Subject: [PATCH 2/6] Bump version to 0.1.1 --- ndx-ecog/ndx-meta.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndx-ecog/ndx-meta.yaml b/ndx-ecog/ndx-meta.yaml index 34808c0..08bc9f7 100644 --- a/ndx-ecog/ndx-meta.yaml +++ b/ndx-ecog/ndx-meta.yaml @@ -1,5 +1,5 @@ name: ndx-ecog -version: 0.1.0 +version: 0.1.1 src: https://github.com/ben-dichter-consulting/ndx-ecog pip: https://pypi.org/project/ndx-ecog/ license: BSD From 4567805bcd18a6368747f6930dd9baa6fd7ea9b7 Mon Sep 17 00:00:00 2001 From: "!git for-each-ref --format='%(refname:short)' `git symbolic-ref HEAD`" Date: Thu, 14 Nov 2019 17:00:19 -0800 Subject: [PATCH 3/6] add ndx-bipolar-referencing --- ndx_bipolar_referencing/README.md | 71 +++++++++++++++++++++++++++ ndx_bipolar_referencing/ndx-meta.yaml | 8 +++ 2 files changed, 79 insertions(+) create mode 100644 ndx_bipolar_referencing/README.md create mode 100644 ndx_bipolar_referencing/ndx-meta.yaml diff --git a/ndx_bipolar_referencing/README.md b/ndx_bipolar_referencing/README.md new file mode 100644 index 0000000..3957d1b --- /dev/null +++ b/ndx_bipolar_referencing/README.md @@ -0,0 +1,71 @@ +# ndx-bipolar-referencing Extension for NWB:N + +Structure for storing the bipolar schema of a recording in an NWB file. + +![schema schema](https://github.com/ben-dichter-consulting/ndx-bipolar-referencing/blob/master/docs/media/bipolar_reference_schema_schema.png?raw=true) + +## python installation +```bash +$ pip install ndx-bipolar-referencing +``` + +## python usage + +```python +from pynwb import NWBHDF5IO, NWBFile +from pynwb.file import DynamicTable, DynamicTableRegion +from datetime import datetime +from ndx_bipolar_referencing import EcephysExt +from pynwb.ecephys import ElectricalSeries + +import numpy as np + +nwbfile = NWBFile('description', 'id', datetime.now().astimezone()) + +device = nwbfile.create_device('device_name') + +electrode_group = nwbfile.create_electrode_group('electrode_group', + 'desc', 'loc', device=device) + +for _ in range(20): + nwbfile.add_electrode(np.nan, np.nan, np.nan, np.nan, 'loc', 'filt', + electrode_group) + +positive_electrodes = DynamicTableRegion('positive_electrodes', + np.arange(0, 20, 2), + 'desc', + nwbfile.electrodes) +negative_electrodes = DynamicTableRegion('negative_electrodes', + np.arange(1, 20, 2), + 'desc', + nwbfile.electrodes) + +bipolar_reference_scheme = DynamicTable(name='bipolar_reference_scheme', + description='desc', + columns=[positive_electrodes, + negative_electrodes]) + +ecephys_ext = EcephysExt(bipolar_reference_scheme=bipolar_reference_scheme) +nwbfile.add_lab_meta_data(ecephys_ext) + +bipolar_scheme = DynamicTableRegion( + name='electrodes', + data=np.arange(0, 10), + description='desc', + table=nwbfile.lab_meta_data['extracellular_electrophysiology_extensions'].bipolar_reference_scheme) + +ec_series = ElectricalSeries(name='test_ec_series', + description='desc', + data=np.random.rand(100, 10), + rate=1000., + electrodes=bipolar_scheme) + +nwbfile.add_acquisition(ec_series) + +with NWBHDF5IO('test_nwb.nwb', 'w') as io: + io.write(nwbfile) + +with NWBHDF5IO('test_nwb.nwb', 'r', load_namespaces=True) as io: + nwbfile = io.read() + print(nwbfile.acquisition['test_ec_series'].electrodes.table['positive_electrodes'].data) +``` diff --git a/ndx_bipolar_referencing/ndx-meta.yaml b/ndx_bipolar_referencing/ndx-meta.yaml new file mode 100644 index 0000000..52b81f2 --- /dev/null +++ b/ndx_bipolar_referencing/ndx-meta.yaml @@ -0,0 +1,8 @@ +name: ndx-bipolar-referencing +version: 0.1.2 +src: https://github.com/ben-dichter-consulting/ndx-bipolar-referencing +pip: https://pypi.org/project/ndx-bipolar-referencing/ +license: BSD +maintainers: + - bendichter + From 4e8718357a80bfecc2b6d3dcc2008d5ed35228ba Mon Sep 17 00:00:00 2001 From: "!git for-each-ref --format='%(refname:short)' `git symbolic-ref HEAD`" Date: Thu, 14 Nov 2019 17:02:19 -0800 Subject: [PATCH 4/6] remove ndx-ecog --- ndx-ecog/README.md | 65 ------------------------------------------ ndx-ecog/ndx-meta.yaml | 8 ------ 2 files changed, 73 deletions(-) delete mode 100644 ndx-ecog/README.md delete mode 100644 ndx-ecog/ndx-meta.yaml diff --git a/ndx-ecog/README.md b/ndx-ecog/README.md deleted file mode 100644 index 39e508a..0000000 --- a/ndx-ecog/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# ndx-ecog Extension for NWB:N - -Author: Ben Dichter - -There are three data types, `Surface`, `CorticalSurfaces`, and `ECoGSubject`. `CorticalSurfaces` is simply a group (like a folder) to put `Surface` objects into. `Surface` holds surface mesh data (vertices and triangular faces) for sections of cortex. `ECoGSubject` is an extension of `Subject` that allows you to add the `CorticalSurfaces` object to `/general/subject`. - -## Usage - -### python - -install: -```bash -pip install ndx_ecog -``` - -write: -```python -import pynwb -from ndx_ecog import CorticalSurfaces, ECoGSubject - -nwbfile = pynwb.NWBFile(...) - -... - -cortical_surfaces = CorticalSurfaces() -## loop me - cortical_surfaces.create_surface(name=name, faces=faces, vertices=veritices) -## -nwbfile.subject = ECoGSubject(cortical_surfaces=cortical_surfaces) -``` - -You can optionally attach images of the subject's brain: -```python -from pynwb.base import Images -from pynwb.image import GrayscaleImage - -subject.images = Images(name='subject images', images=[GrayscaleImage('image1', data=image_data)]) -``` - -read: -```python -import nwbext_ecog -from pynwb import NWBHDF5IO -io = NWBHDF5IO('path_to_file.nwb','r') -nwb = io.read() -nwb.subject.cortical_surfaces -``` - -### MATLAB -install: -```matlab -generateExtension('/path/to/ndx-ecog/spec/ndx-ecog.namespace.yaml'); -``` - -write: -```matlab -cortical_surfaces = types.ecog.CorticalSurfaces; - -%%% loop me - surf = types.ecog.Surface('faces', faces, 'vertices', vertices); - cortical_surfaces.surface.set(surface_name, surf); -%%% - -file.subject = types.ecog.ECoGSubject(name, cortical_surfaces); -``` diff --git a/ndx-ecog/ndx-meta.yaml b/ndx-ecog/ndx-meta.yaml deleted file mode 100644 index 08bc9f7..0000000 --- a/ndx-ecog/ndx-meta.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: ndx-ecog -version: 0.1.1 -src: https://github.com/ben-dichter-consulting/ndx-ecog -pip: https://pypi.org/project/ndx-ecog/ -license: BSD -maintainers: - - bendichter - From 80cb9edd23fa71a8a10e672563593c309a5db12b Mon Sep 17 00:00:00 2001 From: luiz Date: Mon, 12 Sep 2022 14:56:24 +0200 Subject: [PATCH 5/6] ndx pose --- ndx_bipolar_referencing/README.md | 71 ----------------- ndx_bipolar_referencing/ndx-meta.yaml | 8 -- ndx_pose/README.md | 110 ++++++++++++++++++++++++++ ndx_pose/ndx-meta.yaml | 8 ++ 4 files changed, 118 insertions(+), 79 deletions(-) delete mode 100644 ndx_bipolar_referencing/README.md delete mode 100644 ndx_bipolar_referencing/ndx-meta.yaml create mode 100644 ndx_pose/README.md create mode 100644 ndx_pose/ndx-meta.yaml diff --git a/ndx_bipolar_referencing/README.md b/ndx_bipolar_referencing/README.md deleted file mode 100644 index 3957d1b..0000000 --- a/ndx_bipolar_referencing/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# ndx-bipolar-referencing Extension for NWB:N - -Structure for storing the bipolar schema of a recording in an NWB file. - -![schema schema](https://github.com/ben-dichter-consulting/ndx-bipolar-referencing/blob/master/docs/media/bipolar_reference_schema_schema.png?raw=true) - -## python installation -```bash -$ pip install ndx-bipolar-referencing -``` - -## python usage - -```python -from pynwb import NWBHDF5IO, NWBFile -from pynwb.file import DynamicTable, DynamicTableRegion -from datetime import datetime -from ndx_bipolar_referencing import EcephysExt -from pynwb.ecephys import ElectricalSeries - -import numpy as np - -nwbfile = NWBFile('description', 'id', datetime.now().astimezone()) - -device = nwbfile.create_device('device_name') - -electrode_group = nwbfile.create_electrode_group('electrode_group', - 'desc', 'loc', device=device) - -for _ in range(20): - nwbfile.add_electrode(np.nan, np.nan, np.nan, np.nan, 'loc', 'filt', - electrode_group) - -positive_electrodes = DynamicTableRegion('positive_electrodes', - np.arange(0, 20, 2), - 'desc', - nwbfile.electrodes) -negative_electrodes = DynamicTableRegion('negative_electrodes', - np.arange(1, 20, 2), - 'desc', - nwbfile.electrodes) - -bipolar_reference_scheme = DynamicTable(name='bipolar_reference_scheme', - description='desc', - columns=[positive_electrodes, - negative_electrodes]) - -ecephys_ext = EcephysExt(bipolar_reference_scheme=bipolar_reference_scheme) -nwbfile.add_lab_meta_data(ecephys_ext) - -bipolar_scheme = DynamicTableRegion( - name='electrodes', - data=np.arange(0, 10), - description='desc', - table=nwbfile.lab_meta_data['extracellular_electrophysiology_extensions'].bipolar_reference_scheme) - -ec_series = ElectricalSeries(name='test_ec_series', - description='desc', - data=np.random.rand(100, 10), - rate=1000., - electrodes=bipolar_scheme) - -nwbfile.add_acquisition(ec_series) - -with NWBHDF5IO('test_nwb.nwb', 'w') as io: - io.write(nwbfile) - -with NWBHDF5IO('test_nwb.nwb', 'r', load_namespaces=True) as io: - nwbfile = io.read() - print(nwbfile.acquisition['test_ec_series'].electrodes.table['positive_electrodes'].data) -``` diff --git a/ndx_bipolar_referencing/ndx-meta.yaml b/ndx_bipolar_referencing/ndx-meta.yaml deleted file mode 100644 index 52b81f2..0000000 --- a/ndx_bipolar_referencing/ndx-meta.yaml +++ /dev/null @@ -1,8 +0,0 @@ -name: ndx-bipolar-referencing -version: 0.1.2 -src: https://github.com/ben-dichter-consulting/ndx-bipolar-referencing -pip: https://pypi.org/project/ndx-bipolar-referencing/ -license: BSD -maintainers: - - bendichter - diff --git a/ndx_pose/README.md b/ndx_pose/README.md new file mode 100644 index 0000000..be49a04 --- /dev/null +++ b/ndx_pose/README.md @@ -0,0 +1,110 @@ +# ndx-pose Extension for NWB + +[![PyPI version](https://badge.fury.io/py/ndx-pose.svg)](https://badge.fury.io/py/ndx-pose) + +ndx-pose is a standardized format for storing pose estimation data in NWB. It was developed initially to store the +output of [DeepLabCut](http://www.mackenziemathislab.org/deeplabcut) in NWB, but is also designed to store the output +of general pose estimation tools. Please post an issue or PR to suggest or add support for your favorite pose +estimation tool. + +This extension consists of two new neurodata types: +- `PoseEstimationSeries` which stores the estimated positions (x, y) or (x, y, z) of a body part over time as well as +the confidence/likelihood of the estimated positions. +- `PoseEstimation` which stores the estimated position data (`PoseEstimationSeries`) for multiple body parts, +computed from the same video(s) with the same tool/algorithm. + +## Installation + +`pip install ndx-pose` + +## Usage +```python +import datetime +import numpy as np +from pynwb import NWBFile, NWBHDF5IO +from ndx_pose import PoseEstimationSeries, PoseEstimation + +nwbfile = NWBFile( + session_description='session_description', + identifier='identifier', + session_start_time=datetime.datetime.now(datetime.timezone.utc) +) + +camera1 = nwbfile.create_device( + name='camera1', + description='left camera', + manufacturer='my manufacturer' +) +camera2 = nwbfile.create_device( + name='camera2', + description='right camera', + manufacturer='my manufacturer' +) + +data = np.random.rand(100, 3) # num_frames x (x, y, z) +timestamps = np.linspace(0, 10, num=100) # a timestamp for every frame +confidence = np.random.rand(100) # a confidence value for every frame +front_left_paw = PoseEstimationSeries( + name='front_left_paw', + description='Marker placed around fingers of front left paw.', + data=data, + unit='pixels', + reference_frame='(0,0,0) corresponds to ...', + timestamps=timestamps, + confidence=confidence, + confidence_definition='Softmax output of the deep neural network.', +) + +data = np.random.rand(100, 2) # num_frames x (x, y) +timestamps = np.linspace(0, 10, num=100) # a timestamp for every frame +confidence = np.random.rand(100) # a confidence value for every frame +front_right_paw = PoseEstimationSeries( + name='front_right_paw', + description='Marker placed around fingers of front right paw.', + data=data, + unit='pixels', + reference_frame='(0,0,0) corresponds to ...', + timestamps=front_left_paw, # link to timestamps of front_left_paw + confidence=confidence, + confidence_definition='Softmax output of the deep neural network.', +) + +pose_estimation_series = [front_left_paw, front_right_paw] + +pe = PoseEstimation( + pose_estimation_series=pose_estimation_series, + description='Estimated positions of front paws using DeepLabCut.', + original_videos=['camera1.mp4', 'camera2.mp4'], + labeled_videos=['camera1_labeled.mp4', 'camera2_labeled.mp4'], + dimensions=np.array([[640, 480], [1024, 768]], dtype='uint8'), + scorer='DLC_resnet50_openfieldOct30shuffle1_1600', + source_software='DeepLabCut', + source_software_version='2.2b8', + nodes=['front_left_paw', 'front_right_paw'], + edges=np.array([[0, 1]], dtype='uint8'), + # devices=[camera1, camera2], # this is not yet supported +) + +behavior_pm = nwbfile.create_processing_module( + name='behavior', + description='processed behavioral data' +) +behavior_pm.add(pe) + +path = 'test_pose.nwb' +with NWBHDF5IO(path, mode='w') as io: + io.write(nwbfile) + +with NWBHDF5IO(path, mode='r', load_namespaces=True) as io: + read_nwbfile = io.read() + read_pe = read_nwbfile.processing['behavior']['PoseEstimation'] + print(read_pe) +``` + + +## Contributors +- @rly +- @bendichter +- @AlexEMG + +This extension was created using [ndx-template](https://github.com/nwb-extensions/ndx-template). diff --git a/ndx_pose/ndx-meta.yaml b/ndx_pose/ndx-meta.yaml new file mode 100644 index 0000000..55b7f22 --- /dev/null +++ b/ndx_pose/ndx-meta.yaml @@ -0,0 +1,8 @@ +name: ndx-pose +version: 0.1.1 +src: https://github.com/rly/ndx-pose +pip: https://pypi.org/project/ndx-pose +license: BSD +maintainers: + - rly + - bendichter From 3eda85f382c2f2681bfbdced6247710a4d355752 Mon Sep 17 00:00:00 2001 From: Luiz Tauffer Date: Wed, 21 Jun 2023 17:02:45 +0200 Subject: [PATCH 6/6] Update ndx_pose/README.md Co-authored-by: Ben Dichter --- ndx_pose/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ndx_pose/README.md b/ndx_pose/README.md index be49a04..edfa8f7 100644 --- a/ndx_pose/README.md +++ b/ndx_pose/README.md @@ -3,7 +3,7 @@ [![PyPI version](https://badge.fury.io/py/ndx-pose.svg)](https://badge.fury.io/py/ndx-pose) ndx-pose is a standardized format for storing pose estimation data in NWB. It was developed initially to store the -output of [DeepLabCut](http://www.mackenziemathislab.org/deeplabcut) in NWB, but is also designed to store the output +output of [DeepLabCut](http://www.mackenziemathislab.org/deeplabcut) in NWB, and is designed to store the output of general pose estimation tools. Please post an issue or PR to suggest or add support for your favorite pose estimation tool.