Skip to content

Commit

Permalink
Merge pull request #482 from NeurodataWithoutBorders/enh/analysis
Browse files Browse the repository at this point in the history
final changes before minor release
  • Loading branch information
ajtritt authored Apr 24, 2018
2 parents e21a7c1 + ccd7a29 commit 9b52025
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 32 deletions.
4 changes: 2 additions & 2 deletions docs/gallery/domain/ophys.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@


optical_channel = OpticalChannel('my_optchan', 'Ca2+ imaging example',
'pi wavelength', '3.14')
'pi wavelength', 500.)
imaging_plane = nwbfile.create_imaging_plane('my_imgpln',
'Ca2+ imaging example',
optical_channel,
'a very interesting part of the brain',
'imaging_device_1',
'6.28', '2.718', 'GFP', 'my favorite brain location',
600., '2.718', 'GFP', 'my favorite brain location',
(1, 2, 1, 2, 3), 4.0, 'manifold unit', 'A frame to refer to')


Expand Down
4 changes: 2 additions & 2 deletions docs/gallery/general/linking_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,5 +252,5 @@
#
# External links are convenient but to share data we may want to hand a single file with all the
# data to our collaborator rather than having to collect all relevant files. To do this,
# :py:class:`~pynwb.from.backends.hdf5.h5tools.HDF5IO` (and in turn :py:class:`~pynwb.NWBHDF5IO`)
# provide the convenience function :py:func:`~pynwb.from.backends.hdf5.h5tools.HDF5IO.copy_file`
# :py:class:`~pynwb.form.backends.hdf5.h5tools.HDF5IO` (and in turn :py:class:`~pynwb.NWBHDF5IO`)
# provide the convenience function :py:func:`~pynwb.form.backends.hdf5.h5tools.HDF5IO.copy_file`
4 changes: 4 additions & 0 deletions src/pynwb/data/nwb.file.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ groups:
end users. Such data should be placed in the analysis group. The analysis data
should be documented so that it is sharable with other labs'
name: analysis
groups:
- doc: Custom analysis results
neurodata_type_inc: NWBContainer
quantity: '*'
- doc: "Experimental intervals, whether that be logically distinct sub-experiments\
\ having a particular scientific goal, trials during an experiment, or epochs\
\ deriving from analysis of data. COMMENT: Epochs provide pointers to time\
Expand Down
4 changes: 2 additions & 2 deletions src/pynwb/data/nwb.ophys.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ groups:
dtype: text
name: device
- doc: Excitation wavelength
dtype: text
dtype: float
name: excitation_lambda
- doc: Rate images are acquired, in Hz.
dtype: text
Expand Down Expand Up @@ -283,7 +283,7 @@ groups:
dtype: text
name: description
- doc: Emission lambda for channel
dtype: text
dtype: float
name: emission_lambda
doc: 'One of possibly many groups storing channel-specific data COMMENT: Name
is arbitrary but should be meaningful'
Expand Down
6 changes: 6 additions & 0 deletions src/pynwb/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ class NWBFile(MultiContainerInterface):
'type': NWBDataInterface,
'get': 'get_acquisition'
},
{
'attr': 'analysis',
'add': 'add_analysis',
'type': NWBContainer,
'get': 'get_analysis'
},
{
'attr': 'stimulus',
'add': 'add_stimulus',
Expand Down
5 changes: 4 additions & 1 deletion src/pynwb/form/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ class Container(with_metaclass(abc.ABCMeta, object)):
{'name': 'parent', 'type': 'Container', 'doc': 'the Container that holds this Container', 'default': None},
{'name': 'container_source', 'type': str, 'doc': 'the source of this container', 'default': None})
def __init__(self, **kwargs):
self.__name = getargs('name', kwargs)
name = getargs('name', kwargs)
if '/' in name:
raise ValueError("name '" + name + "' cannot contain '/'")
self.__name = name
self.__parent = getargs('parent', kwargs)
self.__container_source = getargs('container_source', kwargs)
self.__children = list()
Expand Down
6 changes: 3 additions & 3 deletions src/pynwb/ophys.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class OpticalChannel(NWBContainer):
@docval({'name': 'name', 'type': str, 'doc': 'the name of this electrode'},
{'name': 'source', 'type': str, 'doc': 'the source of the data'},
{'name': 'description', 'type': str, 'doc': 'Any notes or comments about the channel.'},
{'name': 'emission_lambda', 'type': str, 'doc': 'Emission lambda for channel.'},
{'name': 'emission_lambda', 'type': float, 'doc': 'Emission lambda for channel.'},
{'name': 'parent', 'type': 'NWBContainer',
'doc': 'The parent NWBContainer for this NWBContainer', 'default': None})
def __init__(self, **kwargs):
Expand Down Expand Up @@ -57,11 +57,11 @@ class ImagingPlane(NWBContainer):
'doc': 'One of possibly many groups storing channelspecific data.'},
{'name': 'description', 'type': str, 'doc': 'Description of this ImagingPlane.'},
{'name': 'device', 'type': str, 'doc': 'Name of device in /general/devices'},
{'name': 'excitation_lambda', 'type': str, 'doc': 'Excitation wavelength.'},
{'name': 'excitation_lambda', 'type': float, 'doc': 'Excitation wavelength.'},
{'name': 'imaging_rate', 'type': str, 'doc': 'Rate images are acquired, in Hz.'},
{'name': 'indicator', 'type': str, 'doc': 'Calcium indicator'},
{'name': 'location', 'type': str, 'doc': 'Location of image plane.'},
{'name': 'manifold', 'type': Iterable, 'doc': 'Physical position of each pixel. height, weight, x, y, z.',
{'name': 'manifold', 'type': Iterable, 'doc': 'Physical position of each pixel. height, weight, xyz.',
'default': None},
{'name': 'conversion', 'type': float,
'doc': 'Multiplier to get from stored values to specified unit (e.g., 1e-3 for millimeters)',
Expand Down
24 changes: 12 additions & 12 deletions tests/integration/ui_write/test_ophys.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class TestImagingPlaneIO(base.TestMapRoundTrip):

def setUpContainer(self):
self.optical_channel = OpticalChannel('optchan1', 'unit test TestImagingPlaneIO',
'a fake OpticalChannel', '3.14')
'a fake OpticalChannel', 500.)
return ImagingPlane('imgpln1', 'unit test TestImagingPlaneIO', self.optical_channel,
'a fake ImagingPlane', 'imaging_device_1', '6.28', '2.718', 'GFP', 'somewhere in the brain')
'a fake ImagingPlane', 'imaging_device_1', 600., '2.718', 'GFP', 'somewhere in the brain')

