-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
ENH: Convert NIRS raw data to optical density #6827
Merged
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
3a55b79
Initial framework for fnirs raw to optical density conversion
rob-luke e307139
Add optical density to docs
rob-luke bd64791
Update mne/preprocessing/tests/test_optical_density.py
rob-luke 7337b5e
Update mne/preprocessing/tests/test_optical_density.py
rob-luke e6a5a1b
Import testing
rob-luke 59a96c8
Put optical density docs in preprocessing section
rob-luke 97e0e1d
Implement optical density conversion
rob-luke acad961
Fix optical density code style issues
rob-luke d0ed6f4
Add plotting of optical density data
rob-luke 9efc700
Add defaults for optical density plotting
rob-luke f42cd3e
Update mne/preprocessing/optical_density.py
rob-luke 687b63f
Handle negative intensities in optical density conversion
rob-luke f80c0de
Add in -1* that was removed in previous commit
rob-luke 0971ef7
Add tests and fix imports for optical density
rob-luke 91ece64
Add tests for optical density conversion
rob-luke 9575d47
Use assert_allclose for testing optical density
rob-luke f3fe457
Update test_optical_density.py
larsoner 2509f1e
Update mne/preprocessing/_optical_density.py
rob-luke 79a9e76
Do not operate in place for optical density
rob-luke b2940ff
Force data to load and modify test to include preload=False condition
rob-luke File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -359,6 +359,7 @@ Projections: | |
read_ica | ||
run_ica | ||
corrmap | ||
optical_density | ||
|
||
EEG referencing: | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Authors: Robert Luke <[email protected]> | ||
# Eric Larson <[email protected]> | ||
# | ||
# License: BSD (3-clause) | ||
|
||
from ..io import BaseRaw | ||
from ..io.constants import FIFF | ||
from ..utils import _validate_type, warn | ||
from ..io.pick import _picks_to_idx | ||
|
||
import numpy as np | ||
|
||
|
||
def optical_density(raw): | ||
r"""Convert NIRS raw data to optical density. | ||
|
||
Parameters | ||
---------- | ||
raw : instance of Raw | ||
The raw data. | ||
|
||
Returns | ||
------- | ||
raw : instance of Raw | ||
The modified raw instance. | ||
|
||
""" | ||
raw = raw.copy().load_data() | ||
_validate_type(raw, BaseRaw, 'raw') | ||
picks = _picks_to_idx(raw.info, 'fnirs_raw') | ||
data_means = np.mean(raw.get_data(), axis=1) | ||
|
||
# The devices measure light intensity. Negative light intensities should | ||
# not occur. If they do it is likely due to hardware or movement issues. | ||
# Set all negative values to abs(x), this also has the benefit of ensuring | ||
# that the means are all greater than zero for the division below. | ||
if len(np.where(raw._data[picks] <= 0)[0]) > 0: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
warn("Negative intensities encountered. Setting to abs(x)") | ||
raw._data[picks] = np.abs(raw._data[picks]) | ||
rob-luke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
for ii in picks: | ||
raw._data[ii] /= data_means[ii] | ||
rob-luke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
np.log(raw._data[ii], out=raw._data[ii]) | ||
raw._data[ii] *= -1 | ||
raw.info['chs'][ii]['coil_type'] = FIFF.FIFFV_COIL_FNIRS_OD | ||
|
||
return raw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# Authors: Robert Luke <[email protected]> | ||
# Eric Larson <[email protected]> | ||
# | ||
# License: BSD (3-clause) | ||
|
||
import os.path as op | ||
|
||
from mne.datasets.testing import data_path | ||
from mne.io import read_raw_nirx, BaseRaw | ||
from mne.preprocessing import optical_density | ||
from mne.utils import _validate_type | ||
from mne.datasets import testing | ||
|
||
import pytest as pytest | ||
import numpy as np | ||
from numpy.testing import assert_allclose | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same remark. Imports should be from more general packages to local ones |
||
|
||
|
||
fname_nirx = op.join(data_path(download=False), | ||
'NIRx', 'nirx_15_2_recording_w_short') | ||
|
||
|
||
@testing.requires_testing_data | ||
def test_optical_density(): | ||
rob-luke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""Test return type for optical density.""" | ||
raw = read_raw_nirx(fname_nirx, preload=False) | ||
assert 'fnirs_raw' in raw | ||
assert 'fnirs_od' not in raw | ||
raw = optical_density(raw) | ||
_validate_type(raw, BaseRaw, 'raw') | ||
assert 'fnirs_raw' not in raw | ||
assert 'fnirs_od' in raw | ||
|
||
|
||
@testing.requires_testing_data | ||
def test_optical_density_zeromean(): | ||
"""Test that optical density can process zero mean data.""" | ||
raw = read_raw_nirx(fname_nirx, preload=True) | ||
rob-luke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
raw._data[4] -= np.mean(raw._data[4]) | ||
with pytest.warns(RuntimeWarning, match='Negative'): | ||
raw = optical_density(raw) | ||
assert 'fnirs_od' in raw | ||
|
||
|
||
@testing.requires_testing_data | ||
def test_optical_density_manual(): | ||
"""Test optical density on known values.""" | ||
test_tol = 0.01 | ||
raw = read_raw_nirx(fname_nirx, preload=True) | ||
# log(1) = 0 | ||
raw._data[4] = np.ones((145)) | ||
# log(0.5)/-1 = 0.69 | ||
# log(1.5)/-1 = -0.40 | ||
test_data = np.tile([0.5, 1.5], 73)[:145] | ||
raw._data[5] = test_data | ||
|
||
od = optical_density(raw) | ||
assert_allclose(od.get_data([4]), 0.) | ||
assert_allclose(od.get_data([5])[0, :2], [0.69, -0.4], atol=test_tol) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
numpy should have been imported before mne stuff