BUNPC / pysnirf2

Python package for reading, writing and validating Shared Near Infrared Spectroscopy Format (SNIRF) files
GNU General Public License v3.0
15 stars 11 forks source link

Trying pysnirf2 #12

Closed rob-luke closed 2 years ago

rob-luke commented 2 years ago

Thanks again for the great work here @sstucker

I just tried the validator against SNIRF files written by MNE. The files exist here: https://github.com/rob-luke/BIDS-NIRS-Tapping These files passed the earlier validator from: https://github.com/andyzjc/snirf_validator But my files fail to pass on this validator (probably a good thing, it means this validator is stricter, we want strict).

However, I am struggling to understand what the error means, and how I should modify my writer. The code I used to validate the file was

import pysnirf2
pysnirf2.validateSnirf("/Volumes/MassStorage2TB/rluke/Repositories/BIDS-NIRS-Tapping/sub-03/nirs/sub-03_task-Tapping_nirs.snirf")

The error I get is

TypeError                                 Traceback (most recent call last)
<ipython-input-2-18afb2f43692> in <module>
----> 1 pysnirf2.validateSnirf("/Volumes/MassStorage2TB/rluke/Repositories/BIDS-NIRS-Tapping/sub-03/nirs/sub-03_task-Tapping_nirs.snirf")

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in validateSnirf(path)
   4025         path += '.snirf'
   4026     if os.path.exists(path):
-> 4027         s = Snirf(path)
   4028         valid, result = s.validate()
   4029         s.close()

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in __init__(self, dynamic_loading, logfile, *args)
   3753         else:  # if the dataset is not found on disk
   3754             self._formatVersion = AbsentDataset
-> 3755         self.nirs = Nirs(self, self._cfg)  # Indexed group
   3756         self._indexed_groups.append(self.nirs)
   3757

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in __init__(self, h, cfg)
   2255
   2256     def __init__(self, h: h5py.File, cfg: SnirfConfig):
-> 2257         super().__init__(h, cfg)
   2258
   2259

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in __init__(self, parent, cfg)
    607         self._parent = parent
    608         self._cfg = cfg
--> 609         self._populate_list()
    610         self._cfg.logger.info('IndexedGroup %s at %s in %s initalized with %i instances of %s', self.__class__.__name__,
    611                               self._parent.location, self.filename, len(self._list), self._element)

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in _populate_list(self)
    702         for name in names:
    703             if name in self._parent._h:
--> 704                 self._list.append(self._element(self._parent._h[name].id, self._cfg))
    705
    706     def _check_type(self, item):

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in __init__(self, gid, cfg)
   2092         self._indexed_groups = []
   2093         if 'metaDataTags' in self._h:
-> 2094             self._metaDataTags = MetaDataTags(self._h['metaDataTags'].id, self._cfg)  # Group
   2095         else:
   2096             self._metaDataTags = MetaDataTags(self.location + '/' + 'metaDataTags', self._cfg)  # Anonymous group (wrapper only)

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in __init__(self, var, cfg)
    843             # If the name isn't specified
    844             if key not in self._snirf_names and not any([key in indexed_group for indexed_group in self._indexed_groups]):
--> 845                 setattr(self, key, _read_dataset(self._h[key]))
    846                 self._unspecified_names.append(key)
    847

~/opt/anaconda3/envs/mne/lib/python3.9/site-packages/pysnirf2/pysnirf2.py in _read_dataset(h_dataset)
    138         elif _DTYPE_FLOAT32 in h_dataset.dtype.str or _DTYPE_FLOAT64 in h_dataset.dtype.str:
    139             return _read_float(h_dataset)
--> 140     raise TypeError("Dataset dtype='" + str(h_dataset.dtype)
    141                     + "' not recognized. Expecting dtype to contain one of these: "
    142                     + str([_DTYPE_FIXED_LEN_STR, _DTYPE_VAR_LEN_STR, _DTYPE_INT, _DTYPE_FLOAT32, _DTYPE_FLOAT64]))

TypeError: Dataset dtype='int64' not recognized. Expecting dtype to contain one of these: ['S', 'O', 'i4', 'f4', 'f8']

Running through the debugger I see that the error occurs when processing the custom metadata tag /nirs/metaDataTags/MNE_coordFrame.

Any hints as to what I am doing wrong?

sstucker commented 2 years ago

One major reason I don't think this code is ready is I haven't used it on very diverse files.

I think this is an issue of it not recognizing your metaDataTag because of its type (internally all our metaDataTags are just strings)

sstucker commented 2 years ago

I will try the code on your dataset and get back to you.

sstucker commented 2 years ago

Confirming here it is because I had never dealt with a 64 bit string integer before...

rob-luke commented 2 years ago

Thanks mate