def setUpBuilder(self):
optchan_builder = GroupBuilder(
Expand All @@ -37,7 +37,7 @@ def setUpBuilder(self):
'source': 'unit test TestImagingPlaneIO'},
datasets={
'description': DatasetBuilder('description', 'a fake OpticalChannel'),
'emission_lambda': DatasetBuilder('emission_lambda', '3.14')},
'emission_lambda': DatasetBuilder('emission_lambda', 500.)},
)
return GroupBuilder(
'imgpln1',
Expand All @@ -49,7 +49,7 @@ def setUpBuilder(self):
datasets={
'description': DatasetBuilder('description', 'a fake ImagingPlane'),
'device': DatasetBuilder('device', 'imaging_device_1'),
'excitation_lambda': DatasetBuilder('excitation_lambda', '6.28'),
'excitation_lambda': DatasetBuilder('excitation_lambda', 600.),
'imaging_rate': DatasetBuilder('imaging_rate', '2.718'),
'indicator': DatasetBuilder('indicator', 'GFP'),
'location': DatasetBuilder('location', 'somewhere in the brain')},
Expand All @@ -70,10 +70,10 @@ def getContainer(self, nwbfile):
class TestTwoPhotonSeries(base.TestDataInterfaceIO):

def make_imaging_plane(self, source):
self.optical_channel = OpticalChannel('optchan1', source, 'a fake OpticalChannel', '3.14')
self.optical_channel = OpticalChannel('optchan1', source, 'a fake OpticalChannel', 500.)
self.imaging_plane = ImagingPlane('imgpln1', source, self.optical_channel,
'a fake ImagingPlane',
'imaging_device_1', '6.28', '2.718', 'GFP', 'somewhere in the brain')
'imaging_device_1', 600., '2.718', 'GFP', 'somewhere in the brain')

