.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\preprocessor\user_conduction_system_pr.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_preprocessor_user_conduction_system_pr.py: Full-heart conduction system example ==================================== This example demonstrates how to build a conduction system for a full-heart model, including the Purkinje network and other conduction pathways. .. note:: The fractal tree used in this example was generated with LS-DYNA and is based on: `F. Sahli Costabal, D. Hurtado and E. Kuhl. Generating Purkinje networks in the human heart. 2016, Journal of Biomechanics `_. Overview -------- In addition to the Purkinje fibers, this example defines other key conduction pathways, such as the sinoatrial (SA) node to atrioventricular (AV) node path, the Bachmann bundle, the His bundle and its bifurcation, as well as the left and right bundle branches. Each conduction path is constructed using anatomical landmarks and keypoints, and is integrated into the heart model. .. GENERATED FROM PYTHON SOURCE LINES 46-48 Required imports ~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 48-65 .. code-block:: Python from pathlib import Path import numpy as np import pyvista as pv from ansys.health.heart.examples import ( get_fractal_tree_purkinje, get_preprocessed_fullheart, ) import ansys.health.heart.models as models from ansys.health.heart.models_utils import HeartModelUtils from ansys.health.heart.pre.conduction_path import ConductionPath, ConductionPathType # Set the working directory and path to the model. workdir = Path.home() / "pyansys-heart" / "downloads" / "Rodero2021" / "01" / "FullHeart" path_to_model, path_to_partinfo, _ = get_preprocessed_fullheart(resolution="2.0mm") .. GENERATED FROM PYTHON SOURCE LINES 66-68 Load the full-heart model ~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 68-72 .. code-block:: Python model: models.FullHeart = models.FullHeart.load_model( path_to_model, path_to_partinfo, working_directory=workdir ) .. GENERATED FROM PYTHON SOURCE LINES 73-75 Create conduction paths for the Purkinje network ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 75-96 .. code-block:: Python # Load precomputed Purkinje network meshes left_purkinje, right_purkinje = get_fractal_tree_purkinje() # Create left Purkinje network conduction path left_purkinje = ConductionPath( name=ConductionPathType.LEFT_PURKINJE, mesh=left_purkinje, is_connected=np.zeros(left_purkinje.n_points), id=1, relying_surface=model.left_ventricle.endocardium, ) # Add Purkinje-myocardial junctions (PMJs) at terminal nodes pmj_nodes_left = left_purkinje.get_terminal_nodes() pmj_coordinates_left = left_purkinje.get_terminal_coordinates() left_purkinje.add_pmj_path(pmj_list=pmj_nodes_left) # Visualize the left Purkinje network left_purkinje.plot() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_001.png :alt: user conduction system pr :srcset: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_001.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: C:\Users\ansys\actions-runner\_work\pyansys-heart\pyansys-heart\doc\source\examples\preprocessor\images\sphx_glr_user_conduction_system_pr_001.vtksz .. GENERATED FROM PYTHON SOURCE LINES 97-99 Create right Purkinje network ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 99-115 .. code-block:: Python right_purkinje = ConductionPath( name=ConductionPathType.RIGHT_PURKINJE, mesh=right_purkinje, is_connected=np.zeros(right_purkinje.n_points), id=2, relying_surface=model.right_ventricle.endocardium, ) # Add Purkinje-myocardial junctions (PMJs) at terminal nodes pmj_nodes_right = right_purkinje.get_terminal_nodes() pmj_coordinates_right = right_purkinje.get_terminal_coordinates() right_purkinje.add_pmj_path(pmj_list=pmj_nodes_right) # Visualize the right Purkinje network right_purkinje.plot() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_002.png :alt: user conduction system pr :srcset: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_002.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: C:\Users\ansys\actions-runner\_work\pyansys-heart\pyansys-heart\doc\source\examples\preprocessor\images\sphx_glr_user_conduction_system_pr_002.vtksz .. GENERATED FROM PYTHON SOURCE LINES 116-119 Visualize both Purkinje networks and PMJ points together ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Combine PMJ coordinates for visualization .. GENERATED FROM PYTHON SOURCE LINES 119-134 .. code-block:: Python pmj_points = pv.PolyData(np.vstack([pmj_coordinates_left, pmj_coordinates_right])) # Create a plotter and add all relevant meshes plotter = pv.Plotter() plotter.add_mesh(pmj_points, color="r", render_points_as_spheres=True, point_size=5) plotter.add_mesh(pv.merge([left_purkinje.mesh, right_purkinje.mesh]), line_width=2) plotter.add_mesh( pv.merge([left_purkinje.relying_surface, right_purkinje.relying_surface]), opacity=0.5, color="white", ) plotter.add_text("Left and right Purkinje networks.", position="upper_edge") plotter.show() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_003.png :alt: user conduction system pr :srcset: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_003.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: C:\Users\ansys\actions-runner\_work\pyansys-heart\pyansys-heart\doc\source\examples\preprocessor\images\sphx_glr_user_conduction_system_pr_003.vtksz .. GENERATED FROM PYTHON SOURCE LINES 135-137 Create the SA-AV node conduction path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 137-157 .. code-block:: Python sa = HeartModelUtils.define_sino_atrial_node(model, target_coord=[6, 66, 88]) av = HeartModelUtils.define_atrio_ventricular_node(model) # Create the SA-AV node conduction path. The default option is to connect the # SA node and AV node by a geodesic path. sa_av = ConductionPath.create_from_keypoints( name=ConductionPathType.SAN_AVN, keypoints=[sa.xyz, av.xyz], id=3, base_mesh=model.right_atrium.endocardium, connection="first", line_length=None, center=True, ) # Add PMJ nodes at every 4th node along the SA-AV path (excluding endpoints) sa_av.add_pmj_path(list(range(1, sa_av.mesh.n_points - 1, 4))) # Visualize the SA-AV node conduction path sa_av.plot() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_004.png :alt: user conduction system pr :srcset: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_004.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: C:\Users\ansys\actions-runner\_work\pyansys-heart\pyansys-heart\doc\source\examples\preprocessor\images\sphx_glr_user_conduction_system_pr_004.vtksz .. GENERATED FROM PYTHON SOURCE LINES 158-161 Create the His bundle and its bifurcation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The His bundle is constructuted inside the myocardium, not on a surface. .. GENERATED FROM PYTHON SOURCE LINES 163-166 .. note:: You can modify the conduction velocity in ``his_top.ep_material`` to induce a delay in activation. .. GENERATED FROM PYTHON SOURCE LINES 166-197 .. code-block:: Python # Define three keypoints for the His bundle his_bif = HeartModelUtils.define_his_bundle_bifurcation_node(model) his_left_point = HeartModelUtils.define_his_bundle_end_node(model, side="left") his_right_point = HeartModelUtils.define_his_bundle_end_node(model, side="right") # Top part of the His bundle. his_top = ConductionPath.create_from_keypoints( name=ConductionPathType.HIS_TOP, keypoints=[av.xyz, his_bif.xyz], id=4, base_mesh=model.mesh.extract_cells_by_type(10), ) his_top.up_path = sa_av # Create branches for the left and right bundle branches his_left = ConductionPath.create_from_keypoints( name=ConductionPathType.HIS_LEFT, keypoints=[his_bif.xyz, his_left_point.xyz], id=5, base_mesh=model.mesh.extract_cells_by_type(pv.CellType.TETRA), ) his_left.up_path = his_top his_right = ConductionPath.create_from_keypoints( name=ConductionPathType.HIS_RIGHT, keypoints=[his_bif.xyz, his_right_point.xyz], id=6, base_mesh=model.mesh.extract_cells_by_type(pv.CellType.TETRA), ) his_right.up_path = his_top .. GENERATED FROM PYTHON SOURCE LINES 198-201 Create the left and right bundle branches ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create the left and right bundle branches by defining their keypoints .. GENERATED FROM PYTHON SOURCE LINES 201-238 .. code-block:: Python left_bundle = ConductionPath.create_from_keypoints( name=ConductionPathType.LEFT_BUNDLE_BRANCH, keypoints=[his_left_point.xyz, model.left_ventricle.apex_points[0].xyz], id=7, base_mesh=model.left_ventricle.endocardium, line_length=None, center=True, ) # Connect the left bundle branch to the septum by adding additional Purkinje-myocardial junctions pmj_list = list( range( int((0.4 * left_bundle.mesh.n_points)), int((0.9 * left_bundle.mesh.n_points)), 4, # every 4 nodes ) ) left_bundle.add_pmj_path(pmj_list, merge_with="node") left_bundle.up_path = his_left left_bundle.down_path = left_purkinje # Build the right bundle branch surface_ids = [ model.right_ventricle.endocardium.id, model.right_ventricle.septum.id, ] endo_surface = model.mesh.get_surface(surface_ids) right_bundle = ConductionPath.create_from_keypoints( name=ConductionPathType.RIGHT_BUNDLE_BRANCH, keypoints=[his_right_point.xyz, model.right_ventricle.apex_points[0].xyz], id=8, base_mesh=endo_surface, line_length=None, ) right_bundle.up_path = his_right right_bundle.down_path = right_purkinje .. GENERATED FROM PYTHON SOURCE LINES 239-241 Create the Bachmann bundle ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 241-257 .. code-block:: Python surface_ids = [ model.left_atrium.epicardium.id, model.right_atrium.epicardium.id, ] surface = model.mesh.get_surface(surface_ids) bachman_bundle = ConductionPath.create_from_keypoints( name=ConductionPathType.BACHMANN_BUNDLE, keypoints=[sa.xyz, [46, 102, 97]], id=9, base_mesh=surface, line_length=None, center=True, ) bachman_bundle.add_pmj_path(list(range(1, bachman_bundle.mesh.n_points - 1, 4))) bachman_bundle.up_path = sa_av .. GENERATED FROM PYTHON SOURCE LINES 258-260 Create the mid and post SA-AV node conduction paths ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 260-292 .. code-block:: Python # The mid and post SA-AV node conduction paths are created by providing a list of keypoints. mid_sa_av = ConductionPath.create_from_keypoints( name=ConductionPathType.MID_SAN_AVN, keypoints=[ sa.xyz, [10, 79, 64], [18, 95, 41], [32, 93, 31], [43, 88, 26], av.xyz, ], id=10, base_mesh=model.right_atrium.endocardium, line_length=None, center=True, ) mid_sa_av.add_pmj_path(list(range(5, mid_sa_av.mesh.n_points - 5, 4))) mid_sa_av.up_path = sa_av mid_sa_av.down_path = sa_av post_sa_av = ConductionPath.create_from_keypoints( name=ConductionPathType.POST_SAN_AVN, keypoints=[sa.xyz, [2, 65, 53], [6, 73, 34], [25, 75, 26], av.xyz], id=11, base_mesh=model.right_atrium.endocardium, line_length=None, center=True, ) post_sa_av.add_pmj_path(list(range(5, post_sa_av.mesh.n_points - 5, 4))) post_sa_av.up_path = sa_av post_sa_av.down_path = sa_av .. GENERATED FROM PYTHON SOURCE LINES 293-295 Assign all conduction paths to the model and visualize the complete system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. GENERATED FROM PYTHON SOURCE LINES 295-314 .. code-block:: Python model.assign_conduction_paths( [ left_purkinje, right_purkinje, sa_av, his_top, his_left, his_right, left_bundle, right_bundle, bachman_bundle, mid_sa_av, post_sa_av, ] ) # Visualize the entire conduction system model.plot_purkinje() .. tab-set:: .. tab-item:: Static Scene .. image-sg:: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_005.png :alt: user conduction system pr :srcset: /examples/preprocessor/images/sphx_glr_user_conduction_system_pr_005.png :class: sphx-glr-single-img .. tab-item:: Interactive Scene .. offlineviewer:: C:\Users\ansys\actions-runner\_work\pyansys-heart\pyansys-heart\doc\source\examples\preprocessor\images\sphx_glr_user_conduction_system_pr_005.vtksz .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 36.638 seconds) .. _sphx_glr_download_examples_preprocessor_user_conduction_system_pr.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: user_conduction_system_pr.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: user_conduction_system_pr.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: user_conduction_system_pr.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_