https://github.com/catalystneuro/tank-lab-to-nwb
Science Score: 10.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
○codemeta.json file
-
○.zenodo.json file
-
○DOI references
-
○Academic publication links
-
✓Committers with academic emails
2 of 7 committers (28.6%) from academic institutions -
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (9.2%) to scientific vocabulary
Keywords from Contributors
Repository
Basic Info
- Host: GitHub
- Owner: catalystneuro
- License: mit
- Language: Python
- Default Branch: main
- Size: 429 KB
Statistics
- Stars: 0
- Watchers: 3
- Forks: 2
- Open Issues: 0
- Releases: 0
Metadata Files
README.md
tank-lab-to-nwb
NWB conversion scripts and tutorials. A collaboration with the Tank lab, funded by the Simons Foundation.
Install
bash
$ pip install tank-lab-to-nwb
Usage
There are two ways to go about converting Neuropixel and Virmen behavior data.
(1) The primary processing pipeline synchronizes the task data with the electrophysiology data through TTL pulse and writes the spiking output to the same NWB file.
The required arguments for the use of the relevant functions are denoted in the comments of their respective sections of the conversion script. These include the file or folder locations of the data to be converted to NWB format, as well as several optional fields such as Subject information (species/age/weight).
After editing the conversion script convert_towers.py with the proper path for Neuropixel and behavior data,
the conversion can be executed from the terminal:
bash
$ cd tank-lab-to-nwb
$ python tank_lab_to_nwb/convert_towers_task/convert_towers.py
Alternatively, the conversion can be done using a custom tailored jupyter notebook spikeinterface_pipeline.ipynb
that can be launched from the terminal:
bash
$ jupyter notebook notebooks/spikeinterface_pipeline.ipynb
(2) The NWBFile can be inspected by reading it from a python script: ```python from pynwb import NWBHDF5IO
filepath = 'TowersTaskstub.nwb'
io = NWBHDF5IO(filepath, 'r')
nwb = io.read()
print(nwb)
Alternatively, the NWB data can be visualized with `nwb-jupyter-widgets` in a jupyter notebook:
bash
$ jupyter notebook notebooks/towerstaskcustomwidget.ipynb
python
from pynwb import NWBHDF5IO
from nwbwidgets import nwb2widget
from tanklabtonwb.nwbwidgets import customtimeserieswidgetforbehavior
from nwbwidgets.view import defaultneurodatavisspec
import pynwb
filepath = 'TowersTaskstub.nwb' io = NWBHDF5IO(file_path, 'r') nwb = io.read()
defaultneurodatavisspec[pynwb.TimeSeries] = customtimeserieswidgetfor_behavior nwb2widget(nwb) ```
Background
Behavioral data mapping
The behavioral data is contained in .matfiles similar to the form:
PoissonBlocksReboot4_cohort4_Bezos3_E65_T_20180202.mat
This matlab file contains a struct (log) which contains several fields relevant for conversion.
The list of fields that are extracted from this struct can be found below.
NWBFile
Location in Virmen (.mat) file | Location in NWB file | Description
------------- | ------------- | -------------
log.session.start | nwb.session_start_time | datetime when session started
[not in file] | nwb.session_description | additional information about session (optional)
[name of file] | nwb.session_id| unique identifier of the session
Subject
Location in Virmen (.mat) file | Location in NWB file | Description
------------- | ------------- | -------------
log.session.start | nwb.subject.age | age (days) in isoformat (optional)
[not in file] | nwb.species | information about the species (optional)
log.animal.name | nwb.subject_id| identifier of the subject
[not in file] | nwb.genotype| information about the genotype (optional)
[not in file] | nwb.sex| information about the sex of the subject (optional)
LabMetaData
The lab specific metadata is populated in tank_lab_to_nwb/convert_towers_task/virmenbehaviordatainterface.py
using the custom extension ndx-tank-metadata
built for extending the NWB LabMetaData schema with the required fields:
Location in Virmen (.mat) file | Location in NWB file | Description
------------- | ------------- | -------------
log.version.code | nwb.lab_meta_data['LabMetaData'].experiment_name | name of experiment run
log.version.name | nwb.lab_meta_data['LabMetaData'].world_file_name | name of world run
log.animal.protocol | nwb.lab_meta_data['LabMetaData'].protocol_name| name of protocol run
log.animal.stimulusBank | nwb.lab_meta_data['LabMetaData'].stimulus_bank_path| path of stimulus bank file
log.version.repository | nwb.lab_meta_data['LabMetaData'].commit_id| commit id for session run
log.session.end | nwb.lab_meta_data['LabMetaData'].session_end_time| datetime when session ended
log.version.rig.rig | nwb.lab_meta_data['LabMetaData'].location| name of rig where session was run
[not in file] | nwb.lab_meta_data['LabMetaData'].num_trials| number of trials in the session
[not in file] | nwb.lab_meta_data['LabMetaData'].session_performance| performance of correct responses in % (optional)*
log.version.rig | nwb.lab_meta_data['LabMetaData'].rig.fields| rig information
log.version.mazes | nwb.lab_meta_data['LabMetaData'].mazes.to_dataframe()| maze information
* session_performance can be edited from virmenbehaviordatainterface.py.
Rig
Rig information is converted from a log.version.rig struct object to a dictionary like as in this example:
{'rig': 'NPX',
'simulationMode': 1,
'hasDAQ': 1,
'hasSyncComm': 0,
'minIterationDT': 0.01,
'arduinoPort': 'COM18',
'sensorDotsPerRev': array([2469.2, 2469.2, 2469.2, 2469.2]),
'ballCircumference': 63.8,
'toroidXFormP1': 0.3879,
'toroidXFormP2': 0.392,
'colorAdjustment': array([0. , 0.4, 0.5]),
'soundAdjustment': 0.2,
'nidaqDevice': 1,
'nidaqPort': 1,
'nidaqLines': array([ 0, 11], dtype=int32),
'syncClockChannel': 5,
'syncDataChannel': 6,
'rewardChannel': 0,
'rewardSize': 0.004,
'rewardDuration': 0.05,
'laserChannel': 1,
'rightPuffChannel': 2,
'leftPuffChannel': 3}
#### Mazes
Maze information is converted to a DynamicTable
object that can be converted to a pandas dataframe by calling .to_dataframe() as in this example:
| id | world | lStart | lCue | lMemory | cueDuration | cueVisibleAt | cueProbability | ... | blockPerform |-----|--------|---------|-------|----------|--------------|---------------|-----------------|-----------------|-----------------| | 0 | 1 | 5 | 45 | 10 | nan | inf | inf | ... | 0.7 | 1 | 1 | 30 | 120 | 20 | nan | inf | inf | ... | 0.7 | 2 | 1 | 30 | 220 | 20 | nan | inf | inf | ... | 0.7 | 3 | 1 | 30 | 300 | 20 | nan | inf | inf | ... | 0.7 | 4 | 1 | 30 | 380 | 20 | nan | inf | inf | ... | 0.7
Epochs
Location in Virmen (.mat) file | Location in NWB file | Description
------------- | ------------- | -------------
| index of log.blockstructure | nwb.intervals['epochs'].id | number of epoch in session |
| log.block.mazeID| nwb.intervals['epochs'].maze_id | number of maze in epoch|
| log.block.mainMazeID | nwb.intervals['epochs'].main_maze_id | number of maze of "highest" level for subject |
| log.block.easyBlockFlag | nwb.intervals['epochs'].easy_epoch | 1 if block was flagged as easy (mazeid < mainmazeid) |
| log.block.firstTrial | `nwb.intervals['epochs'].firsttrial| first trial run in an epoch |
| [not in file] |nwb.intervals['epochs'].numtrials | number of trials for each epoch |
|log.block.start|nwb.intervals['epochs'].starttime| datetime when epoch started with respect to the start time of the session|
|log.block.duration|nwb.intervals['epochs'].duration| epoch duration in seconds |
|log.block.rewardMiL|nwb.intervals['epochs'].reward_ml `| ml of reward in an epoch|
Trials
Location in Virmen (.mat) file | Location in NWB file | Description
------------- | ------------- | -------------
| [not in file] | nwb.intervals['trials'].id | unique identifier of trial for all epochs |
| index of log.block.trial | nwb.intervals['trials'].trial_id | identifier of trial within an epoch |
| log.block.trial.trialType| nwb.intervals['trials'].trial_type | type of trial (L=Left, R=Right)|
| log.block.trial.choice | nwb.intervals['trials'].choice | (L=Left, R=Right, nil=Trial violation) |
| log.block.trial.start | nwb.intervals['trials'].start_time | start time of trial with respect to the start time of the epoch|
| log.block.trial.duration | nwb.intervals['trials'].duration | duration of trial in seconds |
| log.block.trial.iterations| nwb.intervals['trials'].iterations| number of frames in a trial |
| log.block.trial.iCueEntry | nwb.intervals['trials'].iCueEntry | iteration # when subject entered cue region|
| log.block.trial.iMemEntry | nwb.intervals['trials'].iMemEntry | iteration # when subject entered memory region|
| log.block.trial.iTurnEntry | nwb.intervals['trials'].iTurnEntry | iteration # when subject entered turn region|
| log.block.trial.iArmEntry | nwb.intervals['trials'].iArmEntry | iteration # when subject entered arm region|
| log.block.trial.iBlank | nwb.intervals['trials'].iBlank | iteration # when screen if turned off|
| log.block.trial.cueCombo | nwb.intervals['trials'].left_cue_presence, nwb.intervals['trials'].right_cue_presence | indicates if nth cue appeared on left or right |
| log.block.trial.cuePosition | nwb.intervals['trials'].left_cue_position, nwb.intervals['trials'].right_cue_position | position in maze for each cue |
| log.block.trial.cueOnset | nwb.intervals['trials'].left_cue_onset, nwb.intervals['trials'].right_cue_onset | iteration number when cues appeared in trial |
| log.block.trial.cueOffset | nwb.intervals['trials'].left_cue_offset, nwb.intervals['trials'].right_cue_offset | iteration number when cues disappeared in trial |
| log.block.trial.excessTravel | nwb.intervals['trials'].excessTravel| parameter that measures extra distance run by subject |
| log.block.trial.rewardScale | nwb.intervals['trials'].rewardScale| Multiplier of reward for each correct trial |
Behavior
Position, ViewAngle, Velocity, Collision
Location in Virmen (.mat) file | Location in NWB file | Description
------------- | ------------- | -------------
| log.block.trial.time | nwb.processing['behavior'].data_interfaces['Time']| time vector for each frame measured by Virmen |
| log.block.trial.position | nwb.processing['behavior'].data_interfaces['Position'].spatial_series| position matrix for each frame (X(cm), Y(cm))|
| log.block.trial.position | nwb.processing['behavior'].data_interfaces['ViewAngle'].spatial_series| viewAngle for each frame (degrees)|
| log.block.trial.velocity | nwb.processing['behavior'].data_interfaces['Velocity']| velocity matrix for each frame (X(cm/s), Y(cm/s))|
| log.block.trial.collision |nwb.processing['behavior'].data_interfaces['Collision']| for each frame 1= collision detected|
Owner
- Name: CatalystNeuro
- Login: catalystneuro
- Kind: organization
- Email: hello@catalystneuro.com
- Website: catalystneuro.com
- Twitter: catalystneuro
- Repositories: 87
- Profile: https://github.com/catalystneuro
GitHub Events
Total
Last Year
Committers
Last synced: over 3 years ago
All Time
- Total Commits: 161
- Total Committers: 7
- Avg Commits per committer: 23.0
- Development Distribution Score (DDS): 0.584
Top Committers
| Name | Commits | |
|---|---|---|
| weiglszonja | w****a@g****m | 67 |
| Cody Baker | c****9@n****u | 46 |
| Cody Baker | 5****D@u****m | 19 |
| Michael Scheid | m****5@u****u | 12 |
| Ben Dichter | b****r@g****m | 12 |
| Alessio Buccino | a****7@g****m | 4 |
| luiztauffer | l****r@h****m | 1 |
Committer Domains (Top 20 + Academic)
Issues and Pull Requests
Last synced: 12 months ago
All Time
- Total issues: 1
- Total pull requests: 33
- Average time to close issues: 5 days
- Average time to close pull requests: 4 days
- Total issue authors: 1
- Total pull request authors: 5
- Average comments per issue: 0.0
- Average comments per pull request: 1.06
- Merged pull requests: 30
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 0
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 0
- Pull request authors: 0
- Average comments per issue: 0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
- bendichter (1)
Pull Request Authors
- weiglszonja (14)
- CodyCBakerPhD (13)
- alejoe91 (4)
- MRScheid (1)
- bendichter (1)
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 1
-
Total downloads:
- pypi 17 last-month
- Total dependent packages: 0
- Total dependent repositories: 1
- Total versions: 2
- Total maintainers: 2
pypi.org: tank-lab-to-nwb
NWB conversion scripts and tutorials.
- Homepage: https://github.com/catalystneuro/tank-lab-to-nwb
- Documentation: https://tank-lab-to-nwb.readthedocs.io/
- License: mit
-
Latest release: 0.2.0
published over 5 years ago