Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ Yousra Bekhti <yousra.bekhti@gmail.com> Yoursa BEKHTI <ybekhti@is222485.intra.ce
Yousra Bekhti <yousra.bekhti@gmail.com> Yoursa BEKHTI <yousra.bekhti@gmail.com>
Yousra Bekhti <yousra.bekhti@gmail.com> Yousra BEKHTI <yousra.bekhti@gmail.com>
Yousra Bekhti <yousra.bekhti@gmail.com> yousrabk <yousra.bekhti@gmail.com>
Zahra M. Aghajan <zahraa.aghajani@gmail.com> Zahra M. Aghajan <zahraa.aghajani@gmail.com>
Zhi Zhang <850734033@qq.com> ZHANG Zhi <850734033@qq.com>
Zhi Zhang <850734033@qq.com> ZHANG Zhi <zhi271.zhang@connect.polyu.hk>
Ziyi ZENG <ziyizeng@link.cuhk.edu.cn> ZIYI ZENG <CME1909120@XMU.EDU.MY>
1 change: 1 addition & 0 deletions doc/changes/dev/13938.newfeature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added basic support for TD fNIRS data, by :newcontrib:`Zahra Aghajan`, :newcontrib:`Julien Dubois`, :newcontrib:`John Griffiths`, `Robert Luke`_, and `Eric Larson`_.
3 changes: 3 additions & 0 deletions doc/changes/names.inc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
.. _Johann Benerradi: https://github.com/HanBnrd
.. _Johannes Herforth: https://herforth.net
.. _Johannes Niediek: https://github.com/jniediek
.. _John Griffiths: https://www.grifflab.com
.. _John Samuelsson: https://github.com/johnsam7
.. _John Veillette: https://psychology.uchicago.edu/directory/john-veillette
.. _Jon Houck: https://www.mrn.org/people/jon-m.-houck/principal-investigators
Expand All @@ -174,6 +175,7 @@
.. _Judy D Zhu: https://github.com/JD-Zhu
.. _Juergen Dammers: https://github.com/jdammers
.. _Jukka Nenonen: https://www.linkedin.com/pub/jukka-nenonen/28/b5a/684
.. _Julien Dubois: https://github.com/jcrdubois
.. _Jussi Nurminen: https://github.com/jjnurminen
.. _Kaisu Lankinen: http://bishoplab.berkeley.edu/Kaisu.html
.. _Kalle Makela: https://github.com/Kallemakela
Expand Down Expand Up @@ -375,6 +377,7 @@
.. _Yixiao Shen: https://github.com/SYXiao2002
.. _Yousra Bekhti: https://www.linkedin.com/pub/yousra-bekhti/56/886/421
.. _Yu-Han Luo: https://github.com/yh-luo
.. _Zahra Aghajan: https://github.com/Zahra-M-Aghajan
.. _Zhi Zhang: https://github.com/tczhangzhi/
.. _Ziyi ZENG: https://github.com/ZiyiTsang
.. _Zvi Baratz: https://github.com/ZviBaratz
10 changes: 8 additions & 2 deletions mne/_fiff/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,7 @@
FIFF.FIFF_UNIT_LM = 115 # lumen
FIFF.FIFF_UNIT_LX = 116 # lux
FIFF.FIFF_UNIT_V_M2 = 117 # V/m^2
FIFF.FIFF_UNIT_SEC2 = 118 # second^2
#
# Others we need
#
Expand Down Expand Up @@ -972,6 +973,7 @@
FIFF.FIFF_UNIT_LM,
FIFF.FIFF_UNIT_LX,
FIFF.FIFF_UNIT_V_M2,
FIFF.FIFF_UNIT_SEC2,
FIFF.FIFF_UNIT_T_M,
FIFF.FIFF_UNIT_AM,
FIFF.FIFF_UNIT_AM_M2,
Expand Down Expand Up @@ -1044,7 +1046,9 @@
FIFF.FIFFV_COIL_FNIRS_FD_PHASE = 305 # fNIRS frequency domain phase
FIFF.FIFFV_COIL_FNIRS_RAW = FIFF.FIFFV_COIL_FNIRS_CW_AMPLITUDE # old alias
FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE = 306 # fNIRS time-domain gated amplitude
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE = 307 # fNIRS time-domain moments amplitude
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY = 307 # fNIRS time-domain moments intensity
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN = 308 # fNIRS time-domain moments mean
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE = 309 # fNIRS time-domain moments variance

