Skip to content

Add coordinate converters between MNI152 and FSAverage #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ Change tags (adopted from `sklearn <https://scikit-learn.org/stable/whats_new/v0

- |API| : you will need to change your code to have the same effect in the future; or a feature will be removed in the future.

Version 2.5.0
-------------
- |Feature| : Add functions to convert electrode coordinates between MNI152 and fsaverage space, with ``localization.mni152_to_fsaverage`` and ``localization.fsaverage_to_mni152``.

Version 2.4.0
-------------
- |Enhancement| : Adds the ability to set vmin and vmax to ``plot_brain_overlay``.

Version 2.3.0
-------------
- |MajorFeature| : Adds the ability to interpolate electrode data onto the brain surface using ``interpolate_electrodes_onto_brain`` as well as enhanced functionality of the ``plot_brain_overlay`` function to plot such data.

Version 2.2.0
-------------
- |Enhancement| : Adds the ``del`` keyword functionality to the Data object and its sub-components.
- |Enhancement| : Enhance the capability of local electrode rereferencing.


Version 2.1.0
-------------
- |Feature| : Allow the ``Brain`` class to work with MNI152 brains.
- |Enhancement| : Allow ``plot_brain_elecs`` to work with varied opacity per electrodes.
- |Fix| : Fix a bug in responsiveness_ttest.

Version 2.0.0
-------------
- |MajorFeature| : Added the ``Brain`` class for representing a brain to the ``naplib.localization`` module. This can be used to plot intracranial electrodes on static or interactive 3D brain plots with the ``naplib.visualization module``, estimate anatomical locations of electrodes, calculate statistics on brains, and more. See Examples for illustrations of use-cases.
Expand Down
11 changes: 11 additions & 0 deletions docs/references/localization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ Localization

.. currentmodule:: naplib.localization

Convert from MNI152 to FSAverage
--------------------------------

.. autofunction:: mni152_to_fsaverage

Convert from FSAverage to MNI152
--------------------------------

.. autofunction:: fsaverage_to_mni152


Localization on a Freesurfer Brain
----------------------------------

Expand Down
3 changes: 2 additions & 1 deletion naplib/localization/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .freesurfer import Brain, find_closest_vertices
from .coordinate_conversions import mni152_to_fsaverage, fsaverage_to_mni152

__all__ = ['Brain', 'find_closest_vertices']
__all__ = ['Brain', 'find_closest_vertices', 'mni152_to_fsaverage', 'fsaverage_to_mni152']
41 changes: 41 additions & 0 deletions naplib/localization/coordinate_conversions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import numpy as np

def mni152_to_fsaverage(coords):
"""
Convert 3D coordinates from MNI152 space to fsaverage space.

Parameters
----------
coords : np.ndarray (elecs, 3)
Coordinates in MNI space

Returns
-------
new_coords : np.ndarray (elecs, 3)
Coordinates in fsaverage space
"""
old_coords = np.concatenate([coords, np.ones((len(coords),1))], axis=1).T
xform = np.array([[1.0022, 0.0071, -0.0177, 0.0528], [-0.0146, 0.999, 0.0027, -1.5519], [0.0129, 0.0094, 1.0027, -1.2012]])
new_coords = (xform @ old_coords).T
return new_coords

def fsaverage_to_mni152(coords):
"""
Convert 3D coordinates from fsaverage space to MNI152 space.

Parameters
----------
coords : np.ndarray (elecs, 3)
Coordinates in fsaverage space

Returns
-------
new_coords : np.ndarray (elecs, 3)
Coordinates in MNI152 space
"""
old_coords = np.concatenate([coords, np.ones((len(coords),1))], axis=1).T
xform = np.array([[0.9975, -0.0073, 0.0176, -0.0429], [0.0146, 1.0009, -0.0024, 1.5496], [-0.013, -0.0093, 0.9971, 1.184]])
new_coords = (xform @ old_coords).T
return new_coords


14 changes: 14 additions & 0 deletions tests/test_coordinate_conversions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import numpy as np
from naplib.localization import mni152_to_fsaverage, fsaverage_to_mni152

def test_mni152_fsaverage_conversions():
coords_tmp = np.array([[13.987, 36.5, 10.067], [-10.54, 24.5, 15.555]])
coords_tmp2 = mni152_to_fsaverage(coords_tmp)
expected_2 = np.array(
[[ 14.15310394, 34.73510469, 9.41733728],
[-10.60987978, 23.11927315, 14.49010227]]
)
assert np.allclose(coords_tmp2, expected_2, rtol=1e-3)

coords_tmp3 = fsaverage_to_mni152(coords_tmp2)
assert np.allclose(coords_tmp3, coords_tmp, rtol=1e-3)