def setUpContainer(self):
self.make_imaging_plane('unit test TestTwoPhotonSeries')
Expand All @@ -95,7 +95,7 @@ def setUpBuilder(self):
'source': 'unit test TestTwoPhotonSeries'},
datasets={
'description': DatasetBuilder('description', 'a fake OpticalChannel'),
'emission_lambda': DatasetBuilder('emission_lambda', '3.14')},
'emission_lambda': DatasetBuilder('emission_lambda', 500.)},
)
imgpln_builder = GroupBuilder(
'imgpln1',
Expand All @@ -107,7 +107,7 @@ def setUpBuilder(self):
datasets={
'description': DatasetBuilder('description', 'a fake ImagingPlane'),
'device': DatasetBuilder('device', 'imaging_device_1'),
'excitation_lambda': DatasetBuilder('excitation_lambda', '6.28'),
'excitation_lambda': DatasetBuilder('excitation_lambda', 600.),
'imaging_rate': DatasetBuilder('imaging_rate', '2.718'),
'indicator': DatasetBuilder('indicator', 'GFP'),
'location': DatasetBuilder('location', 'somewhere in the brain')},
Expand Down Expand Up @@ -167,13 +167,13 @@ def buildPlaneSegmentation(self):
starting_frame=[1, 2, 3], format='tiff', timestamps=list())

self.optical_channel = OpticalChannel('test_optical_channel', 'optical channel source',
'optical channel description', '3.14')
'optical channel description', 500.)
self.imaging_plane = ImagingPlane('test_imaging_plane',
'ophys integration tests',
self.optical_channel,
'imaging plane description',
'imaging_device_1',
'6.28', '2.718', 'GFP', 'somewhere in the brain',
600., '2.718', 'GFP', 'somewhere in the brain',
(1, 2, 1, 2, 3), 4.0, 'manifold unit', 'A frame to refer to')

