Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNIRF import ignores timeUnit field contrary to specification #10538

Closed
samuelpowell opened this issue Apr 17, 2022 · 8 comments · Fixed by #10555
Closed

SNIRF import ignores timeUnit field contrary to specification #10538

samuelpowell opened this issue Apr 17, 2022 · 8 comments · Fixed by #10555
Assignees
Labels

Comments

@samuelpowell
Copy link

Describe the bug

When importing SNIRF data, the timeUnit field is ignored and seconds are silently assumed when computing the sampling frequency of the input data. This is contrary to the specification.

The consequence is that the computed sample rate may be incorrect.

Cause

Rather than demonstrate reproduction, one can observe the cause of this behaviour in the codebase, which makes no reference to timeUnit and computes the sampling rate assuming seconds. From master:

            samplingrate_raw = np.array(dat.get('nirs/data1/time'))
            sampling_rate = 0
            if samplingrate_raw.shape == (2, 1):
                # specified as onset/samplerate
                warn("Onset/sample rate SNIRF not yet supported.")
            else:
                # specified as time points
                fs_diff = np.around(np.diff(samplingrate_raw), decimals=4)
                if len(np.unique(fs_diff)) == 1:
                    # Uniformly sampled data
                    sampling_rate = 1. / np.unique(fs_diff)
                else:
                    # print(np.unique(fs_diff))
                    warn("Non uniform sampled data not supported.")
            if sampling_rate == 0:
                warn("Unable to extract sample rate from SNIRF file.")

Expected results

Either:

  • Throw an error if a timeUnit is both present and not equal to 's', or,
  • Correctly manipulate time vector according to unit specified.

Actual results

The timeUnit is silently ignored and the resulting sampling frequency is incorrect.

Additional information

Error present on master.

@welcome
Copy link

welcome bot commented Apr 17, 2022

Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴🏽‍♂️

@agramfort
Copy link
Member

ping @rob-luke

@rob-luke
Copy link
Member

@samuelpowell is correct. I will discuss with him today how we can fix this and get a test file.

In general, the SNIRF specification is very large, and MNE only covers a small amount of what can be stored. I have been taking a pragmatic approach and just ensuring we can read data from all the manafacturers. But I will take more care in future PRs to add some defensive programming and throwing some more warnings.

@rob-luke rob-luke added the fNIRS label Apr 20, 2022
@rob-luke rob-luke self-assigned this Apr 20, 2022
@samuelpowell
Copy link
Author

Sample file posted in connected issue. Sample rate in this file is 6.67 Hz (e.g. the time vector is [0, 150] ms).

@samuelpowell
Copy link
Author

@rob-luke please note that the sample file I provided included events (stim entries) whose timestamps matches the timeUnit. It transpires this is out of spec and the stim entries always use seconds. I've corrected this and ill provide a smaller sample file shortly, as requested.

@rob-luke
Copy link
Member

That's madness from the spec. So your data could be in ms and your stim times would be in s? Crazy.

@samuelpowell
Copy link
Author

Indeed so, I will open an issue but this is a breaking change. Note that I'm away until Thursday but will pick up on everything promised when I return.

@samuelpowell
Copy link
Author

@rob-luke I attach a pair of smaller sample files. The recordings were made using only three tiles (216 channels) in an eighteen tile cap (10Hz output data rate), include landmarks and sample events, and were converted using version 1.1 of our conversation package.

There are two files included which have some small differences which we have previously discussed.

  • mne_sample_18_FU3_29_04_22_20_40_12_standard.snirf : default output format, channels in an arbitrary order, landmarks using LUMO names (Al, Ar, Inion, Nasion, Cz).
  • mne_sample_18_FU3_29_04_22_20_40_12_mnestyle.snirf : mne output style, channels reordered to alternate in wavelength, landmarks translated (Al->LPA, Ar -> RPA, Nasion->NASION).

At present, only the latter will load in MNE-NIRS, as the former will result in a ValueError: NIRS channels not ordered correctly. Channels must be ordered as source detector pairs with alternating frequencies: 735 & 850.

The current problems are:

  • time unit (this issue)
  • channel ordering (no issue opened but we have discussed this and I understand you would like to support arbitrary ordering)
  • automatic registration (linked issue)

mne_sample_18_FU3_29_04_22_20_40_12.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants