Closed Carlafrenzel closed 2 years ago
Hi,
I am not particularly familiar with MNE's SNIRF parser, but hopefully I can help you create a SNIRF file.
Just to clarify, you have data and want to create a SNIRF file from scratch using pysnirf2?
snirf.nirs[0].probe.appendGroup() shows: AttributeError: 'Probe' object has no attribute 'appendGroup'
This is expected, as Probe
is not an indexed Group, it is just a Group. It is required, so creating a new nirs element will create one automatically
You can add data to the probe with assignment ie
snirf.nirs[0].probe.sourcePos2D = <your array>
Feel free to share the code you are using to create the SNIRF file
Hi,
Thanks so much for the reply. Yes, we collected data with LSL and have a bunch of xdf files. The idea is now to extract the relevant information and save it as a snirf file.
snirf.nirs[0].probe.sourcePos2D =
This is exactly what I did the first time. And it seems to be alright. The problem appears when I add the remaining data and then reload the snirf file after saving. In that case the probe data is missing again? Thats why I tried appending the probe group.
The code looks like this:
snirf_file = Snirf()
snirf_file.nirs.appendGroup()
now the probe data I used another snirf file for testing if I can actually create a snirf file.
snirf_file.nirs[0].probe.coordinateSystem = None
snirf_file.nirs[0].probe.coordinateSystemDescription = None
snirf_file.nirs[0].probe.correlationTimeDelayWidths = None
snirf_file.nirs[0].probe.correlationTimeDelays = None
snirf_file.nirs[0].probe.detectorLabels = None
snirf_file.nirs[0].probe.detectorPos2D = snirf.nirs[0].probe.detectorPos2D
snirf_file.nirs[0].probe.detectorPos3D = snirf.nirs[0].probe.detectorPos3D
snirf_file.nirs[0].probe.sourcePos2D = snirf.nirs[0].probe.sourcePos2D
snirf_file.nirs[0].probe.sourcePos3D = snirf.nirs[0].probe.sourcePos3D
snirf_file.nirs[0].probe.wavelengths = snirf.nirs[0].probe.wavelengths
All Pos2D and Pos3D are numpy.ndarray, so I think the datatype is alright.
So up until this point everything is great. I can save it and re load the file and the probe data is there. As soon as I add other data the probe group shows no data if I load the file in Matlab/ Homer3. So I was wondering if I made a mistake somewhere.
I also attached the full code with the output, in case that makes a difference
But you see the second data element when loading the file with pysnirf?
Your code looks great, aside from the formatVersion actually being 1.1 :) You are also not using measurementList which is required.
I don't see how this could be your issue based on the code you sent, but note that Homer3 has uncertain support for SNIRF files with multiple data elements. That may be the issue, Homer3 expects each run to be in its own file. This is apparently also true for MNE in the output you attached:
---> 96 if 'data2' in dat['nirs']: 97 warn("File contains multiple recordings. " 98 "MNE does not support this feature. "
Hi,
I think my previous response got lost. Sorry for that!
But you see the second data element when loading the file with pysnirf?
No, I do not. And to be honest I didn't intend to have a second data element at all. I also have no idea where it is coming from? I think it very well is possible and likely that that is the cause for all my problems. Is there a way to get rid of it?
I am confused by what you are doing. I don't see in your attachment a place where you append nirs groups, but I thought that was your goal.
Post here the complete code used to generate the file (not as attachment) and attach the file itself, thanks
nirs = Snirf()
nirs.nirs.appendGroup()
nirs.nirs[0].data.appendGroup()
for i in range(0,34):
nirs.nirs[0].data[0].measurementList.appendGroup()
nirs.nirs[0].stim.appendGroup()
nirs.nirs[0].metaDataTags.SubjectID = 'default'
nirs.nirs[0].metaDataTags.FrequencyUnit = 'Hz'
nirs.nirs[0].metaDataTags.LengthUnit = 'mm'
nirs.nirs[0].metaDataTags.MeasurementDate = '2021-06-24'
nirs.nirs[0].metaDataTags.TimeUnit = 's'
nirs.nirs[0].metaDataTags.SubjectID = 'default'
nirs.nirs[0].probe.coordinateSystem = None
nirs.nirs[0].probe.coordinateSystemDescription = None
nirs.nirs[0].probe.correlationTimeDelayWidths = None
nirs.nirs[0].probe.correlationTimeDelays = None
nirs.nirs[0].probe.detectorLabels = None
nirs.nirs[0].probe.detectorPos2D = snirf.nirs[0].probe.detectorPos2D
nirs.nirs[0].probe.detectorPos3D = snirf.nirs[0].probe.detectorPos3D
nirs.nirs[0].probe.sourcePos2D = snirf.nirs[0].probe.sourcePos2D
nirs.nirs[0].probe.sourcePos3D = snirf.nirs[0].probe.sourcePos3D
nirs.nirs[0].probe.wavelengths = snirf.nirs[0].probe.wavelengths
nirs.nirs[0].data[0].dataTimeSeries = snirf.nirs[0].data[0].dataTimeSeries
nirs.nirs[0].data[0].time = snirf.nirs[0].data[0].time
for i in range(0,34):
nirs.nirs[0].data[0].measurementList[i].dataType = snirf.nirs[0].data[0].measurementList[i].dataType`
nirs.nirs[0].data[0].measurementList[i].dataTypeIndex = snirf.nirs[0].data[0].measurementList[i].dataTypeIndex
nirs.nirs[0].data[0].measurementList[i].dataTypeLabel = snirf.nirs[0].data[0].measurementList[i].dataTypeLabel
nirs.nirs[0].data[0].measurementList[i].dataUnit=snirf.nirs[0].data[0].measurementList[i].dataUnit
nirs.nirs[0].data[0].measurementList[i].detectorGain = snirf.nirs[0].data[0].measurementList[i].detectorGain
nirs.nirs[0].data[0].measurementList[i].detectorIndex=snirf.nirs[0].data[0].measurementList[i].detectorIndex
nirs.nirs[0].data[0].measurementList[i].detectorModuleIndex = snirf.nirs[0].data[0].measurementList[i].detectorModuleIndex
nirs.nirs[0].data[0].measurementList[i].moduleIndex=snirf.nirs[0].data[0].measurementList[i].moduleIndex
nirs.nirs[0].data[0].measurementList[i].sourceIndex = snirf.nirs[0].data[0].measurementList[i].sourceIndex
nirs.nirs[0].data[0].measurementList[i].sourceModuleIndex = snirf.nirs[0].data[0].measurementList[i].sourceModuleIndex
nirs.nirs[0].data[0].measurementList[i].sourcePower = snirf.nirs[0].data[0].measurementList[i].sourcePower
nirs.nirs[0].data[0].measurementList[i].wavelengthActual = snirf.nirs[0].data[0].measurementList[i].wavelengthActual
nirs.nirs[0].data[0].measurementList[i].wavelengthEmissionActual = snirf.nirs[0].data[0].measurementList[i].wavelengthEmissionActual
nirs.nirs[0].data[0].measurementList[i].wavelengthIndex = snirf.nirs[0].data[0].measurementList[i].wavelengthIndex
nirs.formatVersion = '1.0'
nirs.nirs[0].metaDataTags.MeasurementTime = '16:07:58'
nirs.save(r'Desktop/Homer/nirs_file.snirf')
nirs.close()
from pysnirf2 import validateSnirf
result = validateSnirf(r'Desktop/Homer/nirs_file.snirf')
assert result, 'Invalid SNIRF file!\n' + result.display()
Just be sure:
nirs_file.nirs[0].data[0]
will result in
DataElement at /nirs1/data1
dataTimeSeries: <(3819, 34) array of float64>
filename: Desktop/Homer/nirs_file.snirf
location: /nirs1/data1
measurementList:
<iterable of 34 <class 'pysnirf2.pysnirf2.MeasurementListElement'>>
time: <(3819,) array of float64>
But:
nirs_file.nirs[0].data[1]
leads to
IndexError: list index out of range
So this is why I can't see where there would be a second data element.
This file looks great. I was able to validate it on my end and open it in Homer3.
I don't think your issue is with pysnirf2.
Thank you so much for taking the time to go through it!
One last question. Could you let me know which version of Matlab you are using and possibly share the code you used in Homer3 for this file?
I am using the latest version of master branch of https://github.com/BUNPC/Homer3
MATLAB 2019b
Thank you so much again!
Hi, I am trying to create a snirf file from fNIRS data we have collected. I then want to use the created snirf file with Homer3 and/or MNE. In case of Homer3, the created snirf files are validated correctly but once loaded in Homer show that the probe group is empty. If I create an empty snirf file and only add the probe group data, it is working. I am a bit confused now as I have absolutely no idea why or how this is possible? I can also not append the probe group manually. snirf.nirs[0].stim.appendGroup() works but snirf.nirs[0].probe.appendGroup() shows: AttributeError: 'Probe' object has no attribute 'appendGroup'
As for MNE, none of the snirf files are even readable as all of them result in an error: KeyError: "Unable to open object (object 'nirs' doesn't exist)"
All the files are validated with validateSnirf and show no error.