Skip to content

Commit e9403d8

Browse files
committed
WIP: More constants
1 parent 2b03f75 commit e9403d8

10 files changed

Lines changed: 116 additions & 35 deletions

File tree

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ dependencies:
2323
- joblib
2424
- jupyter
2525
- lazy_loader >=0.3
26+
- libxml2 !=2.14.0
2627
- mamba
2728
- matplotlib >=3.7
2829
- mffpy >=0.5.7

mne/_fiff/constants.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,9 @@
10441044
FIFF.FIFFV_COIL_FNIRS_FD_PHASE = 305 # fNIRS frequency domain phase
10451045
FIFF.FIFFV_COIL_FNIRS_RAW = FIFF.FIFFV_COIL_FNIRS_CW_AMPLITUDE # old alias
10461046
FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE = 306 # fNIRS time-domain gated amplitude
1047-
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE = 307 # fNIRS time-domain moments amplitude
1047+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY = 307 # fNIRS time-domain moments intensity
1048+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN = 308 # fNIRS time-domain moments mean
1049+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE = 309 # fNIRS time-domain moments variance
10481050

10491051
FIFF.FIFFV_COIL_EYETRACK_POS = 400 # Eye-tracking gaze position
10501052
FIFF.FIFFV_COIL_EYETRACK_PUPIL = 401 # Eye-tracking pupil size
@@ -1145,7 +1147,9 @@
11451147
FIFF.FIFFV_COIL_FNIRS_FD_AC_AMPLITUDE,
11461148
FIFF.FIFFV_COIL_FNIRS_FD_PHASE,
11471149
FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE,
1148-
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE,
1150+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY,
1151+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN,
1152+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE,
11491153
FIFF.FIFFV_COIL_MCG_42,
11501154
FIFF.FIFFV_COIL_EYETRACK_POS,
11511155
FIFF.FIFFV_COIL_EYETRACK_PUPIL,

