cuNIBS
cuNIBS computes the electric field that transcranial magnetic stimulation (TMS) induces in an individual head model. It solves the full-volume finite-element model on an NVIDIA GPU and reads head models built with the SimNIBS CHARM pipeline.
Many TMS analyses solve the same head model hundreds or thousands of times. cuNIBS builds the solver for a head once, keeps it on the GPU, and reuses it for every solve. Setup takes under a second, and each additional placement takes milliseconds. Use it to:
- simulate one coil placement or a sweep of placements,
- run the same analysis across a cohort of subjects,
- estimate how uncertain tissue conductivities affect the field,
- find the coil position and orientation that best stimulates a target.
The accompanying manuscript describes the numerical method and its validation against analytic solutions and SimNIBS.
Installation
python -m pip install cunibs
cuNIBS needs Python 3.12 or later, an NVIDIA GPU, and a driver that supports CUDA 13 (r580 or later). Wheels are available for x86-64 Linux and Windows, for CPython 3.12 through 3.14, including free-threaded Python 3.14. The package installs its own CUDA libraries, so a separate CUDA toolkit is not needed.
Quick start
from cunibs import Placement, Subject
from cunibs.coil import Coil, MAGSTIM_D70
subject = Subject.from_mesh("subject.msh")
coil = Coil.load(MAGSTIM_D70)
placement = Placement(
center_mm=[0.0, 20.0, 80.0],
handle_mm=[0.0, 70.0, 80.0],
distance_mm=4.0,
)
result = subject.simulate(coil, placement, didt=1.0e6)
print(result.peak_magnE())
print(result.peak_location_mm())
print(result.focality(0.5))
center_mm is the target on the scalp and handle_mm sets the direction of the
coil handle. cuNIBS projects the target onto the scalp and places the coil
distance_mm above it. didt is the rate of change of the coil current in A/s.
The field scales linearly with it.
Inputs
Head models
Build a head model from MRI with CHARM:
charm subject_id T1w.nii.gz T2w.nii.gz
This writes m2m_subject_id/subject_id.msh. A T1-weighted image is enough; a
T2-weighted image improves the skull segmentation. Check the segmentation before
you simulate.
cuNIBS assigns each tissue the standard SimNIBS conductivity. To check a mesh
before using it, call validate_mesh("subject.msh"). It returns a report instead
of raising, so you can screen a whole cohort up front.
A mesh can be saved as HDF5, which is smaller and loads faster than the .msh.
Pass the CHARM eeg_positions directory to keep the electrode positions in the
same file. load_mesh, Subject.from_mesh and validate_mesh read either format,
and read_cap reads the positions back.
from cunibs import Subject, load_mesh
from cunibs.head import read_cap
load_mesh("m2m_subject_id/subject_id.msh").save(
"subject_id.h5", eeg_positions="m2m_subject_id/eeg_positions"
)
subject = Subject.from_mesh("subject_id.h5")
c3 = read_cap("subject_id.h5")["C3"]
Coils
cuNIBS includes the 25 validated coil models from Drakaki et al. (2022). Load
one by constant or by name, and call bundled_coils() to list them. SimNIBS
.ccd files load directly.
coil = Coil.load("MagStim_D70")
coil = Coil.load("my_coil.ccd")
Placement sweeps and cohorts
Pass a list of placements to iter_simulate. It yields results in input order
and reuses the subject setup for all of them.
placements = [
Placement([0.0, 20.0, 80.0], [0.0, 70.0, 80.0]),
Placement([20.0, 0.0, 80.0], [70.0, 0.0, 80.0]),
]
for result in subject.iter_simulate(coil, placements, didt=1.0e6):
print(result.peak_magnE())
A Subject holds GPU memory until it is freed. Use it as a context manager when
you process many subjects:
from pathlib import Path
for mesh_file in Path("subjects").glob("m2m_*/*.msh"):
with Subject.from_mesh(mesh_file) as subject:
result = subject.simulate(coil, placement, didt=1.0e6)
Results
Each result carries summary metrics for gray matter: peak field and its location, focality, centre of gravity, and distribution statistics. Results stay small because full-volume arrays are kept only when you ask for them:
result = subject.simulate(
coil, placement, didt=1.0e6, magnitude=True, vectors=True, potential=True
)
result.magnE # |E| per tetrahedron, V/m
result.E # E per tetrahedron, V/m
result.v # potential per node, V
Save and load results as HDF5 with result.save(path) and
FieldResult.load(path). Saved files record the software versions, GPU, mesh,
and coil used.
The recovery argument selects how the reported field is computed from the
finite-element solution. The default, "harmonic", is accurate at tissue
interfaces. Use "spr_tissue" or "spr_global" to compare with SimNIBS
outputs, or "raw" for the unprocessed field.
Conductivity uncertainty
simulate_conductivity_uq samples tissue conductivities and reports the mean
field and its variability.
from cunibs import ConductivityUQConfig
config = ConductivityUQConfig(
n_samples=500,
tissue_cov={"gray_matter": 0.15, "csf": 0.05, "cortical_bone": 0.35},
seed=1,
)
uq = subject.simulate_conductivity_uq(coil, placement, config, didt=1.0e6)
print(uq.peak_mean_magnE())
print(uq.max_local_cov())
print(uq.peak_samples)
tissue_cov sets the coefficient of variation for each tissue. Only the tissues
it names are varied. Samples are lognormal by default.
Coil-placement optimization
cunibs.adm searches candidate coil positions and orientations for the one that
maximizes the field at a target. It uses the auxiliary dipole method (Gomez et
al., 2021), so it does not need a separate solve for each candidate.
from cunibs import Target, adm, head
target = Target(position_mm=[-45.0, -5.0, 25.0], region="gray_matter")
centers = head.scalp_grid(subject, [-50.0, -10.0, 80.0], radius_mm=20.0, spacing_mm=2.0)
search = adm.optimize(subject, coil, target, centers)
result = subject.simulate(coil, search.best_placement)
Give Target a direction to maximize the field along that direction instead
of its magnitude.
cunibs.head also measures scalp-to-cortex distance and tissue thickness, and
reads the electrode positions and fiducials that CHARM writes.
Reproducibility
A result depends only on the mesh, coil, placement, didt, solver tolerance,
and recovery method. It does not depend on the other placements in a sweep or
their order. The same calculation on the same hardware and software gives
bitwise-identical results. Results can differ across GPU models and software
versions.
Citation
No archival citation is available yet. Cite the software name, author, version, and Git commit, and archive the mesh, coil, placements, and settings with your study data.
License
cuNIBS is released under the GNU General Public License v3.0.
References
- Drakaki, M., Mathiesen, C., Siebner, H. R., Madsen, K., and Thielscher, A. (2022). Database of 25 validated coil models for electric field simulations for TMS. Brain Stimulation, 15(3), 697-706.
- Gomez, L. J., Dannhauer, M., and Peterchev, A. V. (2021). Fast computational optimization of TMS coil placement for individualized electric field targeting. NeuroImage, 228, 117696.
- Puonti, O., Van Leemput, K., Saturnino, G. B., Siebner, H. R., Madsen, K. H., and Thielscher, A. (2020). Accurate and robust whole-head segmentation from magnetic resonance images for individualized head modeling. NeuroImage, 219, 117044.
- Saturnino, G. B., Puonti, O., Nielsen, J. D., Antonenko, D., Madsen, K. H., and Thielscher, A. (2019). SimNIBS 2.1: A comprehensive pipeline for individualized electric field modelling for transcranial brain stimulation.
Metadata
Release files for cunibs 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cunibs-0.5.0.tar.gz | 1.5 MB | With provenance | Details for cunibs-0.5.0.tar.gz |
Built distributions (wheels)
Total release size: 47.5 MB
Release files / cunibs-0.5.0.tar.gz
| Download URL | cunibs-0.5.0.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
50abe15fc8d51a0e561ae3dcd56e43b122c9a72a0b390b18a0df9203812f2a91
|
|
BLAKE2b-256 checksum How to use checksums |
7eeda9c2143fd60b4bad7b1d80356ae29b35e852b6aac29e02ffd0608f24245b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp314-cp314t-win_amd64.whl
| Download URL | cunibs-0.5.0-cp314-cp314t-win_amd64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Windows x86-64 |
|
SHA-256 checksum How to use checksums |
da222b3170dcf997281fc45d17311a04aaee6318155206cf4f197d651ceaa3a3
|
|
BLAKE2b-256 checksum How to use checksums |
b562707993ad0f4259299adf54191128fed106ef002e472c447b0a986e3066f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | cunibs-0.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | CPython 3.14 CPython 3.14 free-threading Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
1036220efe9a4770ba506ecb220d29456d92ca8f575f2d528986f3f7d2f43526
|
|
BLAKE2b-256 checksum How to use checksums |
55a242893203a3d3c50ab50bb4cdedc8e6e7a35f0ed33071a597431b40183b26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp314-cp314-win_amd64.whl
| Download URL | cunibs-0.5.0-cp314-cp314-win_amd64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.14 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
e0a8e4572960b06bf3a901b305c18a90db505611399981a09be88c34f91f6685
|
|
BLAKE2b-256 checksum How to use checksums |
3f967e441884fa42a1d45a5d66a745be8c580359cf6a1f5e3673fc8e28eab03e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | cunibs-0.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
d0fdfc1d56c55ed4530b6f3fdf71a06b190ceba4cee30cf157220c7fc5854861
|
|
BLAKE2b-256 checksum How to use checksums |
96b5116cd3dd1a4c81675f9fa390780048c7001461be44cfeb3d6ff8addee287
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp313-cp313-win_amd64.whl
| Download URL | cunibs-0.5.0-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
823f012780f80a2dd97a6ae55af4d24851b46808ec403d6f5d9cacfcfd80d611
|
|
BLAKE2b-256 checksum How to use checksums |
1d21aa43b6933a79cc77267b065e8997148edae6dbd75551371be7190fb2d236
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | cunibs-0.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
4c7e58536f35251f2c0d8b58a7ce1f5b74930d1126529a5f4e8e031863219ed9
|
|
BLAKE2b-256 checksum How to use checksums |
e5c3c6d965a2f61ed2614bc64205245caadb75d2d977718dfe2cce336f5b1fb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp312-cp312-win_amd64.whl
| Download URL | cunibs-0.5.0-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
ef6448f2f8d8ded1172663978d3af2fb31e01ead1ac44e93279a64d24d74e31b
|
|
BLAKE2b-256 checksum How to use checksums |
28432ebc15c81eaca7c6480d0fa1b4828149306e308b91f00bbf270a90c556fb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logRelease files / cunibs-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | cunibs-0.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 5.7 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
4981c03e0dbfa98291fe2b8b7b1fe3a635e6be087e42695fc2ad11e65846c1c8
|
|
BLAKE2b-256 checksum How to use checksums |
50ce1f8d81386a9068361b12bbfccccaef0f54ae4cfd8b0a03d2144ac2f10643
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logSecurity for cunibs 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 9 files in this release have been uploaded with provenance metadata.
Attestation for cunibs-0.5.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.