self.img_mask = deepcopy(img_mask)
Expand All @@ -195,7 +195,7 @@ def get_plane_segmentation_builder(self):
'source': 'optical channel source'},
datasets={
'description': DatasetBuilder('description', 'optical channel description'),
'emission_lambda': DatasetBuilder('emission_lambda', '3.14')},
'emission_lambda': DatasetBuilder('emission_lambda', 500.)},
)
self.imgpln_builder = GroupBuilder(
'imgpln1',
Expand All @@ -207,7 +207,7 @@ def get_plane_segmentation_builder(self):
datasets={
'description': DatasetBuilder('description', 'imaging plane description'),
'device': DatasetBuilder('device', 'imaging_device_1'),
'excitation_lambda': DatasetBuilder('excitation_lambda', '6.28'),
'excitation_lambda': DatasetBuilder('excitation_lambda', 600.),
'imaging_rate': DatasetBuilder('imaging_rate', '2.718'),
'indicator': DatasetBuilder('indicator', 'GFP'),
'manifold': DatasetBuilder('manifold', (1, 2, 1, 2, 3),
Expand Down
52 changes: 52 additions & 0 deletions tests/unit/form_tests/test_container.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import unittest2 as unittest

from pynwb.form.container import Container


class MyTestClass(Container):

def __init__(self, src, name, parent=None):
super(MyTestClass, self).__init__(src, name, parent=parent)

def basic_add(self, **kwargs):
return kwargs

def basic_add2(self, **kwargs):
return kwargs

def basic_add2_kw(self, **kwargs):
return kwargs


class MyTestSubclass(MyTestClass):

def basic_add(self, **kwargs):
return kwargs

def basic_add2_kw(self, **kwargs):
return kwargs


class TestNWBContainer(unittest.TestCase):

def test_constructor(self):
"""Test that constructor properly sets parent
"""
parent_obj = MyTestClass('test source', 'obj1')
child_obj = MyTestSubclass('test source', 'obj2', parent=parent_obj)
self.assertIs(child_obj.parent, parent_obj)

def test_set_parent_parent(self):
"""Test that parent setter properly sets parent
"""
parent_obj = MyTestClass('test source', 'obj1')
child_obj = MyTestSubclass('test source', 'obj2')
child_obj.parent = parent_obj
self.assertIs(child_obj.parent, parent_obj)

def test_slash_restriction(self):
self.assertRaises(ValueError, Container, 'bad/name')


if __name__ == '__main__':
unittest.main()
20 changes: 10 additions & 10 deletions tests/unit/pynwb_tests/test_ophys.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def CreatePlaneSegmentation():
iSS = ImageSeries(name='test_iS', source='a hypothetical source', data=list(), unit='unit',
external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list())

oc = OpticalChannel('test_optical_channel', 'test_source', 'description', 'emission_lambda')
ip = ImagingPlane('test_imaging_plane', 'test_source', oc, 'description', 'device', 'excitation_lambda',
oc = OpticalChannel('test_optical_channel', 'test_source', 'description', 500.)
ip = ImagingPlane('test_imaging_plane', 'test_source', oc, 'description', 'device', 600.,
'imaging_rate', 'indicator', 'location', (1, 2, 1, 2, 3), 4.0, 'unit', 'reference_frame')

pS = PlaneSegmentation('test source', 'description', ip, 'test_name', iSS)
Expand All @@ -29,19 +29,19 @@ def CreatePlaneSegmentation():

class TwoPhotonSeriesConstructor(unittest.TestCase):
def test_init(self):
oc = OpticalChannel('test_name', 'test_source', 'description', 'emission_lambda')
oc = OpticalChannel('test_name', 'test_source', 'description', 500.)
self.assertEqual(oc.description, 'description')
self.assertEqual(oc.emission_lambda, 'emission_lambda')
self.assertEqual(oc.emission_lambda, 500.)

ip = ImagingPlane('test_imaging_plane', 'test source', oc, 'description', 'device', 'excitation_lambda',
'imaging_rate', 'indicator', 'location', (1, 2, 1, 2, 3), 4.0, 'unit', 'reference_frame')
ip = ImagingPlane('test_imaging_plane', 'test source', oc, 'description', 'device', 600.,
'imaging_rate', 'indicator', 'location', (50, 100, 3), 4.0, 'unit', 'reference_frame')
self.assertEqual(ip.optical_channel[0], oc)
self.assertEqual(ip.device, 'device')
self.assertEqual(ip.excitation_lambda, 'excitation_lambda')
self.assertEqual(ip.excitation_lambda, 600.)
self.assertEqual(ip.imaging_rate, 'imaging_rate')
self.assertEqual(ip.indicator, 'indicator')
self.assertEqual(ip.location, 'location')
self.assertEqual(ip.manifold, (1, 2, 1, 2, 3))
self.assertEqual(ip.manifold, (50, 100, 3))
self.assertEqual(ip.conversion, 4.0)
self.assertEqual(ip.unit, 'unit')
self.assertEqual(ip.reference_frame, 'reference_frame')
Expand Down Expand Up @@ -145,8 +145,8 @@ def test_init(self):
iSS = ImageSeries(name='test_iS', source='a hypothetical source', data=list(), unit='unit',
external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list())

oc = OpticalChannel('test_optical_channel', 'test_source', 'description', 'emission_lambda')
ip = ImagingPlane('test_imaging_plane', 'test_source', oc, 'description', 'device', 'excitation_lambda',
oc = OpticalChannel('test_optical_channel', 'test_source', 'description', 500.)
ip = ImagingPlane('test_imaging_plane', 'test_source', oc, 'description', 'device', 600.,
'imaging_rate', 'indicator', 'location', (1, 2, 1, 2, 3), 4.0, 'unit', 'reference_frame')

pS = PlaneSegmentation('test source', 'description', ip, 'test_name', iSS)
Expand Down

0 comments on commit 9b52025

Please sign in to comment.