mne/_fiff/pick.py

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,20 @@ def get_channel_type_constants(include_defaults=False):
109109
unit=FIFF.FIFF_UNIT_V,
110110
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE,
111111
),
112-
fnirs_td_moments_amplitude=dict(
112+
fnirs_td_moments_intensity=dict(
113113
kind=FIFF.FIFFV_FNIRS_CH,
114-
unit=FIFF.FIFF_UNIT_V,
115-
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE,
114+
unit=FIFF.FIFF_UNIT_UNITLESS,
115+
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY,
116+
),
117+
fnirs_td_moments_mean=dict(
118+
kind=FIFF.FIFFV_FNIRS_CH,
119+
unit=FIFF.FIFF_UNIT_S,
120+
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN,
121+
),
122+
fnirs_td_moments_variance=dict(
123+
kind=FIFF.FIFFV_FNIRS_CH,
124+
unit=FIFF.FIFF_UNIT_NONE, # TODO: Maybe someday add s^2
125+
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE,
116126
),
117127
fnirs_od=dict(kind=FIFF.FIFFV_FNIRS_CH, coil_type=FIFF.FIFFV_COIL_FNIRS_OD),
118128
hbo=dict(
@@ -208,7 +218,9 @@ def get_channel_type_constants(include_defaults=False):
208218
FIFF.FIFFV_COIL_FNIRS_FD_PHASE: "fnirs_fd_phase",
209219
FIFF.FIFFV_COIL_FNIRS_OD: "fnirs_od",
210220
FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE: "fnirs_td_gated_amplitude",
211-
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE: "fnirs_td_moments_amplitude",
221+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY: "fnirs_td_moments_intensity",
222+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN: "fnirs_td_moments_mean",
223+
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE: "fnirs_td_moments_variance",
212224
},
213225
),
214226
"eeg": (
@@ -398,13 +410,23 @@ def _triage_fnirs_pick(ch, fnirs, warned):
398410
elif ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_OD and "fnirs_od" in fnirs:
399411
return True
400412
elif (
401-
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE
402-
and "fnirs_td_moments_amplitude" in fnirs
413+
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE
414+
and "fnirs_td_gated_amplitude" in fnirs
403415
):
404416
return True
405417
elif (
406-
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE
407-
and "fnirs_td_gated_amplitude" in fnirs
418+
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY
419+
and "fnirs_td_moments_intensity" in fnirs
420+
):
421+
return True
422+
elif (
423+
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN
424+
and "fnirs_td_moments_mean" in fnirs
425+
):
426+
return True
427+
elif (
428+
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE
429+
and "fnirs_td_moments_variance" in fnirs
408430
):
409431
return True
410432
return False
@@ -885,7 +907,9 @@ def channel_indices_by_type(info, picks=None):
885907
fnirs_fd_phase=list(),
886908
fnirs_od=list(),
887909
fnirs_td_gated_amplitude=list(),
888-
fnirs_td_moments_amplitude=list(),
910+
fnirs_td_moments_intensity=list(),
911+
fnirs_td_moments_mean=list(),
912+
fnirs_td_moments_variance=list(),
889913
eyegaze=list(),
890914
pupil=list(),
891915
)
@@ -1123,8 +1147,10 @@ def _check_excludes_includes(chs, info=None, allow_bads=False):
11231147
"fnirs_fd_ac_amplitude",
11241148
"fnirs_fd_phase",
11251149
"fnirs_od",
1126-
"fnirs_td_moments_amplitude",
11271150
"fnirs_td_gated_amplitude",
1151+
"fnirs_td_moments_intensity",
1152+
"fnirs_td_moments_mean",
1153+
"fnirs_td_moments_variance",
11281154
)
11291155
_EYETRACK_CH_TYPES_SPLIT = ("eyegaze", "pupil")
11301156
_DATA_CH_TYPES_ORDER_DEFAULT = (

mne/_fiff/tests/test_constants.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
from mne.utils import requires_good_network
2828

2929
# https://github.com/mne-tools/fiff-constants/commits/master
30-
REPO = "mne-tools"
31-
COMMIT = "e27f68cbf74dbfc5193ad429cc77900a59475181"
30+
REPO = "larsoner" # TODO: Replace with upstream once merged
31+
COMMIT = "ba2288355b61b00d65d4f1d8a47ef82b83414201"
3232

3333
# These are oddities that we won't address:
3434
iod_dups = (355, 359) # these are in both MEGIN and MNE files
@@ -91,7 +91,9 @@
9191
304, # fNIRS frequency domain AC amplitude
9292
305, # fNIRS frequency domain phase
9393
306, # fNIRS time domain gated amplitude
94-
307, # fNIRS time domain moments amplitude
94+
307, # fNIRS time domain moments intensity
95+
308, # fNIRS time domain moments mean
96+
309, # fNIRS time domain moments variance
9597
400, # Eye-tracking gaze position
9698
401, # Eye-tracking pupil size
9799
1000, # For testing the MCG software

mne/cov.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,9 @@ def __init__(
15271527
fnirs_fd_phase=0.1,
15281528
fnirs_od=0.1,
15291529
fnirs_td_gated_amplitude=0.1,
1530-
fnirs_td_moments_amplitude=0.1,
1530+
fnirs_td_moments_intensity=0.1,
1531+
fnirs_td_moments_mean=0.1,
1532+
fnirs_td_moments_variance=0.1,
15311533
csd=0.1,
15321534
dbs=0.1,
15331535
store_precision=False,
@@ -1548,6 +1550,10 @@ def __init__(
15481550
self.fnirs_fd_ac_amplitude = fnirs_fd_ac_amplitude
15491551
self.fnirs_fd_phase = fnirs_fd_phase
15501552
self.fnirs_od = fnirs_od
1553+
self.fnirs_td_gated_amplitude = fnirs_td_gated_amplitude
1554+
self.fnirs_td_moments_intensity = fnirs_td_moments_intensity
1555+
self.fnirs_td_moments_mean = fnirs_td_moments_mean
1556+
self.fnirs_td_moments_variance = fnirs_td_moments_variance
15511557
self.csd = csd
15521558
self.store_precision = store_precision
15531559
self.assume_centered = assume_centered
@@ -1580,6 +1586,15 @@ def fit(self, X):
15801586
dbs=self.dbs,
15811587
hbo=self.hbo,
15821588
hbr=self.hbr,
1589+
fnirs_cw_amplitude=self.fnirs_cw_amplitude,
1590+
fnirs_fd_ac_amplitude=self.fnirs_fd_ac_amplitude,
1591+
fnirs_fd_phase=self.fnirs_fd_phase,
1592+
fnirs_od=self.fnirs_od,
1593+
fnirs_td_gated_amplitude=self.fnirs_td_gated_amplitude,
1594+
fnirs_td_moments_intensity=self.fnirs_td_moments_intensity,
1595+
fnirs_td_moments_mean=self.fnirs_td_moments_mean,
1596+
fnirs_td_moments_variance=self.fnirs_td_moments_variance,
1597+
csd=self.csd,
15831598
rank="full",
15841599
)
15851600
self.estimator_.covariance_ = self.covariance_ = cov_.data
@@ -1917,7 +1932,9 @@ def regularize(
19171932
fnirs_fd_phase=0.1,
19181933
fnirs_od=0.1,
19191934
fnirs_td_gated_amplitude=0.1,
1920-
fnirs_td_moments_amplitude=0.1,
1935+
fnirs_td_moments_intensity=0.1,
1936+
fnirs_td_moments_mean=0.1,
1937+
fnirs_td_moments_variance=0.1,
19211938
csd=0.1,
19221939
dbs=0.1,
19231940
rank=None,
@@ -1971,8 +1988,12 @@ def regularize(
19711988
Regularization factor for fNIRS optical density signals.
19721989
fnirs_td_gated_amplitude : float (default 0.1)
19731990
Regularization factor for fNIRS time domain gated amplitude signals.
1974-
fnirs_td_moments_amplitude : float (default 0.1)
1991+
fnirs_td_moments_intensity : float (default 0.1)
19751992
Regularization factor for fNIRS time domain moments amplitude signals.
1993+
fnirs_td_moments_mean : float (default 0.1)
1994+
Regularization factor for fNIRS time domain moments mean signals.
1995+
fnirs_td_moments_variance : float (default 0.1)
1996+
Regularization factor for fNIRS time domain moments variance signals.
19761997
csd : float (default 0.1)
19771998
Regularization factor for EEG-CSD signals.
19781999
dbs : float (default 0.1)
@@ -2014,7 +2035,9 @@ def regularize(
20142035
fnirs_fd_phase=fnirs_fd_phase,
20152036
fnirs_od=fnirs_od,
20162037
fnirs_td_gated_amplitude=fnirs_td_gated_amplitude,
2017-
fnirs_td_moments_amplitude=fnirs_td_moments_amplitude,
2038+
fnirs_td_moments_intensity=fnirs_td_moments_intensity,
2039+
fnirs_td_moments_mean=fnirs_td_moments_mean,
2040+
fnirs_td_moments_variance=fnirs_td_moments_variance,
20182041
csd=csd,
20192042
)
20202043

mne/defaults.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
fnirs_fd_phase="k",
3434
fnirs_od="k",
3535
fnirs_td_gated_amplitude="k",
36-
fnirs_td_moments_amplitude="k",
36+
fnirs_td_moments_intensity="k",
37+
fnirs_td_moments_mean="k",
38+
fnirs_td_moments_variance="k",
3739
csd="k",
3840
whitened="k",
3941
gsr="#666633",
@@ -62,8 +64,10 @@
6264
fnirs_fd_ac_amplitude="V",
6365
fnirs_fd_phase="rad",
6466
fnirs_od="V",
65-
fnirs_td_gated_amplitude="M",
66-
fnirs_td_moments_amplitude="M",
67+
fnirs_td_gated_amplitude="AU", # counts
68+
fnirs_td_moments_intensity="AU", # counts
69+
fnirs_td_moments_mean="s",
70+
fnirs_td_moments_variance="s²",
6771
csd="V/m²",
6872
whitened="Z",
6973
gsr="S",
@@ -92,8 +96,10 @@
9296
fnirs_fd_ac_amplitude="V",
9397
fnirs_fd_phase="rad",
9498
fnirs_od="V",
95-
fnirs_td_gated_amplitude="µM",
96-
fnirs_td_moments_amplitude="µM",
99+
fnirs_td_gated_amplitude="AU",
100+
fnirs_td_moments_intensity="AU",
101+
fnirs_td_moments_mean="s",
102+
fnirs_td_moments_variance="s²",
97103
csd="mV/m²",
98104
whitened="Z",
99105
gsr="S",
@@ -123,8 +129,10 @@
123129
fnirs_fd_ac_amplitude=1.0,
124130
fnirs_fd_phase=1.0,
125131
fnirs_od=1.0,
126-
fnirs_td_gated_amplitude=1e6,
127-
fnirs_td_moments_amplitude=1e6,
132+
fnirs_td_gated_amplitude=1.0,
133+
fnirs_td_moments_intensity=1.0,
134+
fnirs_td_moments_mean=1.0,
135+
fnirs_td_moments_variance=1.0,
128136
csd=1e3,
129137
whitened=1.0,
130138
gsr=1.0,
@@ -160,7 +168,9 @@
160168
fnirs_fd_phase=2e-1,
161169
fnirs_od=2e-2,
162170
fnirs_td_gated_amplitude=1.0,
163-
fnirs_td_moments_amplitude=1.0,
171+
fnirs_td_moments_intensity=1.0,
172+
fnirs_td_moments_mean=1.0,
173+
fnirs_td_moments_variance=1.0,
164174
csd=200e-4,
165175
dipole=1e-7,
166176
gof=1e2,
@@ -217,7 +227,9 @@
217227
fnirs_od="fNIRS (OD)",
218228
hbr="Deoxyhemoglobin",
219229
fnirs_td_gated_amplitude="fNIRS (TD amplitude)",
220-
fnirs_td_moments_amplitude="fNIRS (TD moment)",
230+
fnirs_td_moments_intensity="fNIRS (TD moment intensity)",
231+
fnirs_td_moments_mean="fNIRS (TD moment mean)",
232+
fnirs_td_moments_variance="fNIRS (TD moment variance)",
221233
gof="Goodness of fit",
222234
csd="Current source density",
223235
stim="Stimulus",

mne/io/snirf/_snirf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,8 @@ def natural_keys(text):
316316
ch_name = (
317317
f"{ch_name} moment{fnirs_moment_orders[moment_idx - 1]}"
318318
)
319-
ch_type = "fnirs_td_moments_amplitude"
319+
ch_type = "fnirs_td_moments_intensity" # TODO: FIX AND TRIAGE!
320+
# raise RuntimeError("FIX THE TYPE")
320321
need_data_scale = True
321322

322323
elif snirf_data_type == SNIRF_PROCESSED:

mne/io/snirf/tests/test_snirf.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ def test_basic_reading_and_min_process(fname):
101101
raw = optical_density(raw)
102102
if "fnirs_od" in raw:
103103
raw = beer_lambert_law(raw, ppf=6)
104-
if "fnirs_td_moments_amplitude" in raw:
104+
if "fnirs_td_moments_intensity" in raw:
105+
# TODO: Re-enable once types are triaged
106+
# assert "fnirs_td_moments_mean" in raw
107+
# assert "fnirs_td_moments_variance" in raw
105108
pass
106109
else:
107110
assert "hbo" in raw
@@ -436,7 +439,8 @@ def test_snirf_kernel(kind):
436439
n_nan = 20
437440
else:
438441
assert raw._data.shape == (1080, 14)
439-
data = raw.get_data("fnirs_td_moments_amplitude")
442+
data = raw.get_data("fnirs_td_moments_intensity")
443+
# TODO: This will need to update once we triage properly
440444
assert data.shape == raw._data.shape
441445
norm = np.nanmedian(np.linalg.norm(data, axis=-1))
442446
assert 1e5 < norm < 1e6 # TODO: 429256, is this reasonable Molars!??

mne/preprocessing/nirs/nirs.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,12 @@ def _check_channels_ordered(info, pair_vals, *, throw_errors=True, check_bads=Tr
105105
picks_chroma = _picks_to_idx(info, ["hbo", "hbr"], exclude=[], allow_empty=True)
106106

107107
# All TD moments
108-
picks_moments = _picks_to_idx(
109-
info, ["fnirs_td_moments_amplitude"], exclude=[], allow_empty=True
110-
)
108+
td_moments = [
109+
"fnirs_td_moments_intensity",
110+
"fnirs_td_moments_mean",
111+
"fnirs_td_moments_variance",
112+
]
113+
picks_moments = _picks_to_idx(info, td_moments, exclude=[], allow_empty=True)
111114

112115
# All TD gated
113116
picks_gated = _picks_to_idx(

tools/hooks/update_environment_file.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@
2222
deps |= set(section_deps)
2323
recursive_deps = set(d for d in deps if d.startswith("mne["))
2424
deps -= recursive_deps
25-
deps |= {"pip", "mamba", "nomkl"}
25+
deps |= { # ones we add to environment.yml in addition to those from pyproject.toml
26+
"pip",
27+
"mamba",
28+
"nomkl",
29+
"libxml2 !=2.14.0", # https://github.com/conda-forge/libxml2-feedstock/issues/146
30+
}
2631

2732

2833
def remove_spaces(version_spec):

0 commit comments

Comments
 (0)