initial commit

This commit is contained in:
2025-08-19 09:13:22 -07:00
parent 28464811d6
commit 0977a3e14d
820 changed files with 1003358 additions and 2 deletions

8
mne/commands/__init__.py Normal file
View File

@@ -0,0 +1,8 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Command-line utilities."""
import lazy_loader as lazy
(__getattr__, __dir__, __all__) = lazy.attach_stub(__name__, __file__)

View File

@@ -0,0 +1,2 @@
__all__ = ["utils"]
from . import utils

View File

@@ -0,0 +1,127 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Anonymize raw fif file.
To anonymize other file types call :func:`mne.io.anonymize_info` on their
:class:`~mne.Info` objects and resave to disk.
Examples
--------
.. code-block:: console
$ mne anonymize -f sample_audvis_raw.fif
"""
import os.path as op
import sys
import mne
ANONYMIZE_FILE_PREFIX = "anon"
def mne_anonymize(fif_fname, out_fname, keep_his, daysback, overwrite):
"""Call *anonymize_info* on fif file and save.
Parameters
----------
fif_fname : path-like
Raw fif File
out_fname : path-like | None
Output file name
relative paths are saved relative to parent dir of fif_fname
None will save to parent dir of fif_fname with default prefix
daysback : int | None
Number of days to subtract from all dates.
If None will default to move date of service to Jan 1 2000
keep_his : bool
If True his_id of subject_info will NOT be overwritten.
defaults to False
overwrite : bool
Overwrite output file if it already exists
"""
raw = mne.io.read_raw_fif(fif_fname, allow_maxshield=True)
raw.anonymize(daysback=daysback, keep_his=keep_his)
# determine out_fname
dir_name = op.split(fif_fname)[0]
if out_fname is None:
fif_bname = op.basename(fif_fname)
out_fname = op.join(dir_name, f"{ANONYMIZE_FILE_PREFIX}-{fif_bname}")
elif not op.isabs(out_fname):
out_fname = op.join(dir_name, out_fname)
raw.save(out_fname, overwrite=overwrite)
def run():
"""Run *mne_anonymize* command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-f",
"--file",
type="string",
dest="file",
help="Name of file to modify.",
metavar="FILE",
default=None,
)
parser.add_option(
"-o",
"--output",
type="string",
dest="output",
help="Name of anonymized output file."
"`anon-` prefix is added to FILE if not given",
metavar="OUTFILE",
default=None,
)
parser.add_option(
"--keep_his",
dest="keep_his",
action="store_true",
help="Keep the HIS tag (not advised)",
default=False,
)
parser.add_option(
"-d",
"--daysback",
type="int",
dest="daysback",
help="Move dates in file backwards by this many days.",
metavar="N_DAYS",
default=None,
)
parser.add_option(
"--overwrite",
dest="overwrite",
action="store_true",
help="Overwrite input file.",
default=False,
)
options, args = parser.parse_args()
if options.file is None:
parser.print_help()
sys.exit(1)
fname = options.file
out_fname = options.output
keep_his = options.keep_his
daysback = options.daysback
overwrite = options.overwrite
if not fname.endswith(".fif"):
raise ValueError(f"{fname} does not seem to be a .fif file.")
mne_anonymize(fname, out_fname, keep_his, daysback, overwrite)
is_main = __name__ == "__main__"
if is_main:
run()

View File

@@ -0,0 +1,220 @@
r"""Browse raw data.
This uses :func:`mne.io.read_raw` so it supports the same formats
(without keyword arguments).
Examples
--------
.. code-block:: console
$ mne browse_raw sample_audvis_raw.fif \
--proj sample_audvis_ecg-proj.fif \
--eve sample_audvis_raw-eve.fif
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
from mne.viz import _RAW_CLIP_DEF
parser = get_optparser(__file__, usage="usage: %prog raw [options]")
parser.add_option(
"--raw",
dest="raw_in",
help="Input raw FIF file (can also be specified "
"directly as an argument without the --raw prefix)",
metavar="FILE",
)
parser.add_option(
"--proj", dest="proj_in", help="Projector file", metavar="FILE", default=""
)
parser.add_option(
"--projoff",
dest="proj_off",
help="Disable all projectors",
default=False,
action="store_true",
)
parser.add_option(
"--eve", dest="eve_in", help="Events file", metavar="FILE", default=""
)
parser.add_option(
"-d",
"--duration",
dest="duration",
type="float",
help="Time window for plotting (s)",
default=10.0,
)
parser.add_option(
"-t",
"--start",
dest="start",
type="float",
help="Initial start time for plotting",
default=0.0,
)
parser.add_option(
"-n",
"--n_channels",
dest="n_channels",
type="int",
help="Number of channels to plot at a time",
default=20,
)
parser.add_option(
"-o",
"--order",
dest="group_by",
help="Order to use for grouping during plotting ('type' or 'original')",
default="type",
)
parser.add_option(
"-p",
"--preload",
dest="preload",
help="Preload raw data (for faster navigation)",
default=False,
action="store_true",
)
parser.add_option(
"-s",
"--show_options",
dest="show_options",
help="Show projection options dialog",
default=False,
)
parser.add_option(
"--allowmaxshield",
dest="maxshield",
help="Allow loading MaxShield processed data",
action="store_true",
)
parser.add_option(
"--highpass",
dest="highpass",
type="float",
help="Display high-pass filter corner frequency",
default=-1,
)
parser.add_option(
"--lowpass",
dest="lowpass",
type="float",
help="Display low-pass filter corner frequency",
default=-1,
)
parser.add_option(
"--filtorder",
dest="filtorder",
type="int",
help="Display filtering IIR order (or 0 to use FIR)",
default=4,
)
parser.add_option(
"--clipping",
dest="clipping",
help="Enable trace clipping mode. Can be 'clamp', 'transparent', a float, "
"or 'none'.",
default=_RAW_CLIP_DEF,
)
parser.add_option(
"--filterchpi",
dest="filterchpi",
help="Enable filtering cHPI signals.",
default=None,
action="store_true",
)
parser.add_option(
"--butterfly",
dest="butterfly",
help="Plot in butterfly mode",
default=False,
action="store_true",
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
if len(args):
raw_in = args[0]
else:
raw_in = options.raw_in
duration = options.duration
start = options.start
n_channels = options.n_channels
group_by = options.group_by
preload = options.preload
show_options = options.show_options
proj_in = options.proj_in
proj_off = options.proj_off
eve_in = options.eve_in
maxshield = options.maxshield
highpass = options.highpass
lowpass = options.lowpass
filtorder = options.filtorder
clipping = options.clipping
if isinstance(clipping, str):
if clipping.lower() == "none":
clipping = None
else:
try:
clipping = float(clipping) # allow float and convert it
except ValueError:
pass
filterchpi = options.filterchpi
verbose = options.verbose
butterfly = options.butterfly
if raw_in is None:
parser.print_help()
sys.exit(1)
kwargs = dict(preload=preload)
if maxshield:
kwargs.update(allow_maxshield="yes")
raw = mne.io.read_raw(raw_in, **kwargs)
if len(proj_in) > 0:
projs = mne.read_proj(proj_in)
raw.info["projs"] = projs
if len(eve_in) > 0:
events = mne.read_events(eve_in)
else:
events = None
if filterchpi:
if not preload:
raise RuntimeError("Raw data must be preloaded for chpi, use --preload")
raw = mne.chpi.filter_chpi(raw)
highpass = None if highpass < 0 or filtorder < 0 else highpass
lowpass = None if lowpass < 0 or filtorder < 0 else lowpass
raw.plot(
duration=duration,
start=start,
n_channels=n_channels,
group_by=group_by,
show_options=show_options,
events=events,
highpass=highpass,
lowpass=lowpass,
filtorder=filtorder,
clipping=clipping,
butterfly=butterfly,
proj=not proj_off,
verbose=verbose,
show=True,
block=True,
)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,122 @@
"""Import BTi / 4D MagnesWH3600 data to fif file.
Notes
-----
1. Currently direct inclusion of reference channel weights
is not supported. Please use 'mne_create_comp_data' to include
the weights or use the low level functions from this module to
include them by yourself.
2. The informed guess for the 4D name is E31 for the ECG channel and
E63, E63 for the EOG channels. Please check and adjust if those channels
are present in your dataset but 'ECG 01' and 'EOG 01', 'EOG 02' don't
appear in the channel names of the raw object.
Examples
--------
.. code-block:: console
$ mne bti2fiff --pdf C,rfDC -o my_raw.fif
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
from mne.io import read_raw_bti
def run():
"""Run command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-p", "--pdf", dest="pdf_fname", help="Input data file name", metavar="FILE"
)
parser.add_option(
"-c",
"--config",
dest="config_fname",
help="Input config file name",
metavar="FILE",
default="config",
)
parser.add_option(
"--head_shape",
dest="head_shape_fname",
help="Headshape file name",
metavar="FILE",
default="hs_file",
)
parser.add_option(
"-o",
"--out_fname",
dest="out_fname",
help="Name of the resulting fiff file",
default="as_data_fname",
)
parser.add_option(
"-r",
"--rotation_x",
dest="rotation_x",
type="float",
help="Compensatory rotation about Neuromag x axis, deg",
default=2.0,
)
parser.add_option(
"-T",
"--translation",
dest="translation",
type="str",
help="Default translation, meter",
default=(0.00, 0.02, 0.11),
)
parser.add_option(
"--ecg_ch", dest="ecg_ch", type="str", help="4D ECG channel name", default="E31"
)
parser.add_option(
"--eog_ch",
dest="eog_ch",
type="str",
help="4D EOG channel names",
default="E63,E64",
)
options, args = parser.parse_args()
pdf_fname = options.pdf_fname
if pdf_fname is None:
parser.print_help()
sys.exit(1)
config_fname = options.config_fname
head_shape_fname = options.head_shape_fname
out_fname = options.out_fname
rotation_x = options.rotation_x
translation = options.translation
ecg_ch = options.ecg_ch
eog_ch = options.ecg_ch.split(",")
if out_fname == "as_data_fname":
out_fname = pdf_fname + "_raw.fif"
raw = read_raw_bti(
pdf_fname=pdf_fname,
config_fname=config_fname,
head_shape_fname=head_shape_fname,
rotation_x=rotation_x,
translation=translation,
ecg_ch=ecg_ch,
eog_ch=eog_ch,
)
raw.save(out_fname)
raw.close()
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,232 @@
"""Clean a raw file from EOG and ECG artifacts with PCA (ie SSP).
Examples
--------
.. code-block:: console
$ mne clean_eog_ecg -i in_raw.fif -o clean_raw.fif -e -c
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def clean_ecg_eog(
in_fif_fname,
out_fif_fname=None,
eog=True,
ecg=True,
ecg_proj_fname=None,
eog_proj_fname=None,
ecg_event_fname=None,
eog_event_fname=None,
in_path=".",
quiet=False,
):
"""Clean ECG from raw fif file.
Parameters
----------
in_fif_fname : path-like
Raw fif File
eog_event_fname : str
name of EOG event file required.
eog : bool
Reject or not EOG artifacts.
ecg : bool
Reject or not ECG artifacts.
ecg_event_fname : str
name of ECG event file required.
in_path : str
Path where all the files are.
"""
if not eog and not ecg:
raise Exception("EOG and ECG cannot be both disabled")
# Reading fif File
raw_in = mne.io.read_raw_fif(in_fif_fname)
if in_fif_fname.endswith("_raw.fif") or in_fif_fname.endswith("-raw.fif"):
prefix = in_fif_fname[:-8]
else:
prefix = in_fif_fname[:-4]
if out_fif_fname is None:
out_fif_fname = prefix + "_clean_ecg_eog_raw.fif"
if ecg_proj_fname is None:
ecg_proj_fname = prefix + "_ecg-proj.fif"
if eog_proj_fname is None:
eog_proj_fname = prefix + "_eog-proj.fif"
if ecg_event_fname is None:
ecg_event_fname = prefix + "_ecg-eve.fif"
if eog_event_fname is None:
eog_event_fname = prefix + "_eog-eve.fif"
print("Implementing ECG and EOG artifact rejection on data")
kwargs = dict() if quiet else dict(stdout=None, stderr=None)
if ecg:
ecg_events, _, _ = mne.preprocessing.find_ecg_events(
raw_in, reject_by_annotation=True
)
print(f"Writing ECG events in {ecg_event_fname}")
mne.write_events(ecg_event_fname, ecg_events)
print("Computing ECG projector")
command = (
"mne_process_raw",
"--cd",
in_path,
"--raw",
in_fif_fname,
"--events",
ecg_event_fname,
"--makeproj",
"--projtmin",
"-0.08",
"--projtmax",
"0.08",
"--saveprojtag",
"_ecg-proj",
"--projnmag",
"2",
"--projngrad",
"1",
"--projevent",
"999",
"--highpass",
"5",
"--lowpass",
"35",
"--projmagrej",
"4000",
"--projgradrej",
"3000",
)
mne.utils.run_subprocess(command, **kwargs)
if eog:
eog_events = mne.preprocessing.find_eog_events(raw_in)
print(f"Writing EOG events in {eog_event_fname}")
mne.write_events(eog_event_fname, eog_events)
print("Computing EOG projector")
command = (
"mne_process_raw",
"--cd",
in_path,
"--raw",
in_fif_fname,
"--events",
eog_event_fname,
"--makeproj",
"--projtmin",
"-0.15",
"--projtmax",
"0.15",
"--saveprojtag",
"_eog-proj",
"--projnmag",
"2",
"--projngrad",
"2",
"--projevent",
"998",
"--lowpass",
"35",
"--projmagrej",
"4000",
"--projgradrej",
"3000",
)
mne.utils.run_subprocess(command, **kwargs)
if out_fif_fname is not None:
# Applying the ECG EOG projector
print("Applying ECG EOG projector")
command = (
"mne_process_raw",
"--cd",
in_path,
"--raw",
in_fif_fname,
"--proj",
in_fif_fname,
"--projoff",
"--save",
out_fif_fname,
"--filteroff",
"--proj",
ecg_proj_fname,
"--proj",
eog_proj_fname,
)
mne.utils.run_subprocess(command, **kwargs)
print("Done removing artifacts.")
print(f"Cleaned raw data saved in: {out_fif_fname}")
print("IMPORTANT : Please eye-ball the data !!")
else:
print("Projection not applied to raw data.")
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(
"-o",
"--out",
dest="raw_out",
help="Output raw FIF file",
metavar="FILE",
default=None,
)
parser.add_option(
"-e",
"--no-eog",
dest="eog",
action="store_false",
help="Remove EOG",
default=True,
)
parser.add_option(
"-c",
"--no-ecg",
dest="ecg",
action="store_false",
help="Remove ECG",
default=True,
)
parser.add_option(
"-q",
"--quiet",
dest="quiet",
action="store_true",
help="Suppress mne_process_raw output",
default=False,
)
options, args = parser.parse_args()
if options.raw_in is None:
parser.print_help()
sys.exit(1)
raw_in = options.raw_in
raw_out = options.raw_out
eog = options.eog
ecg = options.ecg
quiet = options.quiet
clean_ecg_eog(raw_in, raw_out, eog=eog, ecg=ecg, quiet=quiet)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,32 @@
"""Compare FIFF files.
Examples
--------
.. code-block:: console
$ mne compare_fiff test_raw.fif test_raw_sss.fif
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def run():
"""Run command."""
parser = mne.commands.utils.get_optparser(
__file__, usage="mne compare_fiff <file_a> <file_b>"
)
options, args = parser.parse_args()
if len(args) != 2:
parser.print_help()
sys.exit(1)
mne.viz.compare_fiff(args[0], args[1])
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,331 @@
r"""Compute SSP/PCA projections for ECG artifacts.
Examples
--------
.. code-block:: console
$ mne compute_proj_ecg -i sample_audvis_raw.fif -c "MEG 1531" -a \
--l-freq 1 --h-freq 100 \
--rej-grad 3000 --rej-mag 4000 --rej-eeg 100
"""
# 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.4,
)
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=100,
)
parser.add_option(
"--ecg-l-freq",
dest="ecg_l_freq",
type="float",
help="Filter low cut-off frequency in Hz used for ECG event detection",
default=5,
)
parser.add_option(
"--ecg-h-freq",
dest="ecg_h_freq",
type="float",
help="Filter high cut-off frequency in Hz used for ECG event detection",
default=35,
)
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(
"-c",
"--channel",
dest="ch_name",
help="Channel to use for ECG detection (Required if no ECG found)",
default=None,
)
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=250,
)
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=999,
)
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(
"--qrsthr",
dest="qrs_threshold",
type="string",
help="QRS detection threshold. Between 0 and 1. Can "
"also be 'auto' for automatic selection",
default="auto",
)
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
ecg_l_freq = options.ecg_l_freq
ecg_h_freq = options.ecg_h_freq
average = options.average
preload = options.preload
filter_length = options.filter_length
n_jobs = options.n_jobs
ch_name = options.ch_name
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
qrs_threshold = options.qrs_threshold
if qrs_threshold != "auto":
try:
qrs_threshold = float(qrs_threshold)
except ValueError:
raise ValueError('qrsthr must be "auto" or a float')
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]
ecg_event_fname = prefix + "_ecg-eve.fif"
if average:
ecg_proj_fname = prefix + "_ecg_avg-proj.fif"
else:
ecg_proj_fname = prefix + "_ecg-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_ecg(
raw,
raw_event,
tmin,
tmax,
n_grad,
n_mag,
n_eeg,
l_freq,
h_freq,
average,
filter_length,
n_jobs,
ch_name,
reject,
flat,
bads,
avg_ref,
no_proj,
event_id,
ecg_l_freq,
ecg_h_freq,
tstart,
qrs_threshold,
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 ecg 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 ECG projections in {ecg_proj_fname}")
mne.write_proj(ecg_proj_fname, projs)
print(f"Writing ECG events in {ecg_event_fname}")
mne.write_events(ecg_event_fname, events)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,329 @@
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()