FIFF.FIFFV_COIL_EYETRACK_POS = 400 # Eye-tracking gaze position
FIFF.FIFFV_COIL_EYETRACK_PUPIL = 401 # Eye-tracking pupil size
Expand Down Expand Up @@ -1145,7 +1149,9 @@
FIFF.FIFFV_COIL_FNIRS_FD_AC_AMPLITUDE,
FIFF.FIFFV_COIL_FNIRS_FD_PHASE,
FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE,
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_AMPLITUDE,
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY,
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN,
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE,
FIFF.FIFFV_COIL_MCG_42,
FIFF.FIFFV_COIL_EYETRACK_POS,
FIFF.FIFFV_COIL_EYETRACK_PUPIL,
Expand Down
1 change: 1 addition & 0 deletions mne/_fiff/meas_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ def set_montage(
FIFF.FIFF_UNIT_NONE: "NA",
FIFF.FIFF_UNIT_CEL: "C",
FIFF.FIFF_UNIT_S: "S",
FIFF.FIFF_UNIT_SEC: "s",
FIFF.FIFF_UNIT_PX: "px",
}

Expand Down
54 changes: 53 additions & 1 deletion mne/_fiff/pick.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ def get_channel_type_constants(include_defaults=False):
unit=FIFF.FIFF_UNIT_RAD,
coil_type=FIFF.FIFFV_COIL_FNIRS_FD_PHASE,
),
fnirs_td_gated_amplitude=dict(
kind=FIFF.FIFFV_FNIRS_CH,
unit=FIFF.FIFF_UNIT_UNITLESS,
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE,
),
fnirs_td_moments_intensity=dict(
kind=FIFF.FIFFV_FNIRS_CH,
unit=FIFF.FIFF_UNIT_UNITLESS,
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY,
),
fnirs_td_moments_mean=dict(
kind=FIFF.FIFFV_FNIRS_CH,
unit=FIFF.FIFF_UNIT_SEC,
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN,
),
fnirs_td_moments_variance=dict(
kind=FIFF.FIFFV_FNIRS_CH,
unit=FIFF.FIFF_UNIT_SEC2,
coil_type=FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE,
),
fnirs_od=dict(kind=FIFF.FIFFV_FNIRS_CH, coil_type=FIFF.FIFFV_COIL_FNIRS_OD),
hbo=dict(
kind=FIFF.FIFFV_FNIRS_CH,
Expand Down Expand Up @@ -197,6 +217,10 @@ def get_channel_type_constants(include_defaults=False):
FIFF.FIFFV_COIL_FNIRS_FD_AC_AMPLITUDE: "fnirs_fd_ac_amplitude",
FIFF.FIFFV_COIL_FNIRS_FD_PHASE: "fnirs_fd_phase",
FIFF.FIFFV_COIL_FNIRS_OD: "fnirs_od",
FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE: "fnirs_td_gated_amplitude",
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY: "fnirs_td_moments_intensity",
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN: "fnirs_td_moments_mean",
FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE: "fnirs_td_moments_variance",
},
),
"eeg": (
Expand Down Expand Up @@ -385,6 +409,26 @@ def _triage_fnirs_pick(ch, fnirs, warned):
return True
elif ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_OD and "fnirs_od" in fnirs:
return True
elif (
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_GATED_AMPLITUDE
and "fnirs_td_gated_amplitude" in fnirs
):
return True
elif (
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_INTENSITY
and "fnirs_td_moments_intensity" in fnirs
):
return True
elif (
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_MEAN
and "fnirs_td_moments_mean" in fnirs
):
return True
elif (
ch["coil_type"] == FIFF.FIFFV_COIL_FNIRS_TD_MOMENTS_VARIANCE
and "fnirs_td_moments_variance" in fnirs
):
return True
return False


Expand Down Expand Up @@ -569,7 +613,7 @@ def pick_types(
pick[k] = _triage_meg_pick(info["chs"][k], ref_meg)
elif ch_type in ("eyegaze", "pupil"):
pick[k] = _triage_eyetrack_pick(info["chs"][k], eyetrack)
else: # ch_type in ('hbo', 'hbr')
else: # ch_type in ('hbo', 'hbr', ...)
pick[k] = _triage_fnirs_pick(info["chs"][k], fnirs, warned)

# restrict channels to selection if provided
Expand Down Expand Up @@ -867,6 +911,10 @@ def channel_indices_by_type(info, picks=None, *, exclude=()):
fnirs_fd_ac_amplitude=list(),
fnirs_fd_phase=list(),
fnirs_od=list(),
fnirs_td_gated_amplitude=list(),
fnirs_td_moments_intensity=list(),
fnirs_td_moments_mean=list(),
fnirs_td_moments_variance=list(),
eyegaze=list(),
pupil=list(),
)
Expand Down Expand Up @@ -1104,6 +1152,10 @@ def _check_excludes_includes(chs, info=None, allow_bads=False):
"fnirs_fd_ac_amplitude",
"fnirs_fd_phase",
"fnirs_od",
"fnirs_td_gated_amplitude",
"fnirs_td_moments_intensity",
"fnirs_td_moments_mean",
"fnirs_td_moments_variance",
)
_EYETRACK_CH_TYPES_SPLIT = ("eyegaze", "pupil")
_DATA_CH_TYPES_ORDER_DEFAULT = (
Expand Down
6 changes: 4 additions & 2 deletions mne/_fiff/tests/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

# https://github.com/mne-tools/fiff-constants/commits/master
REPO = "mne-tools"
COMMIT = "e27f68cbf74dbfc5193ad429cc77900a59475181"
COMMIT = "9ccb09d69daa8332f2e7252638ba397b60ba2502"

# These are oddities that we won't address:
iod_dups = (355, 359) # these are in both MEGIN and MNE files
Expand Down Expand Up @@ -91,7 +91,9 @@
304, # fNIRS frequency domain AC amplitude
305, # fNIRS frequency domain phase
306, # fNIRS time domain gated amplitude
307, # fNIRS time domain moments amplitude
307, # fNIRS time domain moments intensity
308, # fNIRS time domain moments mean
309, # fNIRS time domain moments variance
400, # Eye-tracking gaze position
401, # Eye-tracking pupil size
1000, # For testing the MCG software
Expand Down
35 changes: 35 additions & 0 deletions mne/cov.py
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,7 @@ def __init__(
grad=0.1,
mag=0.1,
eeg=0.1,
*,
seeg=0.1,
ecog=0.1,
hbo=0.1,
Expand All @@ -1546,6 +1547,10 @@ def __init__(
fnirs_fd_ac_amplitude=0.1,
fnirs_fd_phase=0.1,
fnirs_od=0.1,
fnirs_td_gated_amplitude=0.1,
fnirs_td_moments_intensity=0.1,
fnirs_td_moments_mean=0.1,
fnirs_td_moments_variance=0.1,
csd=0.1,
dbs=0.1,
store_precision=False,
Expand All @@ -1566,6 +1571,10 @@ def __init__(
self.fnirs_fd_ac_amplitude = fnirs_fd_ac_amplitude
self.fnirs_fd_phase = fnirs_fd_phase
self.fnirs_od = fnirs_od
self.fnirs_td_gated_amplitude = fnirs_td_gated_amplitude
self.fnirs_td_moments_intensity = fnirs_td_moments_intensity
self.fnirs_td_moments_mean = fnirs_td_moments_mean
self.fnirs_td_moments_variance = fnirs_td_moments_variance
self.csd = csd
self.store_precision = store_precision
self.assume_centered = assume_centered
Expand Down Expand Up @@ -1598,6 +1607,15 @@ def fit(self, X):
dbs=self.dbs,
hbo=self.hbo,
hbr=self.hbr,
fnirs_cw_amplitude=self.fnirs_cw_amplitude,
fnirs_fd_ac_amplitude=self.fnirs_fd_ac_amplitude,
fnirs_fd_phase=self.fnirs_fd_phase,
fnirs_od=self.fnirs_od,
fnirs_td_gated_amplitude=self.fnirs_td_gated_amplitude,
fnirs_td_moments_intensity=self.fnirs_td_moments_intensity,
fnirs_td_moments_mean=self.fnirs_td_moments_mean,
fnirs_td_moments_variance=self.fnirs_td_moments_variance,
csd=self.csd,
rank="full",
)
self.estimator_.covariance_ = self.covariance_ = cov_.data
Expand Down Expand Up @@ -1926,6 +1944,7 @@ def regularize(
eeg=0.1,
exclude="bads",
proj=True,
*,
seeg=0.1,
ecog=0.1,
hbo=0.1,
Expand All @@ -1934,6 +1953,10 @@ def regularize(
fnirs_fd_ac_amplitude=0.1,
fnirs_fd_phase=0.1,
fnirs_od=0.1,
fnirs_td_gated_amplitude=0.1,
fnirs_td_moments_intensity=0.1,
fnirs_td_moments_mean=0.1,
fnirs_td_moments_variance=0.1,
csd=0.1,
dbs=0.1,
rank=None,
Expand Down Expand Up @@ -1985,6 +2008,14 @@ def regularize(
Regularization factor for fNIRS raw phase signals.
fnirs_od : float (default 0.1)
Regularization factor for fNIRS optical density signals.
fnirs_td_gated_amplitude : float (default 0.1)
Regularization factor for fNIRS time domain gated amplitude signals.
fnirs_td_moments_intensity : float (default 0.1)
Regularization factor for fNIRS time domain moments amplitude signals.
fnirs_td_moments_mean : float (default 0.1)
Regularization factor for fNIRS time domain moments mean signals.
fnirs_td_moments_variance : float (default 0.1)
Regularization factor for fNIRS time domain moments variance signals.
csd : float (default 0.1)
Regularization factor for EEG-CSD signals.
dbs : float (default 0.1)
Expand Down Expand Up @@ -2025,6 +2056,10 @@ def regularize(
fnirs_fd_ac_amplitude=fnirs_fd_ac_amplitude,
fnirs_fd_phase=fnirs_fd_phase,
fnirs_od=fnirs_od,
fnirs_td_gated_amplitude=fnirs_td_gated_amplitude,
fnirs_td_moments_intensity=fnirs_td_moments_intensity,
fnirs_td_moments_mean=fnirs_td_moments_mean,
fnirs_td_moments_variance=fnirs_td_moments_variance,
csd=csd,
)

Expand Down
26 changes: 25 additions & 1 deletion mne/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
fnirs_fd_ac_amplitude="k",
fnirs_fd_phase="k",
fnirs_od="k",
fnirs_td_gated_amplitude="k",
fnirs_td_moments_intensity="k",
fnirs_td_moments_mean="k",
fnirs_td_moments_variance="k",
csd="k",
whitened="k",
gsr="#666633",
Expand Down Expand Up @@ -60,6 +64,10 @@
fnirs_fd_ac_amplitude="V",
fnirs_fd_phase="rad",
fnirs_od="V",
fnirs_td_gated_amplitude="AU", # counts
fnirs_td_moments_intensity="AU", # counts
fnirs_td_moments_mean="s",
fnirs_td_moments_variance="s²",
csd="V/m²",
whitened="Z",
gsr="S",
Expand Down Expand Up @@ -88,14 +96,18 @@
fnirs_fd_ac_amplitude="V",
fnirs_fd_phase="rad",
fnirs_od="V",
fnirs_td_gated_amplitude="AU",
fnirs_td_moments_intensity="AU",
fnirs_td_moments_mean="ps",
fnirs_td_moments_variance="ps²",
csd="mV/m²",
whitened="Z",
gsr="S",
temperature="C",
eyegaze="rad",
pupil="mm",
),
# scalings for the units
# scalings for the "units" above (must match!)
scalings=dict(
mag=1e15,
grad=1e13,
Expand All @@ -117,6 +129,10 @@
fnirs_fd_ac_amplitude=1.0,
fnirs_fd_phase=1.0,
fnirs_od=1.0,
fnirs_td_gated_amplitude=1.0,
fnirs_td_moments_intensity=1.0,
fnirs_td_moments_mean=1e12,
fnirs_td_moments_variance=1e24,
csd=1e3,
whitened=1.0,
gsr=1.0,
Expand Down Expand Up @@ -151,6 +167,10 @@
fnirs_fd_ac_amplitude=2e-2,
fnirs_fd_phase=2e-1,
fnirs_od=2e-2,
fnirs_td_gated_amplitude=1.0,
fnirs_td_moments_intensity=1.0,
fnirs_td_moments_mean=1e-10,
fnirs_td_moments_variance=1e-20,
csd=200e-4,
dipole=1e-7,
gof=1e2,
Expand Down Expand Up @@ -206,6 +226,10 @@
fnirs_fd_phase="fNIRS (FD phase)",
fnirs_od="fNIRS (OD)",
hbr="Deoxyhemoglobin",
fnirs_td_gated_amplitude="fNIRS (TD amplitude)",
fnirs_td_moments_intensity="fNIRS (TD moment intensity)",
fnirs_td_moments_mean="fNIRS (TD moment mean)",
fnirs_td_moments_variance="fNIRS (TD moment variance)",
gof="Goodness of fit",
csd="Current source density",
stim="Stimulus",
Expand Down
Loading
Loading