From dea07228b48bde3441338f7b1e0a4b2021df96fe Mon Sep 17 00:00:00 2001 From: Ben Dichter Date: Sun, 11 Nov 2018 20:09:54 -0500 Subject: [PATCH] Apply shape constraints (#706) * apply shape to all datasets * fix tests --- src/pynwb/behavior.py | 4 ++-- src/pynwb/data/nwb.behavior.yaml | 4 ++-- src/pynwb/data/nwb.image.yaml | 11 ++++----- src/pynwb/data/nwb.misc.yaml | 10 ++++---- src/pynwb/data/nwb.ophys.yaml | 4 +++- src/pynwb/ecephys.py | 18 +++++++------- src/pynwb/form/utils.py | 4 ++-- src/pynwb/image.py | 6 ++--- src/pynwb/misc.py | 28 ++++++++++++---------- src/pynwb/ogen.py | 4 ++-- src/pynwb/ophys.py | 13 ++++++---- src/pynwb/retinotopy.py | 5 ++-- tests/integration/ui_write/test_ecephys.py | 4 ++-- tests/integration/ui_write/test_ophys.py | 4 ++-- tests/unit/pynwb_tests/test_behavior.py | 18 +++++++------- tests/unit/pynwb_tests/test_ephys.py | 4 ++-- tests/unit/pynwb_tests/test_image.py | 18 +++++++------- tests/unit/pynwb_tests/test_misc.py | 8 +++---- tests/unit/pynwb_tests/test_ophys.py | 24 +++++++++---------- tests/unit/pynwb_tests/test_retinotopy.py | 4 +++- tests/unit/pynwb_tests/test_timeseries.py | 3 +-- 21 files changed, 105 insertions(+), 93 deletions(-) diff --git a/src/pynwb/behavior.py b/src/pynwb/behavior.py index 1d6af8b1c..3c8214a23 100644 --- a/src/pynwb/behavior.py +++ b/src/pynwb/behavior.py @@ -25,7 +25,7 @@ class SpatialSeries(TimeSeries): _help = "Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]" @docval({'name': 'name', 'type': str, 'doc': 'The name of this SpatialSeries dataset'}, - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, None), 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames'}, {'name': 'reference_frame', 'type': str, 'doc': 'description defining what the zero-position is'}, {'name': 'conversion', 'type': float, @@ -34,7 +34,7 @@ class SpatialSeries(TimeSeries): {'name': 'resolution', 'type': float, 'doc': 'The smallest meaningful difference (in specified unit) between values in data', 'default': _default_resolution}, - {'name': 'timestamps', 'type': ('array_data', 'data', 'TimeSeries'), + {'name': 'timestamps', 'type': ('array_data', 'data', 'TimeSeries'), 'shape': (None, ), 'doc': 'Timestamps for samples stored in data', 'default': None}, {'name': 'starting_time', 'type': float, 'doc': 'The timestamp of the first sample', 'default': None}, {'name': 'rate', 'type': float, 'doc': 'Sampling rate in Hz', 'default': None}, diff --git a/src/pynwb/data/nwb.behavior.yaml b/src/pynwb/data/nwb.behavior.yaml index f92a62693..d0bc933d6 100644 --- a/src/pynwb/data/nwb.behavior.yaml +++ b/src/pynwb/data/nwb.behavior.yaml @@ -13,7 +13,7 @@ groups: attributes: - name: help dtype: text - doc: Value is 'Stores points in space over time. The data[] array structure is + doc: 'Value is: Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions]' value: Stores points in space over time. The data[] array structure is [num samples][num spatial dimensions] @@ -42,7 +42,7 @@ groups: quantity: '?' - neurodata_type_def: BehavioralEpochs neurodata_type_inc: NWBDataInterface - doc: 'TimeSeries for storing behavoioral epochs. The objective of this and the other + doc: 'TimeSeries for storing behavioral epochs. The objective of this and the other two Behavioral interfaces (e.g. BehavioralEvents and BehavioralTimeSeries) is to provide generic hooks for software tools/scripts. This allows a tool/script to take the output one specific interface (e.g., UnitTimes) and plot that data diff --git a/src/pynwb/data/nwb.image.yaml b/src/pynwb/data/nwb.image.yaml index d096a23bd..1b31be3a0 100644 --- a/src/pynwb/data/nwb.image.yaml +++ b/src/pynwb/data/nwb.image.yaml @@ -53,8 +53,6 @@ groups: doc: Either binary data containing image or empty. quantity: '?' dims: - - - x - - y - - frame - y - x @@ -63,8 +61,6 @@ groups: - y - x shape: - - - null - - null - - null - null - null @@ -145,13 +141,14 @@ groups: quantity: '?' - name: field_of_view dtype: float32 - doc: Width, height and depto of image, or imaged area (meters). + doc: Width, height and depth of image, or imaged area (meters). dims: - - width|height - - width|height|depth + - - width|height|depth quantity: '?' shape: - - 2 + - - 2 + - - 3 - name: orientation dtype: text doc: Description of image relative to some reference frame (e.g., which way is diff --git a/src/pynwb/data/nwb.misc.yaml b/src/pynwb/data/nwb.misc.yaml index cf7b7b043..6c909bc94 100644 --- a/src/pynwb/data/nwb.misc.yaml +++ b/src/pynwb/data/nwb.misc.yaml @@ -30,11 +30,13 @@ groups: default_value: see 'feature_units' required: false dims: - - num_times - - num_features + - - num_times + - - num_times + - num_features shape: - - null - - null + - - null + - - null + - null - name: feature_units dtype: text doc: Units of each feature. diff --git a/src/pynwb/data/nwb.ophys.yaml b/src/pynwb/data/nwb.ophys.yaml index 151f2f925..505689f35 100644 --- a/src/pynwb/data/nwb.ophys.yaml +++ b/src/pynwb/data/nwb.ophys.yaml @@ -22,11 +22,13 @@ groups: dtype: float32 doc: Width, height and depth of image, or imaged area (meters). dims: + - width|height - width|height|depth quantity: '?' required: false shape: - - 3 + - - 2 + - - 3 links: - name: imaging_plane doc: link to ImagingPlane group from which this TimeSeries data was generated diff --git a/src/pynwb/ecephys.py b/src/pynwb/ecephys.py index 6c3dbd6ce..525ff75d3 100644 --- a/src/pynwb/ecephys.py +++ b/src/pynwb/ecephys.py @@ -220,8 +220,8 @@ class Clustering(NWBDataInterface): @docval({'name': 'description', 'type': str, 'doc': 'Description of clusters or clustering, (e.g. cluster 0 is noise, \ clusters curated using Klusters, etc).'}, - {'name': 'num', 'type': ('array_data', 'data'), 'doc': 'Cluster number of each event.', 'shape': (None,)}, - {'name': 'peak_over_rms', 'type': Iterable, + {'name': 'num', 'type': ('array_data', 'data'), 'doc': 'Cluster number of each event.', 'shape': (None, )}, + {'name': 'peak_over_rms', 'type': Iterable, 'shape': (None, ), 'doc': 'Maximum ratio of waveform peak to RMS on any channel in the cluster\ (provides a basic clustering metric).'}, {'name': 'times', 'type': ('array_data', 'data'), 'doc': 'Times of clustered events, in seconds.', @@ -256,8 +256,10 @@ class ClusterWaveforms(NWBDataInterface): 'doc': 'the clustered spike data used as input for computing waveforms'}, {'name': 'waveform_filtering', 'type': str, 'doc': 'filter applied to data before calculating mean and standard deviation'}, - {'name': 'waveform_mean', 'type': Iterable, 'doc': 'the mean waveform for each cluster'}, - {'name': 'waveform_sd', 'type': Iterable, 'doc': 'the standard deviations of waveforms for each cluster'}, + {'name': 'waveform_mean', 'type': Iterable, 'shape': (None, None), + 'doc': 'the mean waveform for each cluster'}, + {'name': 'waveform_sd', 'type': Iterable, 'shape': (None, None), + 'doc': 'the standard deviations of waveforms for each cluster'}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'ClusterWaveforms'}) def __init__(self, **kwargs): import warnings @@ -334,10 +336,10 @@ class FeatureExtraction(NWBDataInterface): @docval({'name': 'electrodes', 'type': DynamicTableRegion, 'doc': 'the table region corresponding to the electrodes from which this series was recorded'}, {'name': 'description', 'type': (list, tuple, np.ndarray, DataChunkIterator), - 'doc': 'A description for each feature extracted', 'ndim': 1}, - {'name': 'times', 'type': ('array_data', 'data'), - 'doc': 'The times of events that features correspond to', 'ndim': 1}, - {'name': 'features', 'type': ('array_data', 'data'), + 'doc': 'A description for each feature extracted', 'shape': (None, )}, + {'name': 'times', 'type': ('array_data', 'data'), 'shape': (None, ), + 'doc': 'The times of events that features correspond to'}, + {'name': 'features', 'type': ('array_data', 'data'), 'shape': (None, None, None), 'doc': 'Features for each channel', 'ndim': 3}, {'name': 'name', 'type': str, 'doc': 'the name of this container', 'default': 'FeatureExtraction'}) def __init__(self, **kwargs): diff --git a/src/pynwb/form/utils.py b/src/pynwb/form/utils.py index f67ef8eb8..758371a45 100644 --- a/src/pynwb/form/utils.py +++ b/src/pynwb/form/utils.py @@ -176,12 +176,12 @@ def __parse_args(validator, args, kwargs, enforce_type=True, enforce_shape=True, argsi += 1 else: ret[argname] = arg['default'] + argval = ret[argname] if enforce_type: - argval = ret[argname] if not __type_okay(argval, arg['type'], arg['default'] is None): fmt_val = (argname, type(argval).__name__, __format_type(arg['type'])) type_errors.append("incorrect type for '%s' (got '%s', expected '%s')" % fmt_val) - if enforce_shape and 'shape' in arg: + if enforce_shape and 'shape' in arg and argval is not None: if not __shape_okay_multi(argval, arg['shape']): fmt_val = (argname, get_data_shape(argval), arg['shape']) value_errors.append("incorrect shape for '%s' (got '%s, expected '%s')" % fmt_val) diff --git a/src/pynwb/image.py b/src/pynwb/image.py index f5d37ee28..a650c5b5f 100644 --- a/src/pynwb/image.py +++ b/src/pynwb/image.py @@ -23,7 +23,7 @@ class ImageSeries(TimeSeries): _help = "Storage object for time-series 2-D image data" @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ([None] * 3, [None] * 4), 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames', 'default': None}, {'name': 'unit', 'type': str, @@ -88,7 +88,7 @@ class IndexSeries(TimeSeries): an arbitrary order. The data[] field stores frame number in reference stack." @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, ), 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames'}, {'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)'}, @@ -203,7 +203,7 @@ class OpticalSeries(ImageSeries): {'name': 'format', 'type': str, 'doc': 'Format of image. Three types: 1) Image format; tiff, png, jpg, etc. 2) external 3) raw.'}, {'name': 'distance', 'type': float, 'doc': 'Distance from camera/monitor to target/eye.'}, - {'name': 'field_of_view', 'type': (list, np.ndarray, 'TimeSeries'), + {'name': 'field_of_view', 'type': (list, np.ndarray, 'TimeSeries'), 'shape': ((2, ), (3, )), 'doc': 'Width, height and depth of image, or imaged area (meters).'}, {'name': 'orientation', 'type': str, 'doc': 'Description of image relative to some reference frame (e.g., which way is up). \ diff --git a/src/pynwb/misc.py b/src/pynwb/misc.py index 4a991cdd8..d242219c4 100644 --- a/src/pynwb/misc.py +++ b/src/pynwb/misc.py @@ -26,7 +26,7 @@ class AnnotationSeries(TimeSeries): {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames', 'default': list()}, - {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), + {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, ), 'doc': 'Timestamps for samples stored in data', 'default': None}, {'name': 'comments', 'type': str, 'doc': 'Human-readable comments about this TimeSeries dataset', 'default': 'no comments'}, @@ -68,19 +68,18 @@ class AbstractFeatureSeries(TimeSeries): _help = "Features of an applied stimulus. This is useful when storing the raw stimulus is impractical." @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, - {'name': 'feature_units', 'type': (str, Iterable), 'doc': 'The unit of each feature'}, - {'name': 'features', 'type': (str, Iterable), 'doc': 'Description of each feature'}, - - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), - 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames', - 'default': list()}, + {'name': 'feature_units', 'type': Iterable, 'shape': (None, ), 'doc': 'The unit of each feature'}, + {'name': 'features', 'type': Iterable, 'shape': (None, ), 'doc': 'Description of each feature'}, + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ((None,), (None, None)), + 'default': list(), + 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames'}, {'name': 'resolution', 'type': float, 'doc': 'The smallest meaningful difference (in specified unit) between values in data', 'default': _default_resolution}, {'name': 'conversion', 'type': float, 'doc': 'Scalar to multiply each element in data to convert it to the specified unit', 'default': _default_conversion}, - {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), + {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, ), 'doc': 'Timestamps for samples stored in data', 'default': None}, {'name': 'starting_time', 'type': float, 'doc': 'The timestamp of the first sample', 'default': None}, {'name': 'rate', 'type': float, 'doc': 'Sampling rate in Hz', 'default': None}, @@ -105,8 +104,11 @@ def __init__(self, **kwargs): {'name': 'features', 'type': (list, np.ndarray), 'doc': 'the feature values for this time point'}) def add_features(self, **kwargs): time, features = getargs('time', 'features', kwargs) - self.timestamps.append(time) - self.data.append(features) + if type(self.timestamps) == list and type(self.data) is list: + self.timestamps.append(time) + self.data.append(features) + else: + raise ValueError('Can only add feature if timestamps and data are lists') @register_class('IntervalSeries', CORE_NAMESPACE) @@ -116,7 +118,7 @@ class IntervalSeries(TimeSeries): data field stores whether the interval just started (>0 value) or ended (<0 value). Different interval types can be represented in the same series by using multiple key values (eg, 1 for feature A, 2 for feature B, 3 for feature C, etc). The field data stores an 8-bit integer. This is largely an alias - of a standard TimeSeries but that is identifiable as representing time intervals in a machinereadable + of a standard TimeSeries but that is identifiable as representing time intervals in a machine-readable way. """ @@ -125,9 +127,9 @@ class IntervalSeries(TimeSeries): _help = "Stores the start and stop times for events." @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None,), 'doc': '>0 if interval started, <0 if interval ended.', 'default': list()}, - {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), + {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), 'shape': (None,), 'doc': 'Timestamps for samples stored in data', 'default': list()}, {'name': 'comments', 'type': str, 'doc': 'Human-readable comments about this TimeSeries dataset', 'default': 'no comments'}, diff --git a/src/pynwb/ogen.py b/src/pynwb/ogen.py index 9c1e95cd3..105a8d839 100644 --- a/src/pynwb/ogen.py +++ b/src/pynwb/ogen.py @@ -45,7 +45,7 @@ class OptogeneticSeries(TimeSeries): _help = "Optogenetic stimulus." @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, ), 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames'}, {'name': 'unit', 'type': str, 'doc': 'Value is the string "Watt".', 'default': 'Watt'}, {'name': 'site', 'type': OptogeneticStimulusSite, @@ -55,7 +55,7 @@ class OptogeneticSeries(TimeSeries): {'name': 'conversion', 'type': float, 'doc': 'Scalar to multiply each element by to conver to volts', 'default': _default_conversion}, - {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), + {'name': 'timestamps', 'type': ('array_data', 'data', TimeSeries), 'shape': (None, ), 'doc': 'Timestamps for samples stored in data', 'default': None}, {'name': 'starting_time', 'type': float, 'doc': 'The timestamp of the first sample', 'default': None}, {'name': 'rate', 'type': float, 'doc': 'Sampling rate in Hz', 'default': None}, diff --git a/src/pynwb/ophys.py b/src/pynwb/ophys.py index a7ec094ae..cb3714af0 100644 --- a/src/pynwb/ophys.py +++ b/src/pynwb/ophys.py @@ -106,14 +106,14 @@ class TwoPhotonSeries(ImageSeries): @docval({'name': 'name', 'type': str, 'doc': 'The name of this TimeSeries dataset'}, {'name': 'imaging_plane', 'type': ImagingPlane, 'doc': 'Imaging plane class/pointer.'}, - {'name': 'data', 'type': ('array_data', 'data', TimeSeries), + {'name': 'data', 'type': ('array_data', 'data', TimeSeries), 'shape': ([None] * 3, [None] * 4), 'doc': 'The data this TimeSeries dataset stores. Can also store binary data e.g. image frames', 'default': None}, {'name': 'unit', 'type': str, 'doc': 'The base unit of measurement (should be SI unit)', 'default': None}, {'name': 'format', 'type': str, 'doc': 'Format of image. Three types: 1) Image format; tiff, png, jpg, etc. 2) external 3) raw.', 'default': None}, - {'name': 'field_of_view', 'type': (Iterable, TimeSeries), + {'name': 'field_of_view', 'type': (Iterable, TimeSeries), 'shape': ((2, ), (3, )), 'doc': 'Width, height and depth of image, or imaged area (meters).', 'default': None}, {'name': 'pmt_gain', 'type': float, 'doc': 'Photomultiplier gain.', 'default': None}, {'name': 'scan_line_rate', 'type': float, @@ -245,11 +245,14 @@ def __init__(self, **kwargs): self.reference_images = reference_images @docval({'name': 'pixel_mask', 'type': 'array_data', 'default': None, - 'doc': 'pixel mask for 2D ROIs: [(x1, y1, weight1), (x2, y2, weight2), ...]'}, + 'doc': 'pixel mask for 2D ROIs: [(x1, y1, weight1), (x2, y2, weight2), ...]', + 'shape': (None, 3)}, {'name': 'voxel_mask', 'type': 'array_data', 'default': None, - 'doc': 'voxel mask for 3D ROIs: [(x1, y1, z1, weight1), (x2, y2, z1, weight2), ...]'}, + 'doc': 'voxel mask for 3D ROIs: [(x1, y1, z1, weight1), (x2, y2, z1, weight2), ...]', + 'shape': (None, 4)}, {'name': 'image_mask', 'type': 'array_data', 'default': None, - 'doc': 'image with the same size of image where positive values mark this ROI', }, + 'doc': 'image with the same size of image where positive values mark this ROI', + 'shape': [[None]*2, [None]*3]}, {'name': 'id', 'type': int, 'help': 'the ID for the ROI', 'default': None}, allow_extra=True) def add_roi(self, **kwargs): diff --git a/src/pynwb/retinotopy.py b/src/pynwb/retinotopy.py index 3f978a0d8..96220943e 100644 --- a/src/pynwb/retinotopy.py +++ b/src/pynwb/retinotopy.py @@ -47,10 +47,11 @@ class AxisMap(NWBContainer): 'dimension') @docval({'name': 'name', 'type': str, 'doc': 'the name of this axis map'}, - {'name': 'data', 'type': Iterable, 'doc': 'data field.'}, + {'name': 'data', 'type': Iterable, 'shape': (None, None), 'doc': 'data field.'}, {'name': 'field_of_view', 'type': Iterable, 'doc': 'Size of viewing area, in meters.'}, {'name': 'unit', 'type': str, 'doc': 'Unit that axis data is stored in (e.g., degrees)'}, - {'name': 'dimension', 'type': Iterable, 'doc': 'Number of rows and columns in the image'}) + {'name': 'dimension', 'type': Iterable, 'shape': (None, ), + 'doc': 'Number of rows and columns in the image'}) def __init__(self, **kwargs): data, field_of_view, unit, dimension = popargs('data', 'field_of_view', 'unit', 'dimension', kwargs) pargs, pkwargs = fmt_docval_args(super(AxisMap, self).__init__, kwargs) diff --git a/tests/integration/ui_write/test_ecephys.py b/tests/integration/ui_write/test_ecephys.py index db5086af3..325dec868 100644 --- a/tests/integration/ui_write/test_ecephys.py +++ b/tests/integration/ui_write/test_ecephys.py @@ -338,8 +338,8 @@ def setUpContainer(self): num = [3, 4] peak_over_rms = [5.3, 6.3] self.clustering = Clustering('description', num, peak_over_rms, times) - means = [7.3, 7.3] - stdevs = [8.3, 8.3] + means = [[7.3, 7.3]] + stdevs = [[8.3, 8.3]] cw = ClusterWaveforms(self.clustering, 'filtering', means, stdevs) return cw diff --git a/tests/integration/ui_write/test_ophys.py b/tests/integration/ui_write/test_ophys.py index 069e17ed3..b6db96112 100644 --- a/tests/integration/ui_write/test_ophys.py +++ b/tests/integration/ui_write/test_ophys.py @@ -86,7 +86,7 @@ def make_imaging_plane(self): def setUpContainer(self): self.make_imaging_plane() - data = list(zip(range(10), range(10, 20))) + data = [[[1., 1.] * 2] * 2] timestamps = list(map(lambda x: x/10, range(10))) fov = [2.0, 2.0, 5.0] ret = TwoPhotonSeries('test_2ps', self.imaging_plane, data, 'image_unit', 'raw', fov, 1.7, 3.4, @@ -128,7 +128,7 @@ def setUpBuilder(self): } ) - data = list(zip(range(10), range(10, 20))) + data = [[[1., 1.] * 2] * 2] timestamps = list(map(lambda x: x/10, range(10))) return GroupBuilder( 'test_2ps', diff --git a/tests/unit/pynwb_tests/test_behavior.py b/tests/unit/pynwb_tests/test_behavior.py index 0ff187193..05517bf3d 100644 --- a/tests/unit/pynwb_tests/test_behavior.py +++ b/tests/unit/pynwb_tests/test_behavior.py @@ -1,5 +1,7 @@ import unittest +import numpy as np + from pynwb import TimeSeries from pynwb.misc import IntervalSeries from pynwb.behavior import SpatialSeries, BehavioralEpochs, BehavioralEvents, BehavioralTimeSeries, PupilTracking, EyeTracking, CompassDirection, Position # noqa: E501 @@ -7,7 +9,7 @@ class SpatialSeriesConstructor(unittest.TestCase): def test_init(self): - sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) + sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) self.assertEqual(sS.name, 'test_sS') self.assertEqual(sS.unit, 'meters') self.assertEqual(sS.reference_frame, 'reference_frame') @@ -16,7 +18,7 @@ def test_init(self): class BehavioralEpochsConstructor(unittest.TestCase): def test_init(self): data = [0, 1, 0, 1] - iS = IntervalSeries('test_iS', data, timestamps=list()) + iS = IntervalSeries('test_iS', data, timestamps=[1., 2., 3.]) bE = BehavioralEpochs(iS) self.assertEqual(bE.interval_series['test_iS'], iS) @@ -24,7 +26,7 @@ def test_init(self): class BehavioralEventsConstructor(unittest.TestCase): def test_init(self): - ts = TimeSeries('test_ts', list(), 'unit', timestamps=list()) + ts = TimeSeries('test_ts', np.ones((2, 2)), 'unit', timestamps=[1., 2., 3.]) bE = BehavioralEvents(ts) self.assertEqual(bE.time_series['test_ts'], ts) @@ -32,7 +34,7 @@ def test_init(self): class BehavioralTimeSeriesConstructor(unittest.TestCase): def test_init(self): - ts = TimeSeries('test_ts', list(), 'unit', timestamps=list()) + ts = TimeSeries('test_ts', np.ones((2, 2)), 'unit', timestamps=[1., 2., 3.]) bts = BehavioralTimeSeries(ts) self.assertEqual(bts.time_series['test_ts'], ts) @@ -40,7 +42,7 @@ def test_init(self): class PupilTrackingConstructor(unittest.TestCase): def test_init(self): - ts = TimeSeries('test_ts', list(), 'unit', timestamps=list()) + ts = TimeSeries('test_ts', np.ones((2, 2)), 'unit', timestamps=[1., 2., 3.]) pt = PupilTracking(ts) self.assertEqual(pt.time_series['test_ts'], ts) @@ -48,7 +50,7 @@ def test_init(self): class EyeTrackingConstructor(unittest.TestCase): def test_init(self): - sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) + sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) et = EyeTracking(sS) self.assertEqual(et.spatial_series['test_sS'], sS) @@ -56,7 +58,7 @@ def test_init(self): class CompassDirectionConstructor(unittest.TestCase): def test_init(self): - sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) + sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) cd = CompassDirection(sS) self.assertEqual(cd.spatial_series['test_sS'], sS) @@ -64,7 +66,7 @@ def test_init(self): class PositionConstructor(unittest.TestCase): def test_init(self): - sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) + sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) pc = Position(sS) self.assertEqual(pc.spatial_series.get('test_sS'), sS) diff --git a/tests/unit/pynwb_tests/test_ephys.py b/tests/unit/pynwb_tests/test_ephys.py index b933b273e..0564f00e6 100644 --- a/tests/unit/pynwb_tests/test_ephys.py +++ b/tests/unit/pynwb_tests/test_ephys.py @@ -110,8 +110,8 @@ def test_init(self): peak_over_rms = [5.3, 6.3] cc = Clustering('description', num, peak_over_rms, times) # noqa: F405 - means = [7.3, 7.3] - stdevs = [8.3, 8.3] + means = [[7.3, 7.3]] + stdevs = [[8.3, 8.3]] cw = ClusterWaveforms(cc, 'filtering', means, stdevs) # noqa: F405 self.assertEqual(cw.clustering_interface, cc) diff --git a/tests/unit/pynwb_tests/test_image.py b/tests/unit/pynwb_tests/test_image.py index d4e30bec7..12e4c7583 100644 --- a/tests/unit/pynwb_tests/test_image.py +++ b/tests/unit/pynwb_tests/test_image.py @@ -10,7 +10,7 @@ class ImageSeriesConstructor(unittest.TestCase): def test_init(self): - iS = ImageSeries(name='test_iS', data=list(), unit='unit', + iS = ImageSeries(name='test_iS', data=np.ones((3, 3, 3)), unit='unit', external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list()) self.assertEqual(iS.name, 'test_iS') self.assertEqual(iS.unit, 'unit') @@ -34,13 +34,13 @@ def test_init(self): class ImageMaskSeriesConstructor(unittest.TestCase): def test_init(self): - iS = ImageSeries(name='test_iS', data=list(), unit='unit', + iS = ImageSeries(name='test_iS', data=np.ones((2, 2, 2)), unit='unit', external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', - timestamps=list()) + timestamps=[1., .2]) - ims = ImageMaskSeries(name='test_ims', data=list(), unit='unit', + ims = ImageMaskSeries(name='test_ims', data=np.ones((2, 2, 2)), unit='unit', masked_imageseries=iS, external_file=['external_file'], starting_frame=[1, 2, 3], - format='tiff', timestamps=list()) + format='tiff', timestamps=[1., 2.]) self.assertEqual(ims.name, 'test_ims') self.assertEqual(ims.unit, 'unit') self.assertEqual(ims.masked_imageseries, iS) @@ -52,13 +52,13 @@ def test_init(self): class OpticalSeriesConstructor(unittest.TestCase): def test_init(self): - ts = OpticalSeries(name='test_ts', data=list(), unit='unit', distance=1.0, - field_of_view=list(), orientation='orientation', external_file=['external_file'], - starting_frame=[1, 2, 3], format='tiff', timestamps=list()) + ts = OpticalSeries(name='test_ts', data=np.ones((2, 2, 2)), unit='unit', distance=1.0, + field_of_view=[4, 5], orientation='orientation', external_file=['external_file'], + starting_frame=[1, 2, 3], format='tiff', timestamps=[1., 2.]) self.assertEqual(ts.name, 'test_ts') self.assertEqual(ts.unit, 'unit') self.assertEqual(ts.distance, 1.0) - self.assertEqual(ts.field_of_view, list()) + self.assertEqual(ts.field_of_view, [4, 5]) self.assertEqual(ts.orientation, 'orientation') self.assertEqual(ts.external_file, ['external_file']) self.assertEqual(ts.starting_frame, [1, 2, 3]) diff --git a/tests/unit/pynwb_tests/test_misc.py b/tests/unit/pynwb_tests/test_misc.py index 1836ddf82..a13bc09d0 100644 --- a/tests/unit/pynwb_tests/test_misc.py +++ b/tests/unit/pynwb_tests/test_misc.py @@ -14,12 +14,12 @@ def test_init(self): class AbstractFeatureSeriesConstructor(unittest.TestCase): def test_init(self): - aFS = AbstractFeatureSeries('test_aFS', 'feature units', 'features', timestamps=list()) + aFS = AbstractFeatureSeries('test_aFS', ['feature units'], ['features'], timestamps=list()) self.assertEqual(aFS.name, 'test_aFS') - self.assertEqual(aFS.feature_units, 'feature units') - self.assertEqual(aFS.features, 'features') + self.assertEqual(aFS.feature_units, ['feature units']) + self.assertEqual(aFS.features, ['features']) - aFS.add_features(2.0, list()) + aFS.add_features(2.0, [1.]) class IntervalSeriesConstructor(unittest.TestCase): diff --git a/tests/unit/pynwb_tests/test_ophys.py b/tests/unit/pynwb_tests/test_ophys.py index e671ce6a9..2d417530d 100644 --- a/tests/unit/pynwb_tests/test_ophys.py +++ b/tests/unit/pynwb_tests/test_ophys.py @@ -15,8 +15,8 @@ def CreatePlaneSegmentation(): pix_mask = [[1, 2, 1.0], [3, 4, 1.0], [5, 6, 1.0], [7, 8, 2.0], [9, 10, 2.0]] - iSS = ImageSeries(name='test_iS', data=list(), unit='unit', - external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list()) + iSS = ImageSeries(name='test_iS', data=np.ones((2, 2, 2)), unit='unit', + external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=[1., 2.]) oc = OpticalChannel('test_optical_channel', 'description', 500.) device = Device(name='device_name') @@ -50,12 +50,12 @@ def test_init(self): self.assertEqual(ip.unit, 'unit') self.assertEqual(ip.reference_frame, 'reference_frame') - tPS = TwoPhotonSeries('test_tPS', unit='unit', field_of_view=list(), + tPS = TwoPhotonSeries('test_tPS', unit='unit', field_of_view=[2., 3.], imaging_plane=ip, pmt_gain=1.0, scan_line_rate=2.0, external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list()) self.assertEqual(tPS.name, 'test_tPS') self.assertEqual(tPS.unit, 'unit') - self.assertEqual(tPS.field_of_view, list()) + self.assertEqual(tPS.field_of_view, [2., 3.]) self.assertEqual(tPS.imaging_plane, ip) self.assertEqual(tPS.pmt_gain, 1.0) self.assertEqual(tPS.scan_line_rate, 2.0) @@ -70,9 +70,9 @@ def test_args(self): ip = ImagingPlane('test_imaging_plane', oc, 'description', device, 600., 300., 'indicator', 'location', (50, 100, 3), 4.0, 'unit', 'reference_frame') with self.assertRaises(ValueError): # no data or external file - TwoPhotonSeries('test_tPS', unit='unit', field_of_view=list(), + TwoPhotonSeries('test_tPS', unit='unit', field_of_view=[2., 3.], imaging_plane=ip, pmt_gain=1.0, scan_line_rate=2.0, - starting_frame=[1, 2, 3], format='tiff', timestamps=list()) + starting_frame=[1, 2, 3], format='tiff', timestamps=[1., 2.]) class MotionCorrectionConstructor(unittest.TestCase): @@ -82,10 +82,10 @@ def test_init(self): class CorrectedImageStackConstructor(unittest.TestCase): def test_init(self): - is1 = ImageSeries(name='is1', data=list(), unit='unit', - external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list()) - is2 = ImageSeries(name='is2', data=list(), unit='unit', - external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list()) + is1 = ImageSeries(name='is1', data=np.ones((2, 2, 2)), unit='unit', + external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=[1., 2.]) + is2 = ImageSeries(name='is2', data=np.ones((2, 2, 2)), unit='unit', + external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=[1., 2.]) tstamps = np.arange(1.0, 100.0, 0.1, dtype=np.float) ts = TimeSeries("test_ts", list(range(len(tstamps))), 'unit', timestamps=tstamps) cis = CorrectedImageStack(is1, is2, ts) @@ -98,7 +98,7 @@ class RoiResponseSeriesConstructor(unittest.TestCase): def test_init(self): ip = CreatePlaneSegmentation() - rt_region = ip.create_roi_table_region('the second ROI', region=[1]) + rt_region = ip.create_roi_table_region('the second ROI', region=[0]) ts = RoiResponseSeries('test_ts', list(), 'unit', rt_region, timestamps=list()) self.assertEqual(ts.name, 'test_ts') @@ -146,7 +146,7 @@ class PlaneSegmentationConstructor(unittest.TestCase): def getBoilerPlateObjects(self): - iSS = ImageSeries(name='test_iS', data=list(), unit='unit', + iSS = ImageSeries(name='test_iS', data=np.ones((2, 2, 2)), unit='unit', external_file=['external_file'], starting_frame=[1, 2, 3], format='tiff', timestamps=list()) device = Device(name='device_name') diff --git a/tests/unit/pynwb_tests/test_retinotopy.py b/tests/unit/pynwb_tests/test_retinotopy.py index ad4add40f..4ad2b6583 100644 --- a/tests/unit/pynwb_tests/test_retinotopy.py +++ b/tests/unit/pynwb_tests/test_retinotopy.py @@ -1,12 +1,14 @@ import unittest +import numpy as np + from pynwb.retinotopy import ImagingRetinotopy, AxisMap, AImage class ImageRetinotopyConstructor(unittest.TestCase): def test_init(self): - data = list() + data = np.ones((2, 2)) field_of_view = [1, 2, 3] dimension = [1, 2, 3] sign_map = AxisMap('sign_map', data, field_of_view, 'unit', dimension) diff --git a/tests/unit/pynwb_tests/test_timeseries.py b/tests/unit/pynwb_tests/test_timeseries.py index 8f23e8521..8674a17c3 100644 --- a/tests/unit/pynwb_tests/test_timeseries.py +++ b/tests/unit/pynwb_tests/test_timeseries.py @@ -21,7 +21,7 @@ def test_init_timestampslink_set(self): self.assertIsInstance(ts.timestamp_link, set) self.assertEqual(len(ts.timestamp_link), 0) - def test_init_no_parent(self): # noqa: F811 + def test_init_no_parent2(self): # noqa: F811 parent = NWBContainer('test_parent_container') ts = TimeSeries('test_ts', list(), 'unit', timestamps=list(), parent=parent) self.assertEqual(ts.name, 'test_ts') @@ -29,7 +29,6 @@ def test_init_no_parent(self): # noqa: F811 def test_init_data(self): dat = [0, 1, 2, 3, 4] - tstamps = [0, 1, 2, 3, 4] # noqa: F841 ts = TimeSeries('test_ts', dat, 'Volts', timestamps=[0.1, 0.2, 0.3, 0.4]) self.assertIs(ts.data, dat) self.assertEqual(ts.conversion, 1.0)