116
mne/commands/mne_coreg.py Normal file
View File

@@ -0,0 +1,116 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Open the coregistration GUI.
Examples
--------
.. code-block:: console
$ mne coreg
"""
import os.path as op
import mne
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
default=None,
help="Subjects directory",
)
parser.add_option(
"-s", "--subject", dest="subject", default=None, help="Subject name"
)
parser.add_option(
"-f",
"--fiff",
dest="inst",
default=None,
help="FIFF file with digitizer data for coregistration",
)
parser.add_option(
"--head-opacity",
type=float,
default=None,
dest="head_opacity",
help="The opacity of the head surface, in the range [0, 1].",
)
parser.add_option(
"--high-res-head",
action="store_true",
default=False,
dest="high_res_head",
help="Use a high-resolution head surface.",
)
parser.add_option(
"--low-res-head",
action="store_true",
default=False,
dest="low_res_head",
help="Use a low-resolution head surface.",
)
parser.add_option(
"--trans",
dest="trans",
default=None,
help='Head<->MRI transform FIF file ("-trans.fif")',
)
parser.add_option(
"--interaction",
type=str,
default=None,
dest="interaction",
help='Interaction style to use, can be "trackball" or "terrain".',
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
if options.low_res_head:
if options.high_res_head:
raise ValueError(
"Can't specify --high-res-head and --low-res-head at the same time."
)
head_high_res = False
elif options.high_res_head:
head_high_res = True
else:
head_high_res = None
# expanduser allows ~ for --subjects-dir
subjects_dir = options.subjects_dir
if subjects_dir is not None:
subjects_dir = op.expanduser(subjects_dir)
trans = options.trans
if trans is not None:
trans = op.expanduser(trans)
import faulthandler
faulthandler.enable()
mne.gui.coregistration(
inst=options.inst,
subject=options.subject,
subjects_dir=subjects_dir,
head_opacity=options.head_opacity,
head_high_res=head_high_res,
trans=trans,
interaction=options.interaction,
show=True,
block=True,
verbose=options.verbose,
)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,194 @@
"""Create 3-layer BEM model from Flash MRI images.
Examples
--------
.. code-block:: console
$ mne flash_bem --subject=sample
$ mne flash_bem -s sample -n --registered -5 sample/mri/mef05.mgz -3 sample/mri/mef30.mgz
$ mne flash_bem -s sample -n --registered -5 sample/mri/flash/mef05_*.mgz -3 sample/mri/flash/mef30_*.mgz
Notes
-----
This program assumes that FreeSurfer and MNE are installed and
sourced properly.
This function extracts the BEM surfaces (outer skull, inner skull, and
outer skin) from multiecho FLASH MRI data with spin angles of 5 and 30
degrees. The multiecho FLASH data can be input as .mgz or .nii files.
This function assumes that the Freesurfer segmentation of the subject
has been completed. In particular, the T1.mgz and brain.mgz MRI volumes
should be, as usual, in the subject's mri directory.
""" # noqa E501
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import mne
from mne.bem import convert_flash_mris, make_flash_bem
def _vararg_callback(option, opt_str, value, parser):
assert value is None
del opt_str # required for input but not used
value = []
for arg in parser.rargs:
# stop on --foo like options
if arg[:2] == "--" and len(arg) > 2:
break
if arg[:1] == "-" and len(arg) > 1:
break
value.append(arg)
del parser.rargs[: len(value)]
setattr(parser.values, option.dest, value)
def run():
"""Run command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-s", "--subject", dest="subject", help="Subject name", default=None
)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
help="Subjects directory",
default=None,
)
parser.add_option(
"-3",
"--flash30",
"--noflash30",
dest="flash30",
action="callback",
callback=_vararg_callback,
help=(
"The 30-degree flip angle data. If no argument do "
"not use flash30. If arguments are given, them as "
"file names."
),
)
parser.add_option(
"-5",
"--flash5",
dest="flash5",
action="callback",
callback=_vararg_callback,
help=("Path to the multiecho flash 5 images. Can be one file or one per echo."),
)
parser.add_option(
"-r",
"--registered",
dest="registered",
action="store_true",
default=False,
help=(
"Set if the Flash MRI images have already "
"been registered with the T1.mgz file."
),
)
parser.add_option(
"-n",
"--noconvert",
dest="noconvert",
action="store_true",
default=False,
help=(
"[DEPRECATED] Assume that the Flash MRI images "
"have already been converted to mgz files"
),
)
parser.add_option(
"-u",
"--unwarp",
dest="unwarp",
action="store_true",
default=False,
help=(
"Run grad_unwarp with -unwarp <type> "
"option on each of the converted data sets"
),
)
parser.add_option(
"-o",
"--overwrite",
dest="overwrite",
action="store_true",
default=False,
help="Write over existing .surf files in bem folder",
)
parser.add_option(
"-v",
"--view",
dest="show",
action="store_true",
help="Show BEM model in 3D for visual inspection",
default=False,
)
parser.add_option(
"--copy",
dest="copy",
help="Use copies instead of symlinks for surfaces",
action="store_true",
)
parser.add_option(
"-p",
"--flash-path",
dest="flash_path",
default=None,
help="[DEPRECATED] The directory containing flash5.mgz "
"files (defaults to "
"$SUBJECTS_DIR/$SUBJECT/mri/flash/parameter_maps",
)
options, _ = parser.parse_args()
subject = options.subject
subjects_dir = options.subjects_dir
flash5 = options.flash5
if flash5 is None or len(flash5) == 0:
flash5 = True
flash30 = options.flash30
if flash30 is None:
flash30 = True
elif len(flash30) == 0:
flash30 = False
register = not options.registered
unwarp = options.unwarp
overwrite = options.overwrite
show = options.show
copy = options.copy
if options.subject is None:
parser.print_help()
raise RuntimeError("The subject argument must be set")
flash5_img = convert_flash_mris(
subject=subject,
subjects_dir=subjects_dir,
flash5=flash5,
flash30=flash30,
unwarp=unwarp,
verbose=True,
)
make_flash_bem(
subject=subject,
subjects_dir=subjects_dir,
overwrite=overwrite,
show=show,
copy=copy,
register=register,
flash5_img=flash5_img,
verbose=True,
)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,114 @@
"""View the 3-Layers BEM model using Freeview.
Examples
--------
.. code-block:: console
$ mne freeview_bem_surfaces -s sample
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import os
import os.path as op
import sys
import mne
from mne.utils import get_subjects_dir, run_subprocess
def freeview_bem_surfaces(subject, subjects_dir, method=None):
"""View 3-Layers BEM model with Freeview.
Parameters
----------
subject : str
Subject name
subjects_dir : path-like
Directory containing subjects data (Freesurfer SUBJECTS_DIR)
method : str | None
Can be ``'flash'`` or ``'watershed'``, or None to use the ``bem/`` directory
files.
"""
subjects_dir = str(get_subjects_dir(subjects_dir, raise_error=True))
if subject is None:
raise ValueError("subject argument is None.")
subject_dir = op.join(subjects_dir, subject)
if not op.isdir(subject_dir):
raise ValueError(
f"Wrong path: '{subject_dir}'. Check subjects-dir or subject argument."
)
env = os.environ.copy()
env["SUBJECT"] = subject
env["SUBJECTS_DIR"] = subjects_dir
if "FREESURFER_HOME" not in env:
raise RuntimeError("The FreeSurfer environment needs to be set up.")
mri_dir = op.join(subject_dir, "mri")
bem_dir = op.join(subject_dir, "bem")
mri = op.join(mri_dir, "T1.mgz")
if method == "watershed":
bem_dir = op.join(bem_dir, "watershed")
outer_skin = op.join(bem_dir, f"{subject}_outer_skin_surface")
outer_skull = op.join(bem_dir, f"{subject}_outer_skull_surface")
inner_skull = op.join(bem_dir, f"{subject}_inner_skull_surface")
else:
if method == "flash":
bem_dir = op.join(bem_dir, "flash")
outer_skin = op.join(bem_dir, "outer_skin.surf")
outer_skull = op.join(bem_dir, "outer_skull.surf")
inner_skull = op.join(bem_dir, "inner_skull.surf")
# put together the command
cmd = ["freeview"]
cmd += ["--volume", mri]
cmd += ["--surface", f"{inner_skull}:color=red:edgecolor=red"]
cmd += ["--surface", f"{outer_skull}:color=yellow:edgecolor=yellow"]
cmd += ["--surface", f"{outer_skin}:color=255,170,127:edgecolor=255,170,127"]
run_subprocess(cmd, env=env, stdout=sys.stdout)
print("[done]")
def run():
"""Run command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__)
subject = os.environ.get("SUBJECT")
parser.add_option(
"-s", "--subject", dest="subject", help="Subject name", default=subject
)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
help="Subjects directory",
)
parser.add_option(
"-m",
"--method",
dest="method",
help="Method used to generate the BEM model. Can be flash or watershed.",
)
options, args = parser.parse_args()
subject = options.subject
subjects_dir = options.subjects_dir
method = options.method
freeview_bem_surfaces(subject, subjects_dir, method)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,114 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Import KIT / NYU data to fif file.
Examples
--------
.. code-block:: console
$ mne kit2fiff --input input.sqd --output output.fif
Use without arguments to invoke GUI:
.. code-block:: console
$ mne kt2fiff
"""
import sys
import mne
from mne.io import read_raw_kit
def run():
"""Run command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__)
parser.add_option(
"--input", dest="input_fname", help="Input data file name", metavar="filename"
)
parser.add_option(
"--mrk", dest="mrk_fname", help="MEG Marker file name", metavar="filename"
)
parser.add_option(
"--elp", dest="elp_fname", help="Headshape points file name", metavar="filename"
)
parser.add_option(
"--hsp", dest="hsp_fname", help="Headshape file name", metavar="filename"
)
parser.add_option(
"--stim",
dest="stim",
help="Colon Separated Stimulus Trigger Channels",
metavar="chs",
)
parser.add_option("--slope", dest="slope", help="Slope direction", metavar="slope")
parser.add_option(
"--stimthresh",
dest="stimthresh",
default=1,
help="Threshold value for trigger channels",
metavar="value",
)
parser.add_option(
"--output",
dest="out_fname",
help="Name of the resulting fiff file",
metavar="filename",
)
parser.add_option(
"--debug",
dest="debug",
action="store_true",
default=False,
help="Set logging level for terminal output to debug",
)
options, args = parser.parse_args()
if options.debug:
mne.set_log_level("debug")
input_fname = options.input_fname
if input_fname is None:
try:
from mne_kit_gui import kit2fiff # noqa
except ImportError:
raise ImportError(
"The mne-kit-gui package is required, install it using conda or pip"
) from None
kit2fiff()
sys.exit(0)
hsp_fname = options.hsp_fname
elp_fname = options.elp_fname
mrk_fname = options.mrk_fname
stim = options.stim
slope = options.slope
stimthresh = options.stimthresh
out_fname = options.out_fname
if isinstance(stim, str):
stim = map(int, stim.split(":"))
raw = read_raw_kit(
input_fname=input_fname,
mrk=mrk_fname,
elp=elp_fname,
hsp=hsp_fname,
stim=stim,
slope=slope,
stimthresh=stimthresh,
)
raw.save(out_fname)
raw.close()
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,97 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Create high-resolution head surfaces for coordinate alignment.
Examples
--------
.. code-block:: console
$ mne make_scalp_surfaces --overwrite --subject sample
"""
import os
import sys
import mne
from mne.bem import make_scalp_surfaces
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
subjects_dir = mne.get_config("SUBJECTS_DIR")
parser.add_option(
"-o",
"--overwrite",
dest="overwrite",
action="store_true",
help="Overwrite previously computed surface",
)
parser.add_option(
"-s", "--subject", dest="subject", help="The name of the subject", type="str"
)
parser.add_option(
"-m",
"--mri",
dest="mri",
type="str",
default="T1.mgz",
help="The MRI file to process using mkheadsurf.",
)
parser.add_option(
"-f",
"--force",
dest="force",
action="store_true",
help="Force creation of the surface even if it has "
"some topological defects.",
)
parser.add_option(
"-t",
"--threshold",
dest="threshold",
type="int",
default=20,
help="Threshold value to use with the MRI.",
)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
help="Subjects directory",
default=subjects_dir,
)
parser.add_option(
"-n",
"--no-decimate",
dest="no_decimate",
help="Disable medium and sparse decimations (dense only)",
action="store_true",
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
subject = vars(options).get("subject", os.getenv("SUBJECT"))
subjects_dir = options.subjects_dir
if subject is None or subjects_dir is None:
parser.print_help()
sys.exit(1)
make_scalp_surfaces(
subject=subject,
subjects_dir=subjects_dir,
force=options.force,
overwrite=options.overwrite,
no_decimate=options.no_decimate,
threshold=options.threshold,
mri=options.mri,
verbose=options.verbose,
)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,66 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Create a BEM solution using the linear collocation approach.
Examples
--------
.. code-block:: console
$ mne prepare_bem_model --bem sample-5120-5120-5120-bem.fif
"""
import os
import sys
import mne
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
parser.add_option(
"--bem",
dest="bem_fname",
help="The name of the file containing the "
"triangulations of the BEM surfaces and the "
"conductivities of the compartments. The standard "
"ending for this file is -bem.fif.",
metavar="FILE",
)
parser.add_option(
"--sol",
dest="bem_sol_fname",
help="The name of the resulting file containing BEM "
"solution (geometry matrix). It uses the linear "
"collocation approach. The file should end with "
"-bem-sof.fif.",
metavar="FILE",
default=None,
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
bem_fname = options.bem_fname
bem_sol_fname = options.bem_sol_fname
verbose = True if options.verbose is not None else False
if bem_fname is None:
parser.print_help()
sys.exit(1)
if bem_sol_fname is None:
base, _ = os.path.splitext(bem_fname)
bem_sol_fname = base + "-sol.fif"
bem_model = mne.read_bem_surfaces(bem_fname, patch_stats=False, verbose=verbose)
bem_solution = mne.make_bem_solution(bem_model, verbose=verbose)
mne.write_bem_solution(bem_sol_fname, bem_solution)
mne.utils.run_command_if_main()

200
mne/commands/mne_report.py Normal file
View File

@@ -0,0 +1,200 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
r"""Create mne report for a folder.
Examples
--------
Before getting started with ``mne report``, make sure the files you want to
render follow the filename conventions defined by MNE:
.. highlight:: console
.. cssclass:: table-bordered
.. rst-class:: midvalign
============ ==============================================================
Data object Filename convention (ends with)
============ ==============================================================
raw -raw.fif(.gz), -raw_sss.fif(.gz), -raw_tsss.fif(.gz),
_meg.fif(.gz), _eeg.fif(.gz), _ieeg.fif(.gz)
events -eve.fif(.gz)
epochs -epo.fif(.gz)
evoked -ave.fif(.gz)
covariance -cov.fif(.gz)
trans -trans.fif(.gz)
forward -fwd.fif(.gz)
inverse -inv.fif(.gz)
============ ==============================================================
To generate a barebones report from all the \*.fif files in the sample
dataset, invoke the following command in a system (e.g., Bash) shell::
$ mne report --path MNE-sample-data/ --verbose
On successful creation of the report, it will open the HTML in a new tab in
the browser. To disable this, use the ``--no-browser`` option.
TO generate a report for a single subject, give the ``SUBJECT`` name and
the ``SUBJECTS_DIR`` and this will generate the MRI slices (with BEM
contours overlaid on top if available)::
$ mne report --path MNE-sample-data/ --subject sample --subjects-dir \
MNE-sample-data/subjects --verbose
To properly render ``trans`` and ``covariance`` files, add the measurement
information::
$ mne report --path MNE-sample-data/ \
--info MNE-sample-data/MEG/sample/sample_audvis-ave.fif \
--subject sample --subjects-dir MNE-sample-data/subjects --verbose
To render whitened ``evoked`` files with baseline correction, add the noise
covariance file::
$ mne report --path MNE-sample-data/ \
--info MNE-sample-data/MEG/sample/sample_audvis-ave.fif \
--cov MNE-sample-data/MEG/sample/sample_audvis-cov.fif --bmax 0 \
--subject sample --subjects-dir MNE-sample-data/subjects --verbose
To generate the report in parallel::
$ mne report --path MNE-sample-data/ \
--info MNE-sample-data/MEG/sample/sample_audvis-ave.fif \
--subject sample --subjects-dir MNE-sample-data/subjects \
--verbose --jobs 6
For help on all the available options, do::
$ mne report --help
"""
import sys
import time
import mne
from mne.report import Report
from mne.utils import logger, verbose
@verbose
def log_elapsed(t, verbose=None):
"""Log elapsed time."""
logger.info(f"Report complete in {round(t, 1)} seconds")
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-p",
"--path",
dest="path",
help="Path to folder who MNE-Report must be created",
)
parser.add_option(
"-i",
"--info",
dest="info_fname",
help="File from which info dictionary is to be read",
metavar="FILE",
)
parser.add_option(
"-c",
"--cov",
dest="cov_fname",
help="File from which noise covariance is to be read",
metavar="FILE",
)
parser.add_option(
"--bmin",
dest="bmin",
help="Time at which baseline correction starts for evokeds",
default=None,
)
parser.add_option(
"--bmax",
dest="bmax",
help="Time at which baseline correction stops for evokeds",
default=None,
)
parser.add_option(
"-d", "--subjects-dir", dest="subjects_dir", help="The subjects directory"
)
parser.add_option("-s", "--subject", dest="subject", help="The subject name")
parser.add_option(
"--no-browser",
dest="no_browser",
action="store_false",
help="Do not open MNE-Report in browser",
)
parser.add_option(
"--overwrite",
dest="overwrite",
action="store_false",
help="Overwrite html report if it already exists",
)
parser.add_option(
"-j", "--jobs", dest="n_jobs", help="Number of jobs to run in parallel"
)
parser.add_option(
"-m",
"--mri-decim",
type="int",
dest="mri_decim",
default=2,
help="Integer factor used to decimate BEM plots",
)
parser.add_option(
"--image-format",
type="str",
dest="image_format",
default="png",
help="Image format to use (can be 'png' or 'svg')",
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
path = options.path
if path is None:
parser.print_help()
sys.exit(1)
info_fname = options.info_fname
cov_fname = options.cov_fname
subjects_dir = options.subjects_dir
subject = options.subject
image_format = options.image_format
mri_decim = int(options.mri_decim)
verbose = True if options.verbose is not None else False
open_browser = False if options.no_browser is not None else True
overwrite = True if options.overwrite is not None else False
n_jobs = int(options.n_jobs) if options.n_jobs is not None else 1
bmin = float(options.bmin) if options.bmin is not None else None
bmax = float(options.bmax) if options.bmax is not None else None
# XXX: this means (None, None) cannot be specified through command line
if bmin is None and bmax is None:
baseline = None
else:
baseline = (bmin, bmax)
t0 = time.time()
report = Report(
info_fname,
subjects_dir=subjects_dir,
subject=subject,
baseline=baseline,
cov_fname=cov_fname,
verbose=verbose,
image_format=image_format,
)
report.parse_folder(path, verbose=verbose, n_jobs=n_jobs, mri_decim=mri_decim)
log_elapsed(time.time() - t0, verbose=verbose)
report.save(open_browser=open_browser, overwrite=overwrite)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,150 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Create a BEM model for a subject.
Examples
--------
.. code-block:: console
$ mne setup_forward_model -s 'sample'
"""
import os
import sys
import mne
from mne.utils import get_subjects_dir, warn
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-s", "--subject", dest="subject", help="Subject name (required)", default=None
)
parser.add_option(
"--model",
dest="model",
help="Output file name. Use a name <dir>/<name>-bem.fif",
default=None,
type="string",
)
parser.add_option(
"--ico",
dest="ico",
help="The surface ico downsampling to use, e.g. "
" 5=20484, 4=5120, 3=1280. If None, no subsampling"
" is applied.",
default=None,
type="int",
)
parser.add_option(
"--brainc",
dest="brainc",
help="Defines the brain compartment conductivity. "
"The default value is 0.3 S/m.",
default=0.3,
type="float",
)
parser.add_option(
"--skullc",
dest="skullc",
help="Defines the skull compartment conductivity. "
"The default value is 0.006 S/m.",
default=None,
type="float",
)
parser.add_option(
"--scalpc",
dest="scalpc",
help="Defines the scalp compartment conductivity. "
"The default value is 0.3 S/m.",
default=None,
type="float",
)
parser.add_option(
"--homog",
dest="homog",
help="Use a single compartment model (brain only) "
"instead a three layer one (scalp, skull, and "
" brain). If this flag is specified, the options "
"--skullc and --scalpc are irrelevant.",
default=None,
action="store_true",
)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
help="Subjects directory",
default=None,
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
if options.subject is None:
parser.print_help()
sys.exit(1)
subject = options.subject
fname = options.model
subjects_dir = options.subjects_dir
ico = options.ico
brainc = options.brainc
skullc = options.skullc
scalpc = options.scalpc
homog = True if options.homog is not None else False
verbose = True if options.verbose is not None else False
# Parse conductivity option
if homog is True:
if skullc is not None:
warn(
"Trying to set the skull conductivity for a single layer "
"model. To use a 3 layer model, do not set the --homog flag."
)
if scalpc is not None:
warn(
"Trying to set the scalp conductivity for a single layer "
"model. To use a 3 layer model, do not set the --homog flag."
)
# Single layer
conductivity = [brainc]
else:
if skullc is None:
skullc = 0.006
if scalpc is None:
scalpc = 0.3
conductivity = [brainc, skullc, scalpc]
# Create source space
bem_model = mne.make_bem_model(
subject,
ico=ico,
conductivity=conductivity,
subjects_dir=subjects_dir,
verbose=verbose,
)
# Generate filename
if fname is None:
n_faces = list(str(len(surface["tris"])) for surface in bem_model)
fname = subject + "-" + "-".join(n_faces) + "-bem.fif"
else:
if not (fname.endswith("-bem.fif") or fname.endswith("_bem.fif")):
fname = fname + "-bem.fif"
# Save to subject's directory
subjects_dir = get_subjects_dir(subjects_dir, raise_error=True)
fname = subjects_dir / subject / "bem" / fname
# Save source space to file
mne.write_bem_surfaces(fname, bem_model)
# Compute the solution
sol_fname = os.path.splitext(str(fname))[0] + "-sol.fif"
bem_sol = mne.make_bem_solution(bem_model, verbose=verbose)
mne.write_bem_solution(sol_fname, bem_sol)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,183 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Set up bilateral hemisphere surface-based source space with subsampling.
Examples
--------
.. code-block:: console
$ mne setup_source_space --subject sample
.. note : Only one of --ico, --oct or --spacing options can be set at the same
time. Default to oct6.
"""
import sys
import mne
from mne.utils import _check_option
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-s", "--subject", dest="subject", help="Subject name (required)", default=None
)
parser.add_option(
"--src",
dest="fname",
help="Output file name. Use a name <dir>/<name>-src.fif",
metavar="FILE",
default=None,
)
parser.add_option(
"--morph",
dest="subject_to",
help="morph the source space to this subject",
default=None,
)
parser.add_option(
"--surf",
dest="surface",
help="The surface to use. (default to white)",
default="white",
type="string",
)
parser.add_option(
"--spacing",
dest="spacing",
help="Specifies the approximate grid spacing of the "
"source space in mm. (default to 7mm)",
default=None,
type="int",
)
parser.add_option(
"--ico",
dest="ico",
help="use the recursively subdivided icosahedron "
"to create the source space.",
default=None,
type="int",
)
parser.add_option(
"--oct",
dest="oct",
help="use the recursively subdivided octahedron to create the source space.",
default=None,
type="int",
)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
help="Subjects directory",
default=None,
)
parser.add_option(
"-n",
"--n-jobs",
dest="n_jobs",
help="The number of jobs to run in parallel "
"(default 1). Requires the joblib package. "
"Will use at most 2 jobs"
" (one for each hemisphere).",
default=1,
type="int",
)
parser.add_option(
"--add-dist",
dest="add_dist",
help='Add distances. Can be "True", "False", or "patch" '
"to only compute cortical patch statistics (like the --cps option in MNE-C)",
default="True",
)
parser.add_option(
"-o",
"--overwrite",
dest="overwrite",
help="to write over existing files",
default=None,
action="store_true",
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
if options.subject is None:
parser.print_help()
sys.exit(1)
subject = options.subject
subject_to = options.subject_to
fname = options.fname
subjects_dir = options.subjects_dir
spacing = options.spacing
ico = options.ico
oct_ = options.oct
surface = options.surface
n_jobs = options.n_jobs
add_dist = options.add_dist
_check_option("add_dist", add_dist, ("True", "False", "patch"))
add_dist = {"True": True, "False": False, "patch": "patch"}[add_dist]
verbose = True if options.verbose is not None else False
overwrite = True if options.overwrite is not None else False
# Parse source spacing option
spacing_options = [ico, oct_, spacing]
n_options = len([x for x in spacing_options if x is not None])
use_spacing = "oct6"
if n_options > 1:
raise ValueError("Only one spacing option can be set at the same time")
elif n_options == 0:
# Default to oct6
pass
elif n_options == 1:
if ico is not None:
use_spacing = "ico" + str(ico)
elif oct_ is not None:
use_spacing = "oct" + str(oct_)
elif spacing is not None:
use_spacing = spacing
del ico, oct_, spacing
# Generate filename
if fname is None:
if subject_to is None:
fname = subject + "-" + str(use_spacing) + "-src.fif"
else:
fname = subject_to + "-" + subject + "-" + str(use_spacing) + "-src.fif"
else:
if not (fname.endswith("_src.fif") or fname.endswith("-src.fif")):
fname = fname + "-src.fif"
# Create source space
src = mne.setup_source_space(
subject=subject,
spacing=use_spacing,
surface=surface,
subjects_dir=subjects_dir,
n_jobs=n_jobs,
add_dist=add_dist,
verbose=verbose,
)
# Morph source space if --morph is set
if subject_to is not None:
src = mne.morph_source_spaces(
src,
subject_to=subject_to,
subjects_dir=subjects_dir,
surf=surface,
verbose=verbose,
)
# Save source space to file
src.save(fname=fname, overwrite=overwrite)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,54 @@
"""Show the contents of a FIFF file.
Examples
--------
.. code-block:: console
$ mne show_fiff test_raw.fif
To see only tag 102:
.. code-block:: console
$ mne show_fiff test_raw.fif --tag=102
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def run():
"""Run command."""
parser = mne.commands.utils.get_optparser(__file__, usage="mne show_fiff <file>")
parser.add_option(
"-t",
"--tag",
dest="tag",
help="provide information about this tag",
metavar="TAG",
)
parser.add_option(
"-b",
"--bytes",
dest="show_bytes",
help="show the byte offset of each tag",
action="store_true",
)
options, args = parser.parse_args()
if len(args) != 1:
parser.print_help()
sys.exit(1)
msg = mne.io.show_fiff(
args[0], tag=options.tag, show_bytes=options.show_bytes
).strip()
print(msg)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,38 @@
"""Show measurement info from .fif file.
Examples
--------
.. code-block:: console
$ mne show_info sample_audvis_raw.fif
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def run():
"""Run command."""
parser = mne.commands.utils.get_optparser(__file__, usage="mne show_info <file>")
options, args = parser.parse_args()
if len(args) != 1:
parser.print_help()
sys.exit(1)
fname = args[0]
if not fname.endswith(".fif"):
raise ValueError(f"{fname} does not seem to be a .fif file.")
info = mne.io.read_info(fname)
print(f"File : {fname}")
print(info)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,53 @@
r"""Convert surface to BEM FIF file.
Examples
--------
.. code-block:: console
$ mne surf2bem --surf ${SUBJECTS_DIR}/${SUBJECT}/surf/lh.seghead \
--fif ${SUBJECTS_DIR}/${SUBJECT}/bem/${SUBJECT}-head.fif \
--id=4
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def run():
"""Run command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-s", "--surf", dest="surf", help="Surface in Freesurfer format", metavar="FILE"
)
parser.add_option(
"-f", "--fif", dest="fif", help="FIF file produced", metavar="FILE"
)
parser.add_option(
"-i",
"--id",
dest="id",
default=4,
help=("Surface Id (e.g. 4 for head surface)"),
)
options, args = parser.parse_args()
if options.surf is None:
parser.print_help()
sys.exit(1)
print(f"Converting {options.surf} to BEM FIF file.")
surf = mne.bem._surfaces_to_bem([options.surf], [int(options.id)], sigmas=[1])
mne.write_bem_surfaces(options.fif, surf)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,66 @@
"""Show system information.
Examples
--------
.. code-block:: console
$ mne sys_info
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import sys
import mne
def run():
"""Run command."""
parser = mne.commands.utils.get_optparser(__file__, usage="mne sys_info")
parser.add_option(
"-p",
"--show-paths",
dest="show_paths",
help="Show module paths",
action="store_true",
)
parser.add_option(
"-d",
"--developer",
dest="developer",
help="Show additional developer module information",
action="store_true",
)
parser.add_option(
"-a",
"--ascii",
dest="unicode",
help="Use ASCII instead of unicode symbols",
action="store_false",
default=True,
)
parser.add_option(
"--no-check-version",
dest="check_version",
help="Disable MNE-Python remote version checking.",
action="store_false",
default=True,
)
options, args = parser.parse_args()
dependencies = "developer" if options.developer else "user"
if len(args) != 0:
parser.print_help()
sys.exit(1)
mne.sys_info(
show_paths=options.show_paths,
dependencies=dependencies,
unicode=options.unicode,
check_version=options.check_version,
)
mne.utils.run_command_if_main()

View File

@@ -0,0 +1,134 @@
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
"""Create BEM surfaces using the watershed algorithm included with FreeSurfer.
Examples
--------
.. code-block:: console
$ mne watershed_bem -s sample
"""
import sys
import mne
from mne.bem import make_watershed_bem
from mne.utils import _check_option
def run():
"""Run command."""
from mne.commands.utils import _add_verbose_flag, get_optparser
parser = get_optparser(__file__)
parser.add_option(
"-s", "--subject", dest="subject", help="Subject name (required)", default=None
)
parser.add_option(
"-d",
"--subjects-dir",
dest="subjects_dir",
help="Subjects directory",
default=None,
)
parser.add_option(
"-o",
"--overwrite",
dest="overwrite",
help="Write over existing files",
action="store_true",
)
parser.add_option(
"-v", "--volume", dest="volume", help="Defaults to T1", default="T1"
)
parser.add_option(
"-a",
"--atlas",
dest="atlas",
help="Specify the --atlas option for mri_watershed",
default=False,
action="store_true",
)
parser.add_option(
"-g",
"--gcaatlas",
dest="gcaatlas",
help="Specify the --brain_atlas option for mri_watershed",
default=False,
action="store_true",
)
parser.add_option(
"-p",
"--preflood",
dest="preflood",
help="Change the preflood height",
default=None,
)
parser.add_option(
"--copy",
dest="copy",
help="Use copies instead of symlinks for surfaces",
action="store_true",
)
parser.add_option(
"-t",
"--T1",
dest="T1",
help="Whether or not to pass the -T1 flag "
"(can be true, false, 0, or 1). "
"By default it takes the same value as gcaatlas.",
default=None,
)
parser.add_option(
"-b",
"--brainmask",
dest="brainmask",
help="The filename for the brainmask output file "
"relative to the "
"$SUBJECTS_DIR/$SUBJECT/bem/watershed/ directory.",
default="ws",
)
_add_verbose_flag(parser)
options, args = parser.parse_args()
if options.subject is None:
parser.print_help()
sys.exit(1)
subject = options.subject
subjects_dir = options.subjects_dir
overwrite = options.overwrite
volume = options.volume
atlas = options.atlas
gcaatlas = options.gcaatlas
preflood = options.preflood
copy = options.copy
brainmask = options.brainmask
T1 = options.T1
if T1 is not None:
T1 = T1.lower()
_check_option("--T1", T1, ("true", "false", "0", "1"))
T1 = T1 in ("true", "1")
verbose = options.verbose
make_watershed_bem(
subject=subject,
subjects_dir=subjects_dir,
overwrite=overwrite,
volume=volume,
atlas=atlas,
gcaatlas=gcaatlas,
preflood=preflood,
copy=copy,
T1=T1,
brainmask=brainmask,
verbose=verbose,
)
mne.utils.run_command_if_main()

28
mne/commands/mne_what.py Normal file
View File

@@ -0,0 +1,28 @@
r"""Check type of FIF file.
Examples
--------
.. code-block:: console
$ mne what sample_audvis_raw.fif
raw
"""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import mne
def run():
"""Run command."""
from mne.commands.utils import get_optparser
parser = get_optparser(__file__, usage="usage: %prog fname [fname2 ...]")
options, args = parser.parse_args()
for arg in args:
print(mne.what(arg))
mne.utils.run_command_if_main()

109
mne/commands/utils.py Normal file
View File

@@ -0,0 +1,109 @@
"""Some utility functions for commands (e.g., for cmdline handling)."""
# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import glob
import importlib
import os
import os.path as op
import sys
from optparse import OptionParser
import mne
def _add_verbose_flag(parser):
parser.add_option(
"--verbose",
dest="verbose",
help="Enable verbose mode (printing of log messages).",
default=None,
action="store_true",
)
def load_module(name, path):
"""Load module from .py/.pyc file.
Parameters
----------
name : str
Name of the module.
path : str
Path to .py/.pyc file.
Returns
-------
mod : module
Imported module.
"""
from importlib.util import module_from_spec, spec_from_file_location
spec = spec_from_file_location(name, path)
mod = module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
def get_optparser(cmdpath, usage=None, prog_prefix="mne", version=None):
"""Create OptionParser with cmd specific settings (e.g., prog value)."""
# Fetch description
mod = load_module("__temp", cmdpath)
if mod.__doc__:
doc, description, epilog = mod.__doc__, None, None
doc_lines = doc.split("\n")
description = doc_lines[0]
if len(doc_lines) > 1:
epilog = "\n".join(doc_lines[1:])
# Get the name of the command
command = os.path.basename(cmdpath)
command, _ = os.path.splitext(command)
command = command[len(prog_prefix) + 1 :] # +1 is for `_` character
# Set prog
prog = prog_prefix + f" {command}"
# Set version
if version is None:
version = mne.__version__
# monkey patch OptionParser to not wrap epilog
OptionParser.format_epilog = lambda self, formatter: self.epilog
parser = OptionParser(
prog=prog, version=version, description=description, epilog=epilog, usage=usage
)
return parser
def main():
"""Entrypoint for mne <command> usage."""
mne_bin_dir = op.dirname(op.dirname(__file__))
valid_commands = sorted(glob.glob(op.join(mne_bin_dir, "commands", "mne_*.py")))
valid_commands = [c.split(op.sep)[-1][4:-3] for c in valid_commands]
def print_help(): # noqa
print("Usage : mne command options\n")
print("Accepted commands :\n")
for c in valid_commands:
print(f"\t- {c}")
print("\nExample : mne browse_raw --raw sample_audvis_raw.fif")
print("\nGetting help example : mne compute_proj_eog -h")
if len(sys.argv) == 1 or "help" in sys.argv[1] or "-h" in sys.argv[1]:
print_help()
elif sys.argv[1] == "--version":
print(f"MNE {mne.__version__}")
elif sys.argv[1] not in valid_commands:
print(f'Invalid command: "{sys.argv[1]}"\n')
print_help()
else:
cmd = sys.argv[1]
cmd = importlib.import_module(f".mne_{cmd}", "mne.commands")
sys.argv = sys.argv[1:]
cmd.run()