mne-python
mne-python copied to clipboard
Snirf files not readable
Hi,
I am creating snirf files with pysnirf2 based on data collected with LSL in xdf format. I then want to preprocess the data in the snirf files with MNE. If I create the snirf files, the nirs group is an indexed group. So the key will be 'nirs1' as indexing starts with 1 in h5py, I believe. In the snirf documentation (https://github.com/fNIRS/snirf/blob/master/snirf_specification.md#nirsiprobesourcepos2d) the nirs group should also be an indexed group. In Homer3 the created snirf files are readable.
However, with MNE I get an error that the file does not have the nirs element. This is expected as it searches for 'nirs' as a key but the key is actually 'nirs1'.
KeyError: "Unable to open object (object 'nirs' doesn't exist)"
And opening with h5py:
<KeysViewHDF5 ['nirs1']>
My question is, if anyone has any suggestions how to fix this or if there is an quick fix for my problem so that I can actually use my files in MNE?
Another question is, how to generally handle the nirs group. As far as I understand the snirf format is based on hdf5 format and indexing generally starts at 1? Snirf files created with the aurora directly use 'nirs' as a key. Is there any standard which way it should be?
I also attached the file. subj3_mt_loc.snirf.zip
Thanks, Carla
Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴🏽♂️
@rob-luke any ideas?
Hi @Carlafrenzel, thanks for reporting (and thanks for including the problematic file!)
As for a quick fix, you could try this:
import h5py
import mne
with h5py.File('subj3_mt_loc.snirf', 'r+') as dat:
dat.move('nirs1', 'nirs')
raw = mne.io.read_raw_snirf('subj3_mt_loc.snirf')
but for me at least, that just yields a different error about the MeasurmentTime being None.
Hi,
thanks for the quick reply and fix. Your suggestion does work:)
The file I attached does indeed lack the measurementTime data. I didn't notice before. After fixing my mistake the suggested solution does work and I am now able to open the modified snirf file in MNE.
Thanks again:)
Hi @Carlafrenzel, thanks for taking the time to raise this issue.
I just took a read of the SNIRF spec, and as you say, it supports /nirs#
as valid naming. See...
All SNIRF data elements are associated with a unique HDF5 location path in the form of /root/parent/.../name. All paths must use /nirs or /nirs# (indexed group array). Note that the root /nirs can be either indexed or a non-indexed single entry.
MNE does not yet support all features of the SNIRF specification. For example, multiple measurements in one file, DCS data types etc. And the edge case you report is also not yet supported.
Further, I do not believe any manufacturers use the indexing /nirs#
, every manufacturer file I have got my hands on uses /nirs
.
As you are writing your own files, I suggest you use /nirs
rather than /nirs1
unless you have a great reason to. But, as you seem technically capable, I think the best solution would be for you to open a small PR to MNE-Python to enable reading either naming with our SNIRF reader. Can you contribute a PR?
Hi @rob-luke,
just to clarify, I do not use /nirs1 or /nirs# on purpose. This rather is an issue with creating own snirf files as pysnirf2 creates nirs as an indexed group. Similarly, if I create an .h5 file and define nirs as an indexed group I end up with /nirs1 again. The one thing I could try, which I haven't yet, is to create an .h5 file and do not create an indexed nirs group. With all other ways related to writing own snirf files with pysnirf2 and/or h5py I end up with the nirs1 problem. But now thanks to @drammock I have a solution. At least for now this works for my files and in the future I can still come up with a more elegant solution:)
Further, I do not believe any manufacturers use the indexing /nirs#, every manufacturer file I have got my hands on uses /nirs.
I really think this will be more of an issue for people who want to use data that is not coming straight from the device. In our case, for example, we used LSL as we have multiple data streams that need to be synchronized.
But, as you seem technically capable, I think the best solution would be for you to open a small PR to MNE-Python to enable reading either naming with our SNIRF reader. Can you contribute a PR?
Yes, I can definitely attempt to contribute but it's probably going to take a couple of days or so.
This rather is an issue with creating own snirf files as pysnirf2
Thanks for clarifying! This is great to know. We should definitely make sure we include support for this in MNE then.
Yes, I can definitely attempt to contribute but it's probably going to take a couple of days or so.
Great! We can guide you through the process if you need help at any point. Just yell out 😄
Great! We can guide you through the process if you need help at any point. Just yell out 😄
That would definitely be great and appreciated:)
Relevant info here: https://github.com/BUNPC/pysnirf2/issues/35