Skip to content

Commit 8b3b777

Browse files
committed
chore: move "make_cell_upright" to plotting utils
This functionality is not specific to the vispy plotter.
1 parent 966f928 commit 8b3b777

File tree

2 files changed

+60
-60
lines changed

2 files changed

+60
-60
lines changed

pyneuroml/plot/PlotMorphologyVispy.py

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from scipy.spatial.transform import Rotation
2323

2424
from pyneuroml.pynml import read_neuroml2_file
25-
from pyneuroml.utils import extract_position_info, rotate_cell, translate_cell_to_coords
25+
from pyneuroml.utils import extract_position_info, make_cell_upright
2626
from pyneuroml.utils.plot import (
2727
DEFAULTS,
2828
get_cell_bound_box,
@@ -782,65 +782,6 @@ def plot_interactive_3D(
782782
app.run()
783783

784784

785-
def make_cell_upright(
786-
cell: Cell = None,
787-
inplace: bool = False,
788-
) -> Cell:
789-
"""Use cell's PCA to make it upright
790-
791-
.. versionadded:: 1.2.13
792-
793-
:param cell: cell object to translate
794-
:type cell: neuroml.Cell
795-
:param inplace: toggle whether the cell object should be modified inplace
796-
or a copy created (creates and returns a copy by default)
797-
:type inplace: bool
798-
:returns: new neuroml.Cell object
799-
:rtype: neuroml.Cell
800-
"""
801-
802-
# Get all segments' distal points
803-
segment_points = []
804-
segments_all = cell.morphology.segments
805-
for segment in segments_all:
806-
segment_points.append([segment.distal.x, segment.distal.y, segment.distal.z])
807-
808-
coords = numpy.array(segment_points)
809-
from sklearn.decomposition import PCA
810-
811-
# Get the PCA components
812-
pca = PCA()
813-
pca.fit(coords)
814-
815-
# Get the principal component axes
816-
principal_axes = pca.components_
817-
# Get the first principal component axis
818-
first_pca = principal_axes[0]
819-
# y angle needed to eliminate z component
820-
y_angle = math.atan(first_pca[2] / first_pca[0])
821-
rotation_y = numpy.array(
822-
[
823-
[math.cos(y_angle), 0, math.sin(y_angle)],
824-
[0, 1, 0],
825-
[-math.sin(y_angle), 0, math.cos(y_angle)],
826-
]
827-
)
828-
rotated_pca = numpy.dot(rotation_y, first_pca)
829-
830-
# z angle needed to eliminate x component
831-
z_angle = -math.atan(rotated_pca[0] / rotated_pca[1])
832-
833-
if z_angle < 0:
834-
z_angle += numpy.pi
835-
836-
logger.debug("Making cell upright for visualization")
837-
cell = translate_cell_to_coords(cell, inplace=inplace, dest=[0, 0, 0])
838-
cell = rotate_cell(
839-
cell, 0, y_angle, z_angle, "yzx", relative_to_soma=False, inplace=inplace
840-
)
841-
return cell
842-
843-
844785
def plot_3D_cell_morphology(
845786
offset: typing.List[float] = [0, 0, 0],
846787
cell: Optional[Cell] = None,

pyneuroml/utils/__init__.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,65 @@ def translate_cell_to_coords(
546546
return newcell
547547

548548

549+
def make_cell_upright(
550+
cell: neuroml.Cell = None,
551+
inplace: bool = False,
552+
) -> neuroml.Cell:
553+
"""Use cell's PCA to make it upright
554+
555+
.. versionadded:: 1.2.13
556+
557+
:param cell: cell object to translate
558+
:type cell: neuroml.Cell
559+
:param inplace: toggle whether the cell object should be modified inplace
560+
or a copy created (creates and returns a copy by default)
561+
:type inplace: bool
562+
:returns: new neuroml.Cell object
563+
:rtype: neuroml.Cell
564+
"""
565+
566+
# Get all segments' distal points
567+
segment_points = []
568+
segments_all = cell.morphology.segments
569+
for segment in segments_all:
570+
segment_points.append([segment.distal.x, segment.distal.y, segment.distal.z])
571+
572+
coords = numpy.array(segment_points)
573+
from sklearn.decomposition import PCA
574+
575+
# Get the PCA components
576+
pca = PCA()
577+
pca.fit(coords)
578+
579+
# Get the principal component axes
580+
principal_axes = pca.components_
581+
# Get the first principal component axis
582+
first_pca = principal_axes[0]
583+
# y angle needed to eliminate z component
584+
y_angle = math.atan(first_pca[2] / first_pca[0])
585+
rotation_y = numpy.array(
586+
[
587+
[math.cos(y_angle), 0, math.sin(y_angle)],
588+
[0, 1, 0],
589+
[-math.sin(y_angle), 0, math.cos(y_angle)],
590+
]
591+
)
592+
rotated_pca = numpy.dot(rotation_y, first_pca)
593+
594+
# z angle needed to eliminate x component
595+
z_angle = -math.atan(rotated_pca[0] / rotated_pca[1])
596+
597+
if z_angle < 0:
598+
z_angle += numpy.pi
599+
600+
logger.debug("Making cell upright for visualization")
601+
cell = translate_cell_to_coords(cell, inplace=inplace, dest=[0, 0, 0])
602+
cell = rotate_cell(
603+
cell, 0, y_angle, z_angle, "yzx", relative_to_soma=False, inplace=inplace
604+
)
605+
return cell
606+
607+
549608
def get_pyneuroml_tempdir(rootdir: str = ".", prefix: str = "pyneuroml"):
550609
"""Generate a pyneuroml directory name that can be used for various
551610
purposes.

0 commit comments

Comments
 (0)