NeurodataWithoutBorders / matnwb

A Matlab interface for reading and writing NWB files
BSD 2-Clause "Simplified" License
49 stars 32 forks source link

matnwb files not readable in pynwb #91

Closed bendichter closed 5 years ago

bendichter commented 5 years ago

I generate the following minimal NWB file in MatNWB:

nwb = nwbfile('identifier','01','session_description','aa');
nwb.session_start_time = datetime(now,'InputFormat', 'yyyyMMddHHmmss');

nwbExport('test_out.nwb');

and when I try to open it in python:

with NWBHDF5IO('test_out.nwb', 'r') as io:
    io.read()

I get the following (mysterious) error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-b092eb4f708b> in <module>()
      1 with NWBHDF5IO('/Users/bendichter/dev/matnwb/out/ANM255200_20140910.nwb','r') as io:
----> 2     io.read()

~/dev/pynwb/src/pynwb/form/utils.py in func_call(*args, **kwargs)
    379                         raise_from(ExceptionType(msg), None)
    380 
--> 381                 return func(self, **parsed['args'])
    382         else:
    383             def func_call(*args, **kwargs):

~/dev/pynwb/src/pynwb/form/backends/io.py in read(self, **kwargs)
     31     def read(self, **kwargs):
     32         f_builder = self.read_builder()
---> 33         container = self.__manager.construct(f_builder)
     34         return container
     35 

~/dev/pynwb/src/pynwb/form/utils.py in func_call(*args, **kwargs)
    379                         raise_from(ExceptionType(msg), None)
    380 
--> 381                 return func(self, **parsed['args'])
    382         else:
    383             def func_call(*args, **kwargs):

~/dev/pynwb/src/pynwb/form/build/map.py in construct(self, **kwargs)
    188         result = self.__containers.get(builder_id)
    189         if result is None:
--> 190             result = self.__type_map.construct(builder, self)
    191             parent_builder = self.__get_parent_dt_builder(builder)
    192             if parent_builder is not None:

~/dev/pynwb/src/pynwb/form/utils.py in func_call(*args, **kwargs)
    379                         raise_from(ExceptionType(msg), None)
    380 
--> 381                 return func(self, **parsed['args'])
    382         else:
    383             def func_call(*args, **kwargs):

~/dev/pynwb/src/pynwb/form/build/map.py in construct(self, **kwargs)
   1398         if build_manager is None:
   1399             build_manager = BuildManager(self)
-> 1400         attr_map = self.get_map(builder)
   1401         if attr_map is None:
   1402             raise ValueError('No ObjectMapper found for builder of type %s'

~/dev/pynwb/src/pynwb/form/utils.py in func_call(*args, **kwargs)
    379                         raise_from(ExceptionType(msg), None)
    380 
--> 381                 return func(self, **parsed['args'])
    382         else:
    383             def func_call(*args, **kwargs):

~/dev/pynwb/src/pynwb/form/build/map.py in get_map(self, **kwargs)
   1329             data_type = self.get_builder_dt(obj)
   1330             namespace = self.get_builder_ns(obj)
-> 1331             container_cls = self.get_cls(obj)
   1332         # now build the ObjectMapper class
   1333         spec = self.__ns_catalog.get_spec(namespace, data_type)

~/dev/pynwb/src/pynwb/form/utils.py in func_call(*args, **kwargs)
    379                         raise_from(ExceptionType(msg), None)
    380 
--> 381                 return func(self, **parsed['args'])
    382         else:
    383             def func_call(*args, **kwargs):

~/dev/pynwb/src/pynwb/form/build/map.py in get_cls(self, **kwargs)
   1264         data_type = self.get_builder_dt(builder)
   1265         namespace = self.get_builder_ns(builder)
-> 1266         return self.get_container_cls(namespace, data_type)
   1267 
   1268     @docval({'name': 'spec', 'type': (DatasetSpec, GroupSpec), 'doc': 'the parent spec to search'},

~/dev/pynwb/src/pynwb/form/utils.py in func_call(*args, **kwargs)
    377                     if parse_err:
    378                         msg = ', '.join(parse_err)
--> 379                         raise_from(ExceptionType(msg), None)
    380 
    381                 return func(self, **parsed['args'])

~/anaconda3/lib/python3.6/site-packages/six.py in raise_from(value, from_value)

TypeError: incorrect type for 'namespace' (got 'ndarray', expected 'str'), incorrect type for 'data_type' (got 'ndarray', expected 'str')

I get this error for every file that was written using MatNWB.

lawrence-mbf commented 5 years ago

I believe this issue is because pynwb internally uses a Variable Length String type instead of MatNWB's fixed length strings. I have a fix for this already along with the trials tutorial fixes. I just need to republish.

lawrence-mbf commented 5 years ago

That said, I'm actually stuck on another issue with pynwb compatibility in that pynwb seems to disagree with the schema on how to store the OptogeneticStimulusSite. Maybe that has been fixed since the version I'm using (release 0.6.2)?

lawrence-mbf commented 5 years ago

42ddc52eb1c06cb276775f5c5b9353e3a22dac81

lawrence-mbf commented 5 years ago

This should be fixed. No issues with new release after running scripts.