330 lines
8.1 KiB
Python
330 lines
8.1 KiB
Python
r"""Compute SSP/PCA projections for EOG artifacts.
|
|
|
|
Examples
|
|
--------
|
|
.. code-block:: console
|
|
|
|
$ mne compute_proj_eog -i sample_audvis_raw.fif -a \
|
|
--l-freq 1 --h-freq 35 \
|
|
--rej-grad 3000 --rej-mag 4000 --rej-eeg 100
|
|
|
|
or
|
|
|
|
.. code-block:: console
|
|
|
|
$ mne compute_proj_eog -i sample_audvis_raw.fif -a \
|
|
--l-freq 1 --h-freq 35 \
|
|
--rej-grad 3000 --rej-mag 4000 --rej-eeg 100 \
|
|
--proj sample_audvis_ecg-proj.fif
|
|
|
|
to exclude ECG artifacts from projection computation.
|
|
"""
|
|
|
|
# Authors: The MNE-Python contributors.
|
|
# License: BSD-3-Clause
|
|
# Copyright the MNE-Python contributors.
|
|
|
|
import os
|
|
import sys
|
|
|
|
import mne
|
|
|
|
|
|
def run():
|
|
"""Run command."""
|
|
from mne.commands.utils import get_optparser
|
|
|
|
parser = get_optparser(__file__)
|
|
|
|
parser.add_option(
|
|
"-i", "--in", dest="raw_in", help="Input raw FIF file", metavar="FILE"
|
|
)
|
|
parser.add_option(
|
|
"--tmin",
|
|
dest="tmin",
|
|
type="float",
|
|
help="Time before event in seconds",
|
|
default=-0.2,
|
|
)
|
|
parser.add_option(
|
|
"--tmax",
|
|
dest="tmax",
|
|
type="float",
|
|
help="Time after event in seconds",
|
|
default=0.2,
|
|
)
|
|
parser.add_option(
|
|
"-g",
|
|
"--n-grad",
|
|
dest="n_grad",
|
|
type="int",
|
|
help="Number of SSP vectors for gradiometers",
|
|
default=2,
|
|
)
|
|
parser.add_option(
|
|
"-m",
|
|
"--n-mag",
|
|
dest="n_mag",
|
|
type="int",
|
|
help="Number of SSP vectors for magnetometers",
|
|
default=2,
|
|
)
|
|
parser.add_option(
|
|
"-e",
|
|
"--n-eeg",
|
|
dest="n_eeg",
|
|
type="int",
|
|
help="Number of SSP vectors for EEG",
|
|
default=2,
|
|
)
|
|
parser.add_option(
|
|
"--l-freq",
|
|
dest="l_freq",
|
|
type="float",
|
|
help="Filter low cut-off frequency in Hz",
|
|
default=1,
|
|
)
|
|
parser.add_option(
|
|
"--h-freq",
|
|
dest="h_freq",
|
|
type="float",
|
|
help="Filter high cut-off frequency in Hz",
|
|
default=35,
|
|
)
|
|
parser.add_option(
|
|
"--eog-l-freq",
|
|
dest="eog_l_freq",
|
|
type="float",
|
|
help="Filter low cut-off frequency in Hz used for EOG event detection",
|
|
default=1,
|
|
)
|
|
parser.add_option(
|
|
"--eog-h-freq",
|
|
dest="eog_h_freq",
|
|
type="float",
|
|
help="Filter high cut-off frequency in Hz used for EOG event detection",
|
|
default=10,
|
|
)
|
|
parser.add_option(
|
|
"-p",
|
|
"--preload",
|
|
dest="preload",
|
|
help="Temporary file used during computation (to save memory)",
|
|
default=True,
|
|
)
|
|
parser.add_option(
|
|
"-a",
|
|
"--average",
|
|
dest="average",
|
|
action="store_true",
|
|
help="Compute SSP after averaging",
|
|
default=False,
|
|
)
|
|
parser.add_option(
|
|
"--proj", dest="proj", help="Use SSP projections from a fif file.", default=None
|
|
)
|
|
parser.add_option(
|
|
"--filtersize",
|
|
dest="filter_length",
|
|
type="int",
|
|
help="Number of taps to use for filtering",
|
|
default=2048,
|
|
)
|
|
parser.add_option(
|
|
"-j",
|
|
"--n-jobs",
|
|
dest="n_jobs",
|
|
type="int",
|
|
help="Number of jobs to run in parallel",
|
|
default=1,
|
|
)
|
|
parser.add_option(
|
|
"--rej-grad",
|
|
dest="rej_grad",
|
|
type="float",
|
|
help="Gradiometers rejection parameter in fT/cm (peak to peak amplitude)",
|
|
default=2000,
|
|
)
|
|
parser.add_option(
|
|
"--rej-mag",
|
|
dest="rej_mag",
|
|
type="float",
|
|
help="Magnetometers rejection parameter in fT (peak to peak amplitude)",
|
|
default=3000,
|
|
)
|
|
parser.add_option(
|
|
"--rej-eeg",
|
|
dest="rej_eeg",
|
|
type="float",
|
|
help="EEG rejection parameter in µV (peak to peak amplitude)",
|
|
default=50,
|
|
)
|
|
parser.add_option(
|
|
"--rej-eog",
|
|
dest="rej_eog",
|
|
type="float",
|
|
help="EOG rejection parameter in µV (peak to peak amplitude)",
|
|
default=1e9,
|
|
)
|
|
parser.add_option(
|
|
"--avg-ref",
|
|
dest="avg_ref",
|
|
action="store_true",
|
|
help="Add EEG average reference proj",
|
|
default=False,
|
|
)
|
|
parser.add_option(
|
|
"--no-proj",
|
|
dest="no_proj",
|
|
action="store_true",
|
|
help="Exclude the SSP projectors currently in the fiff file",
|
|
default=False,
|
|
)
|
|
parser.add_option(
|
|
"--bad",
|
|
dest="bad_fname",
|
|
help="Text file containing bad channels list (one per line)",
|
|
default=None,
|
|
)
|
|
parser.add_option(
|
|
"--event-id",
|
|
dest="event_id",
|
|
type="int",
|
|
help="ID to use for events",
|
|
default=998,
|
|
)
|
|
parser.add_option(
|
|
"--event-raw",
|
|
dest="raw_event_fname",
|
|
help="raw file to use for event detection",
|
|
default=None,
|
|
)
|
|
parser.add_option(
|
|
"--tstart",
|
|
dest="tstart",
|
|
type="float",
|
|
help="Start artifact detection after tstart seconds",
|
|
default=0.0,
|
|
)
|
|
parser.add_option(
|
|
"-c",
|
|
"--channel",
|
|
dest="ch_name",
|
|
type="string",
|
|
help="Custom EOG channel(s), comma separated",
|
|
default=None,
|
|
)
|
|
|
|
options, args = parser.parse_args()
|
|
|
|
raw_in = options.raw_in
|
|
|
|
if raw_in is None:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
|
|
tmin = options.tmin
|
|
tmax = options.tmax
|
|
n_grad = options.n_grad
|
|
n_mag = options.n_mag
|
|
n_eeg = options.n_eeg
|
|
l_freq = options.l_freq
|
|
h_freq = options.h_freq
|
|
eog_l_freq = options.eog_l_freq
|
|
eog_h_freq = options.eog_h_freq
|
|
average = options.average
|
|
preload = options.preload
|
|
filter_length = options.filter_length
|
|
n_jobs = options.n_jobs
|
|
reject = dict(
|
|
grad=1e-13 * float(options.rej_grad),
|
|
mag=1e-15 * float(options.rej_mag),
|
|
eeg=1e-6 * float(options.rej_eeg),
|
|
eog=1e-6 * float(options.rej_eog),
|
|
)
|
|
avg_ref = options.avg_ref
|
|
no_proj = options.no_proj
|
|
bad_fname = options.bad_fname
|
|
event_id = options.event_id
|
|
proj_fname = options.proj
|
|
raw_event_fname = options.raw_event_fname
|
|
tstart = options.tstart
|
|
ch_name = options.ch_name
|
|
|
|
if bad_fname is not None:
|
|
with open(bad_fname) as fid:
|
|
bads = [w.rstrip() for w in fid.readlines()]
|
|
print(f"Bad channels read : {bads}")
|
|
else:
|
|
bads = []
|
|
|
|
if raw_in.endswith("_raw.fif") or raw_in.endswith("-raw.fif"):
|
|
prefix = raw_in[:-8]
|
|
else:
|
|
prefix = raw_in[:-4]
|
|
|
|
eog_event_fname = prefix + "_eog-eve.fif"
|
|
|
|
if average:
|
|
eog_proj_fname = prefix + "_eog_avg-proj.fif"
|
|
else:
|
|
eog_proj_fname = prefix + "_eog-proj.fif"
|
|
|
|
raw = mne.io.read_raw_fif(raw_in, preload=preload)
|
|
|
|
if raw_event_fname is not None:
|
|
raw_event = mne.io.read_raw_fif(raw_event_fname)
|
|
else:
|
|
raw_event = raw
|
|
|
|
flat = None
|
|
projs, events = mne.preprocessing.compute_proj_eog(
|
|
raw=raw,
|
|
raw_event=raw_event,
|
|
tmin=tmin,
|
|
tmax=tmax,
|
|
n_grad=n_grad,
|
|
n_mag=n_mag,
|
|
n_eeg=n_eeg,
|
|
l_freq=l_freq,
|
|
h_freq=h_freq,
|
|
average=average,
|
|
filter_length=filter_length,
|
|
n_jobs=n_jobs,
|
|
reject=reject,
|
|
flat=flat,
|
|
bads=bads,
|
|
avg_ref=avg_ref,
|
|
no_proj=no_proj,
|
|
event_id=event_id,
|
|
eog_l_freq=eog_l_freq,
|
|
eog_h_freq=eog_h_freq,
|
|
tstart=tstart,
|
|
ch_name=ch_name,
|
|
copy=False,
|
|
)
|
|
|
|
raw.close()
|
|
|
|
if raw_event_fname is not None:
|
|
raw_event.close()
|
|
|
|
if proj_fname is not None:
|
|
print(f"Including SSP projections from : {proj_fname}")
|
|
# append the eog projs, so they are last in the list
|
|
projs = mne.read_proj(proj_fname) + projs
|
|
|
|
if isinstance(preload, str) and os.path.exists(preload):
|
|
os.remove(preload)
|
|
|
|
print(f"Writing EOG projections in {eog_proj_fname}")
|
|
mne.write_proj(eog_proj_fname, projs)
|
|
|
|
print(f"Writing EOG events in {eog_event_fname}")
|
|
mne.write_events(eog_event_fname, events)
|
|
|
|
|
|
is_main = __name__ == "__main__"
|
|
if is_main:
|
|
run()
|