Tutorial 4 - NWB Conversion¶
Neurodata without borders (NWB) is the data standard that we employ for data storage, packaging and sharing. More information about the NWB project can be found here: https://pynwb.readthedocs.io/en/stable/index.html
We have created some basic functionality to package and store imaging+ data into NWB files.
When generated here, the NWB files will automatically store: - Raw imaging data - Imaging microscope parameters - Time series data channels - ROIs and their extracted raw Flu array (if available for imaging+ trial)
These NWB files can be further modified according to NWB specifications and methods. Please refer to the PyNWB documentation for further additions according to your needs.
Below, we demonstrate how to generate a NWB file from an existing imaging+ data object. Note that one .nwb file is created for one imaging trial.
[2]:
# import necessary modules
from pynwb.file import Subject
from imagingplus.utils.io import import_obj
from imagingplus.utils import nwb
imported imagingplus successfully
version: 0.2-beta
[2]:
# setup a Subject corresponding to the imaging trial
subject = Subject(age='P60D', subject_id='HF113',
genotype='CamkIIa-GCaMP6s/Niell'
)
# load up imaging trial
expobj = import_obj(pkl_path='/mnt/qnap_share/Data/imagingplus-example/imagingplus-test-analysis/HF113_analysis.pkl')
trialobj = expobj.load_trial(expobj.trialIDs[0])
# set some additional metadata required for generating NWB files.
expobj.experimenter = 'P. Shah'
expobj.lab = 'Packer Lab'
expobj.institution = 'University of Oxford'
trialobj.optical_channel_name = 'GCaMP imaging channel'
|- Loaded imagingplus.Experiment object (expID: HF113)agingplus-test-analysis/HF113_analysis.pkl ...
|- Loaded 'HF113 t-001 (TwoPhotonImagingTrial experimental object)'t-analysis/2021-01-31_t-001.pkl ...
[3]:
# create the nwb file
inwb = nwb.newImagingNWB(expobj=expobj, nwb_subject=subject, trialobj=trialobj, save=True, add_raw_tiff=True, indicator='GCaMP6s')
# options: set `add_raw_tiff` = False to skip adding the raw imaging tiffstack to the new NWB file.
# options: set `save` = False to skip saving the new NWB file.
[NWB processing]: Adding 2photon imaging series to nwb file ...
[NWB processing]: Adding temporal series to nwb file ...
** Saving nwb file to: /mnt/qnap_share/Data/imagingplus-example/imagingplus-test-analysis/2021-01-31_t-001.nwb
The NWB file will be saved by default in the same location as the imaging+ analysis object.
To read in a previously collected NWB file, use the readImagingNWB() function from the nwb module.
[3]:
nwbfilepath = '/mnt/qnap_share/Data/imagingplus-example/imagingplus-test-analysis/2021-01-31_t-001.nwb'
enwb = nwb.readImagingNWB(filename=nwbfilepath)
print(enwb)
[NWB processing]: Reading NWB file from:
/mnt/qnap_share/Data/imagingplus-example/imagingplus-test-analysis/2021-01-31_t-001.nwb
root pynwb.file.NWBFile at 0x139712757930928
Fields:
acquisition: {
ImagingTrial <class 'pynwb.ophys.TwoPhotonSeries'>,
frame_clock <class 'pynwb.base.TimeSeries'>,
opto_loopback <class 'pynwb.base.TimeSeries'>,
shutter_loopback <class 'pynwb.base.TimeSeries'>,
voltage <class 'pynwb.base.TimeSeries'>
}
devices: {
Bruker 2pPlus <class 'pynwb.device.Device'>
}
experimenter: ['P. Shah']
file_create_date: [datetime.datetime(2022, 10, 21, 17, 5, 6, 732531, tzinfo=tzlocal())]
identifier: HF113
imaging_planes: {
Plane 0 <class 'pynwb.ophys.ImagingPlane'>
}
institution: University of Oxford
lab: Packer Lab
processing: {
Pre-processed imaging data <class 'pynwb.base.ProcessingModule'>
}
session_description: two photon imaging + LFP dataset
session_start_time: 2022-10-21 17:05:06.732041+00:00
subject: subject pynwb.file.Subject at 0x139712760172704
Fields:
age: P60D
genotype: CamkIIa-GCaMP6s/Niell
subject_id: HF113
timestamps_reference_time: 2022-10-21 17:05:06.732041+00:00
Note
Saving a NWB file: Oddly, once an NWB file is saved, it is difficult to change the location of the NWB file. For example, NWB doesn’t allow the following:
[11]:
from pynwb import NWBHDF5IO
path = '/mnt/qnap_share/Data/imagingplus-example/imagingplus-test-analysis/2021-01-31_t-001_copy.nwb'
with NWBHDF5IO(path, 'w') as io:
io.write(enwb)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/tmp/ipykernel_50119/297517569.py in <module>
2 path = '/mnt/qnap_share/Data/imagingplus-example/imagingplus-test-analysis/2021-01-31_t-001_copy.nwb'
3 with NWBHDF5IO(path, 'w') as io:
----> 4 io.write(enwb)
~/anaconda3/envs/plipy39/lib/python3.9/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
643 def func_call(*args, **kwargs):
644 pargs = _check_args(args, kwargs)
--> 645 return func(args[0], **pargs)
646 else:
647 def func_call(*args, **kwargs):
~/anaconda3/envs/plipy39/lib/python3.9/site-packages/hdmf/backends/hdf5/h5tools.py in write(self, **kwargs)
356
357 cache_spec = popargs('cache_spec', kwargs)
--> 358 super().write(**kwargs)
359 if cache_spec:
360 self.__cache_spec()
~/anaconda3/envs/plipy39/lib/python3.9/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
643 def func_call(*args, **kwargs):
644 pargs = _check_args(args, kwargs)
--> 645 return func(args[0], **pargs)
646 else:
647 def func_call(*args, **kwargs):
~/anaconda3/envs/plipy39/lib/python3.9/site-packages/hdmf/backends/io.py in write(self, **kwargs)
48 """Write a container to the IO source."""
49 container = popargs('container', kwargs)
---> 50 f_builder = self.__manager.build(container, source=self.__source, root=True)
51 self.write_builder(f_builder, **kwargs)
52
~/anaconda3/envs/plipy39/lib/python3.9/site-packages/hdmf/utils.py in func_call(*args, **kwargs)
643 def func_call(*args, **kwargs):
644 pargs = _check_args(args, kwargs)
--> 645 return func(args[0], **pargs)
646 else:
647 def func_call(*args, **kwargs):
~/anaconda3/envs/plipy39/lib/python3.9/site-packages/hdmf/build/manager.py in build(self, **kwargs)
165 else:
166 if container.container_source != source:
--> 167 raise ValueError("Cannot change container_source once set: '%s' %s.%s"
168 % (container.name, container.__class__.__module__,
169 container.__class__.__name__))
ValueError: Cannot change container_source once set: 'root' pynwb.file.NWBFile
[ ]:
