sim
tit.sim ¶
TI/mTI simulation engine.
This package implements temporal interference (TI) and multi-channel temporal interference (mTI) brain stimulation simulations. It wraps the SimNIBS finite-element solver, providing electrode configuration, field computation, and BIDS-compliant output organization.
Public API¶
BaseSimulation
Abstract base class for TI/mTI simulation pipelines.
SimulationConfig
Dataclass holding all parameters for a simulation run.
Montage
Dataclass describing a named electrode montage.
MontageMode
Enum saying how a montage's electrodes are specified (net labels or
XYZ coordinates); also reachable as Montage.Mode.
SimulationMode
Enum distinguishing TI (2-pair) from mTI (4+-pair) mode.
parse_intensities
Parse a comma-separated intensity string into a float list.
run_simulation
Execute simulations for every montage in a configuration.
load_montages
Load the named montages (only those, in that order) from the
project's montage_list.json.
list_montage_names
List the montage names available under an EEG net -- call this
first to see what load_montages can return.
load_montage_data
Load the full montage_list.json as a dict.
save_montage_data
Write a montage dict to montage_list.json.
ensure_montage_file
Return (and optionally create) the path to montage_list.json.
upsert_montage
Insert or update a montage definition in montage_list.json.
See Also¶
tit.sim.config : Configuration dataclasses and enums. tit.sim.utils : Orchestration, montage I/O, and post-processing helpers. tit.sim.TI : 2-pair TI simulation implementation. tit.sim.mTI : N-pair mTI simulation implementation. tit.opt : Optimization modules that consume simulation results. tit.analyzer : Field analysis applied to simulation outputs.
Examples¶
from tit.sim import SimulationConfig, run_simulation, load_montages, list_montage_names list_montage_names("GSN-HydroCel-185.csv", mode="U") # doctest: +SKIP ['L_Insula', 'R_Insula'] montages = load_montages(["L_Insula"], eeg_net="GSN-HydroCel-185.csv") # doctest: +SKIP cfg = SimulationConfig(subject_id="ernie", montages=montages) # doctest: +SKIP run_simulation(cfg) # doctest: +SKIP
SimulationConfig
dataclass
¶
SimulationConfig(subject_id: str, montages: list[Montage], conductivity: str = 'scalar', intensities: list[float] = (lambda: [1.0, 1.0])(), electrode_shape: str = 'ellipse', electrode_dimensions: list[float] = (lambda: [8.0, 8.0])(), gel_thickness: float = 1.0, rubber_thickness: float = 2.0, map_to_vol: bool = False, map_to_mni: bool = False, map_to_fsavg: bool = True, aniso_maxratio: float = 10.0, aniso_maxcond: float = 2.0, output_fields: list[str] | None = None, tissue_conductivities: dict[int, float] | None = None, carrier_only: bool = False)
Full configuration for a TI or mTI simulation run.
Passed to :func:tit.sim.run_simulation to execute one or more
montage simulations for a single subject. Electrode geometry,
conductivity model, and output mapping options are all set here.
Attributes¶
subject_id : str
Subject identifier without the sub- prefix (e.g. "ernie",
"101"); must match an existing m2m_<subject_id> directory.
montages : list[Montage]
One or more :class:Montage definitions to simulate. Two channels
(electrode pairs) is TI, four or more (even) is mTI -- detected
per montage, so a list may mix both.
conductivity : str
Tissue conductivity model. One of:
- ``"scalar"`` -- isotropic scalar conductivities (default).
- ``"vn"`` -- volume-normalized anisotropic conductivities.
- ``"dir"`` -- directly-mapped anisotropic conductivities.
- ``"mc"`` -- mean-conductivity anisotropic conductivities.
The anisotropic modes (``"vn"``, ``"dir"``, ``"mc"``) require
DTI tensors registered to the head mesh.
intensities : list[float]
Current per channel in mA, in electrode_pairs order (one value
per channel). A TI montage reads the first two values; an mTI montage
needs one value per channel (len(intensities) >= num_pairs). A
single value is not broadcast -- a 4-channel montage with the default
two values is rejected. Default [1.0, 1.0].
electrode_shape : str
Electrode shape, "ellipse" or "rect". Default
"ellipse".
electrode_dimensions : list[float]
[width, height] of each electrode in mm. Default
[8.0, 8.0].
gel_thickness : float
Conductive-gel (saline) layer thickness in mm, between the skin and
the rubber. Default 1.0.
rubber_thickness : float
Rubber (silicone) layer thickness in mm. Default 2.0.
map_to_vol : bool
Write NIfTI volumes of the field meshes (SimNIBS's own meaning of the
name; tit.tools.mesh2nii does the conversion after the run): one
3-D <mesh>_subject_<field>.nii.gz per field of each field mesh --
the brain-tissue mesh and its grey- and white-matter copies -- so the
NIfTI set is the mesh field set, name for name, plus each channel's
magnE. Default False: the field meshes are the output, and a
step that needs a NIfTI (a voxel analysis, the group tools) writes the
one it reads on demand (:mod:tit.volume_fields).
map_to_mni : bool
Also write each field NIfTI in MNI space (<mesh>_MNI_MNI_<field>.nii.gz)
and the T1 in MNI space. MNI output is itself a NIfTI, so True turns
map_to_vol on as well (subject and MNI NIfTIs). Default False.
map_to_fsavg : bool
After each TI montage finishes, project its surface fields
(TI_max, TI_normal, hf_peak, hf_rms) onto fsaverage5
for group surface analysis. Default True; set False to
skip. Failures are logged and never abort the simulation.
aniso_maxratio : float
Maximum eigenvalue ratio clamp for anisotropic conductivity
tensors. Default 10.0.
aniso_maxcond : float
Maximum absolute conductivity clamp (S/m) for anisotropic
tensors. Default 2.0.
output_fields : list[str]
Which volume-mesh fields to compute and write. Logical names from
:data:tit.constants.SELECTABLE_OUTPUT_FIELDS: "TI_max",
"TI_avg", "hf_peak", "hf_rms", "hf_power_density".
"TI_max" maps to mTI_max on disk for mTI meshes. None
(the default) is :data:tit.constants.DEFAULT_OUTPUT_FIELDS --
["TI_max", "hf_peak", "hf_rms"], the envelope and the carrier
fields an analysis's carrier metrics read -- or, for a carrier_only
run, which has no envelope, ["hf_peak", "hf_rms"]. TI_avg and
hf_power_density are opt-in; a field not saved here is computed
later, from the kept channel meshes, by the step that needs it
(hf_power_density excepted: its conductivity is not kept).
hf_power_density (W/m^3) uses the conductivity of this run's own
solve, the full tensor under the anisotropic models.
tissue_conductivities : dict[int, float] or None
Per-tissue conductivity overrides (S/m), keyed by SimNIBS tissue
number (1-based, matching tdcs.cond index + 1). None (the
default) uses SimNIBS's own tissue defaults for every tissue.
JSON object keys are always strings, so this round-trips as
{"<tissue number>": <S/m>} on disk; :func:tit.config_io.deserialize_config
coerces the keys back to int, and this dataclass's own
__post_init__ does the same for an instance built directly
with string keys. Applied to every channel's TDCS list by
tit.sim.base.BaseSimulation._apply_tissue_conductivities and
recorded in the run's config.json.
carrier_only : bool
Carrier-only control: both channels run at the same frequency, in
phase (ΔF = 0), so there is no beat. The carrier fields hf_peak,
hf_rms and hf_power_density then add the two channel fields
coherently (|E1+E2|, see :func:tit.calc.hf_peak) and no envelope
field (TI_max, TI_avg, TI_normal) is computed. Requires a
two-channel TI montage; an explicit output_fields must be drawn
from those carrier fields (the default already is). Default False.
Raises¶
ValueError
If conductivity is not one of the valid model names, if
output_fields contains an unknown name or is empty, if any
montage has a channel that is not exactly two electrodes, if
intensities is shorter than a montage needs (2 for TI, one per
channel for mTI), if tissue_conductivities contains a tissue
number outside 1..1000 or a non-positive value, if electrode_shape is not
"ellipse" or "rect" or any electrode dimension, gel_thickness
or rubber_thickness is not a finite number above 0, if carrier_only is set with an envelope
output field or a montage that is not two-channel TI. Filesystem checks (the m2m directory, the
EEG-net CSV) happen later, in :func:run_simulation.
Examples¶
from tit.sim import SimulationConfig, Montage, MontageMode montage = Montage( ... name="L_Insula", mode=MontageMode.NET, ... electrode_pairs=[("E010", "E011"), ("E012", "E013")], ... eeg_net="GSN-HydroCel-185.csv", ... ) cfg = SimulationConfig( ... subject_id="ernie", ... montages=[montage], ... conductivity="scalar", ... intensities=[1.0, 1.0], ... electrode_shape="ellipse", ... electrode_dimensions=[8.0, 8.0], ... output_fields=["TI_max", "hf_peak"], ... ) cfg.output_fields ['TI_max', 'hf_peak']
A carrier-only control of the same montage (both channels at one frequency, in phase; no envelope, so only carrier fields):
sham = SimulationConfig( ... subject_id="ernie", montages=[montage], intensities=[1.0, 1.0], ... carrier_only=True, ... ) sham.output_fields ['hf_peak', 'hf_rms']
Then run_simulation(cfg) (needs SimNIBS and the subject's m2m
directory).
See Also¶
Montage : Electrode montage contained in montages.
run_simulation : Entry point that consumes this config.
parse_intensities : Helper to build the intensities list.
Montage
dataclass
¶
Montage(name: str, mode: MontageMode, electrode_pairs: list[tuple[str | list[float], str | list[float]]], eeg_net: str | None = None, display_name: str | None = None, electrode_poses: list[list[list[float]]] | None = None, provenance: dict[str, str] | None = None)
A named electrode montage used in a TI/mTI simulation.
Wraps the channel definitions of a single montage: one electrode pair
per channel, channel k being electrodes Ek+ and Ek-. Electrodes
may be referenced by EEG-cap label names (NET / FLEX_MAPPED
modes) or by 3-D XYZ coordinates (FLEX_FREE / FREEHAND modes).
The simulation type is auto-detected from the number of channels: 2 channels = standard TI, 4 or more (even) = multi-channel mTI.
Attributes¶
name : str
Human-readable montage name (e.g. "M1_left").
mode : MontageMode
How electrode positions are specified. See :class:MontageMode.
electrode_pairs : list[tuple]
One entry per channel, in channel order. Each element is a tuple of
two electrode identifiers (label strings or XYZ coordinate lists),
(Ek+, Ek-).
eeg_net : str or None
Filename of the EEG-net CSV (e.g. "GSN-HydroCel-185.csv").
Required for NET and FLEX_MAPPED modes, ignored otherwise.
display_name : str or None
Optional user-facing label. name remains the storage and lookup key.
electrode_poses : list[list[list[float]]] or None
Optional full 4x4 homogeneous pose (row-major) per electrode, one
per XYZ position in electrode_pairs order. Only meaningful for
XYZ modes; preserves rectangular-electrode orientation when a
flex-search candidate is replayed. None (default) lets SimNIBS
orient the electrodes itself.
provenance : dict[str, str] or None
Free-form origin metadata (e.g. {"head_mesh_sha256": ...})
checked by :func:run_simulation when present.
Raises¶
ValueError
If electrode_poses is given for a label-based montage, does not
contain exactly one 4x4 right-handed homogeneous transform per
electrode, or its translations do not match electrode_pairs.
Examples¶
from tit.sim import Montage, MontageMode m = Montage( ... name="L_Insula", ... mode=MontageMode.NET, ... electrode_pairs=[("E010", "E011"), ("E012", "E013")], ... eeg_net="GSN-HydroCel-185.csv", ... ) m.num_pairs, m.simulation_mode.value, m.is_xyz (2, 'TI', False)
A free-hand montage uses subject-space millimetre coordinates and no net:
free = Montage( ... name="custom", ... mode=MontageMode.FREEHAND, ... electrode_pairs=[([-60.0, 10.0, 40.0], [60.0, 10.0, 40.0]), ... ([-60.0, -40.0, 40.0], [60.0, -40.0, 40.0])], ... ) free.is_xyz True
See Also¶
SimulationConfig : Holds one or more Montage instances.
load_montages : Build Montage objects from montage_list.json.
is_xyz
property
¶
is_xyz: bool
Whether electrodes are specified as 3-D XYZ coordinates.
Returns¶
bool
True for FLEX_FREE and FREEHAND modes.
simulation_mode
property
¶
simulation_mode: SimulationMode
Infer TI vs mTI from the number of channels (electrode pairs).
Returns¶
SimulationMode
SimulationMode.TI for 2 channels, SimulationMode.MTI
for 4 or more (even).
Raises¶
ValueError
If the channel count is not allowed by
:func:tit.constants.is_valid_pair_count -- an even count of at
least 2. One channel is tACS, not TI; an odd count leaves a channel
with nothing to beat against.
See Also¶
SimulationMode : The returned enum type.
MontageMode ¶
Bases: Enum
How electrode positions are specified.
NET and FLEX_MAPPED use EEG-cap label names resolved against an
EEG-net CSV. FLEX_FREE and FREEHAND use raw 3-D XYZ
coordinates (no net required).
Attributes¶
NET : str Standard EEG-cap electrode labels. FLEX_MAPPED : str Flex-search result mapped back to EEG-cap labels. FLEX_FREE : str Flex-search result with free XYZ coordinates. FREEHAND : str User-specified XYZ coordinates (manual placement).
SimulationMode ¶
BaseSimulation ¶
BaseSimulation(config: SimulationConfig, montage: Montage, logger)
Bases: ABC
Abstract base class for TI/mTI simulations.
Provides the template-method run pipeline that subclasses
customise by implementing _build_session and _post_process.
Parameters¶
config : SimulationConfig Fully specified simulation configuration. montage : Montage The electrode montage to simulate. logger : logging.Logger Logger instance for status and diagnostic messages.
Attributes¶
config : SimulationConfig
Simulation configuration supplied at construction.
montage : Montage
Electrode montage supplied at construction.
logger : logging.Logger
Logger instance used throughout the pipeline.
pm : tit.paths.PathManager
Singleton path manager for BIDS path resolution.
m2m_dir : str
Absolute path to the subject's m2m_<subject> directory.
See Also¶
TISimulation : Concrete two-channel TI subclass.
mTISimulation : Concrete N-channel mTI subclass.
run_simulation : Orchestrates BaseSimulation.run across montages.
Source code in tit/sim/base.py
run ¶
Execute the full simulation pipeline for one montage.
This template method orchestrates directory setup, montage visualisation, SimNIBS FEM execution, and subclass-specific post-processing.
Parameters¶
simulation_dir : str
Root simulations directory for the subject.
overwrite : bool
Replace an earlier result of this montage. The earlier run's
derived outputs are removed first (see
:func:tit.sim.utils.clear_previous_outputs), so the folder holds
exactly what the new config.json says.
Returns¶
dict
Result dictionary with keys montage_name, montage_type,
status, and output_mesh.
Raises¶
FileExistsError
If overwrite is False and the montage folder already holds a
result mesh. Nothing is written, config.json included.
See Also¶
run_simulation : Calls run for each montage in a config.
Source code in tit/sim/base.py
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
parse_intensities ¶
Parse a comma-separated intensity string into a list of floats.
Intensities are one current per channel (electrode pair). A single
value is used for both channels of a TI montage ("2.0" becomes
[2.0, 2.0]). Otherwise the value count must be even: two channels
for TI, four or more for mTI.
Parameters¶
s : str
Comma-separated intensity values (e.g. "1.0,2.0").
Returns¶
list[float] List of floats with an even number of elements.
Raises¶
ValueError If the number of values is odd and greater than 1.
See Also¶
SimulationConfig.intensities : Field populated by this function.
Source code in tit/sim/config.py
run_simulation ¶
run_simulation(config: SimulationConfig, logger: Logger | None = None, progress_callback: Callable[[int, int, str], None] | None = None, *, overwrite: bool = False) -> list[dict]
Run TI or mTI simulations for every montage in config.
For each montage in config.montages, this function:
- Auto-detects TI (2 pairs) vs mTI (4+ pairs) from the montage.
- Builds a SimNIBS SESSION with electrode geometry and conductivity settings from config.
- Runs the FEM solver to compute electric-field distributions.
- Computes temporal-interference envelope fields:
TI_max/TI_avgplusTI_normal(2-pair TI only), or the multi-channel superposition for mTI. - Writes the field mesh, its central surface and (opt-in) NIfTIs to the BIDS-compliant simulation directory.
Montages are processed sequentially. If no logger is provided, a file logger is created under the subject's log directory.
Parameters¶
config : SimulationConfig
Full simulation configuration including subject ID, montage
list, electrode geometry, and conductivity model.
logger : logging.Logger or None, optional
Logger instance. If None, a file logger is created
automatically in the subject's BIDS logs directory.
progress_callback : callable or None, optional
Optional callback invoked before each montage as
callback(current_index, total, montage_name) and once more
with (total, total, "Complete") when finished.
bool, optional
Replace an earlier result of a montage. Defaults to False; existing-result
protection stays enabled unless confirmed. When set, the earlier run's
derived outputs (TI/, mTI/, fsaverage/, high_Frequency/) are
removed before solving, keeping documentation/ and Analyses/, so the
folder holds exactly what the new config.json says.
Returns¶
list[dict]
One result dict per montage with keys montage_name,
montage_type, status, and output_mesh.
Raises¶
ValueError
If config.montages is empty, the subject's m2m_<id>
directory does not exist, a montage has an invalid pair count
(must be an even number >= 2), too few intensities are given
for a montage, a label-based montage has no eeg_net or its
EEG-net CSV is missing from the subject's eeg_positions
folder, or an XYZ montage holds a malformed coordinate.
OSError
FileExistsError when a montage folder already holds a result mesh
(TI/mesh or mTI/mesh) and overwrite is False; every
montage is checked before the first is solved, so nothing is
written. SimNIBS raises its own OSError when an interrupted run
left a session record in high_Frequency/.
Examples¶
from tit.sim import SimulationConfig, load_montages, run_simulation montages = load_montages(["L_Insula"], eeg_net="GSN-HydroCel-185.csv") # doctest: +SKIP cfg = SimulationConfig(subject_id="ernie", montages=montages, ... intensities=[1.0, 1.0], output_fields=["TI_max"]) # doctest: +SKIP results = run_simulation(cfg) # doctest: +SKIP results[0]["status"], results[0]["output_mesh"] # doctest: +SKIP ('completed', '.../Simulations/L_Insula/TI/mesh/ernie_L_Insula_TI.msh')
See Also¶
SimulationConfig : The configuration consumed by this function. BaseSimulation.run : Per-montage pipeline called internally. TISimulation : Concrete class for 2-pair simulations. mTISimulation : Concrete class for N-pair simulations.
Source code in tit/sim/utils.py
816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 | |
load_montages ¶
Load the named montages from the project's montage_list.json.
Only the montages named in montage_names are returned, in that
order -- this is not a listing of every montage under the net.
load_montages(["L_Insula"], ...) returns a one-element list, so
indexing [1] raises IndexError. Use
:func:list_montage_names to see which names exist. A name that is
not defined under eeg_net is silently skipped (no error), so the
result can be shorter than montage_names; check len() or the
returned .name values before relying on positions. A name saved
under both the uni- and the multi-polar section raises ValueError.
Reads the montage_list.json file (managed by
:func:ensure_montage_file), looks up each name under the given
EEG net's uni- and multi-polar sections, and returns them as
:class:Montage instances.
The eeg_net value determines the montage mode:
"freehand"setsMontage.Mode.FREEHAND"flex_mode"setsMontage.Mode.FLEX_FREE- Any other value (e.g.
"GSN-HydroCel-185.csv") setsMontage.Mode.NET
Parameters¶
montage_names : list[str]
Names to look up in the montage file, e.g. ["L_Insula"].
Order is preserved in the result.
eeg_net : str
EEG-net CSV filename (e.g. "GSN-HydroCel-185.csv",
"EEG10-10_UI_Jurak_2007.csv") that selects the sub-dict
inside montage_list.json["nets"]; it is also stored on each
returned :class:Montage as eeg_net.
include_flex : bool, optional
Ignored. It once appended flex montages named by an environment
variable that nothing sets any more; it is still accepted so
scripts and notebooks that pass it keep running.
Returns¶
list[Montage]
One :class:Montage per found name, in montage_names order,
ready to pass as SimulationConfig(montages=...).
Examples¶
from tit.sim import list_montage_names, load_montages list_montage_names("GSN-HydroCel-185.csv", mode="U") # doctest: +SKIP ['L_Insula', 'R_Insula'] montages = load_montages(["L_Insula"], eeg_net="GSN-HydroCel-185.csv") # doctest: +SKIP len(montages), montages[0].name # doctest: +SKIP (1, 'L_Insula') both = load_montages(["L_Insula", "R_Insula"], eeg_net="GSN-HydroCel-185.csv") # doctest: +SKIP [m.name for m in both] # doctest: +SKIP ['L_Insula', 'R_Insula']
See Also¶
list_montage_names : Discover available names before loading. upsert_montage : Add montages that can then be loaded. Montage : The returned dataclass type.
Source code in tit/sim/utils.py
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | |
list_montage_names ¶
List all montage names defined under an EEG net.
These are exactly the names :func:load_montages can resolve for
that net; a name not in this list is silently skipped by
:func:load_montages.
Parameters¶
eeg_net : str
EEG-net CSV filename (e.g. "GSN-HydroCel-185.csv",
"EEG10-10_UI_Jurak_2007.csv"), the key under
montage_list.json["nets"].
mode : str
"U" for uni-polar (2-pair TI) montage names or "M" for
multi-polar (4+-pair mTI) montage names. Case-insensitive.
Returns¶
list[str] Sorted montage names. Returns an empty list if the net or mode key does not exist (never raises for an unknown net).
Examples¶
from tit.sim import list_montage_names list_montage_names("GSN-HydroCel-185.csv", mode="U") # doctest: +SKIP ['L_Insula', 'R_Insula'] list_montage_names("GSN-HydroCel-185.csv", mode="M") # doctest: +SKIP []
See Also¶
upsert_montage : Add montage names to the list.
load_montages : Load the named montages as Montage objects.
Source code in tit/sim/utils.py
load_montage_data ¶
load_montage_data(*, pm: PathManager | None = None) -> dict
Load the full montage_list.json as a dict.
Returns¶
dict
Parsed JSON with top-level key "nets" mapping EEG net
names to their uni/multi polar montage definitions.
See Also¶
save_montage_data : Write the dict back to disk. ensure_montage_file : Guarantees the file exists before reading.
Source code in tit/sim/utils.py
save_montage_data ¶
save_montage_data(data: dict, *, pm: PathManager | None = None) -> None
Write data to montage_list.json, overwriting the file.
Parameters¶
data : dict
Full montage dict (must contain a "nets" key).
See Also¶
load_montage_data : Read the data back after saving.
Source code in tit/sim/utils.py
ensure_montage_file ¶
ensure_montage_file(*, pm: PathManager | None = None) -> str
Return the path to montage_list.json, creating it if absent.
If the file does not exist, creates it with the default schema
{"nets": {}}.
Returns¶
str
Absolute path to the montage_list.json file.
See Also¶
load_montage_data : Read the file returned by this function. save_montage_data : Write data to the file returned by this function.
Source code in tit/sim/utils.py
upsert_montage ¶
upsert_montage(*, eeg_net: str, montage_name: str, electrode_pairs: list[list[str]], mode: str, pm: PathManager | None = None) -> None
Insert or update a montage definition in montage_list.json.
Creates the EEG net entry if it does not already exist.
Parameters¶
eeg_net : str
EEG-net CSV filename exactly as it appears in the subject's
eeg_positions folder, e.g. "GSN-HydroCel-185.csv" or
"EEG10-10_UI_Jurak_2007.csv". Created in the file if absent.
montage_name : str
Montage name; an existing montage of the same name under this net is
replaced, whichever polarity it was saved under (one name, one
Simulations/<name>/ folder).
electrode_pairs : list[list[str]]
Electrode pairs, each a two-element list of labels from that net
(e.g. [["E010", "E011"], ["E012", "E013"]]). Two pairs for
mode="U", four (or more, even) for mode="M".
mode : str
"U" for uni-polar montages (2-pair TI) or "M" for
multi-polar montages (4+-pair mTI). Case-insensitive; anything
other than "U" is treated as "M".
pm : PathManager or None, optional
Path manager to locate the project; None uses the global one.
Returns¶
None The file is rewritten in place.
Examples¶
from tit.sim import upsert_montage, list_montage_names upsert_montage( ... eeg_net="GSN-HydroCel-185.csv", ... montage_name="L_Insula", ... electrode_pairs=[["E010", "E011"], ["E012", "E013"]], ... mode="U", ... ) # doctest: +SKIP list_montage_names("GSN-HydroCel-185.csv", mode="U") # doctest: +SKIP ['L_Insula']
See Also¶
list_montage_names : List montage names after upserting.
load_montages : Load upserted montages as Montage objects.