mne-tools / mne-tools/mne-python
Numerical warnings from `optical_density` / `temporal_derivative_distribution_repair` on channels in `info["bads"]`
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.5k
- Forks
- 1.6k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 100
Description
Describe the new feature or enhancement
Description
mne.preprocessing.nirs.optical_density and mne.preprocessing.nirs.temporal_derivative_distribution_repair are applied to channels marked as 'bad' (intentionally).
The side effect is that garbage in a 'bad' channel warns without naming it:
_optical_density.py:49: RuntimeWarning: divide by zero encountered in log
_tddr.py:97: RuntimeWarning: invalid value encountered in subtract
So users cannot tell whether the data is about to be discarded anyways or is a real problem
in a channel they keep.
Reproduction
import warnings
import numpy as np
import mne
info = mne.create_info(["S1_D1 760", "S1_D1 850", "S2_D2 760", "S2_D2 850"], 10.0,
"fnirs_cw_amplitude")
for ch in info["chs"]:
ch["loc"][6:9] = [0.03, 0.0, 0.0]
ch["loc"][9] = float(ch["ch_name"].split()[1])
data = np.random.default_rng(0).normal(1e5, 1e3, (4, 1000))
data[2, 500], data[2, 501] = -6.6e245, 8.0e-304 # corrupt samples, channel already bad
info["bads"] = ["S2_D2 760", "S2_D2 850"]
raw = mne.io.RawArray(data, info, verbose=False)
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
od = mne.preprocessing.nirs.optical_density(raw, verbose=False)
tddr = mne.preprocessing.nirs.temporal_derivative_distribution_repair(od, verbose=False)
print([str(w.message) for w in caught])
print("non-finite per channel:", (~np.isfinite(tddr.get_data())).sum(axis=1))
['Negative intensities encountered. Setting to abs(x)', 'divide by zero encountered in log',
'invalid value encountered in subtract']
non-finite per channel: [ 0 0 1000 0]
Describe your proposed implementation
Output the channel names which have bad values and let the user ignore them. This might be verbose in some cases.
Describe possible alternatives
Only warn if non-bad channels have invalid values. This does not add verbosity to the warning but might hide issues in cases where bad channels are still used.
Additional context
MNE 1.13.0.dev256+g51216abcb
I can implement if this makes sense to add.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the reproduction and inspect mne/preprocessing/nirs/_optical_density.py and _tddr.py, the files named by the warnings. Trace how channels in info["bads"] are handled during optical_density and temporal_derivative_distribution_repair. Done means warnings make the affected channel names clear and users can distinguish bad-channel artifacts from problems in retained data.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100