cardiac-geometriesx 0.2.0__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cardiac-geometriesx might be problematic. Click here for more details.

Files changed (24) hide show
  1. {cardiac_geometriesx-0.2.0/src/cardiac_geometriesx.egg-info → cardiac_geometriesx-0.3.1}/PKG-INFO +1 -1
  2. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/pyproject.toml +2 -2
  3. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/fibers/lv_ellipsoid.py +86 -8
  4. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/mesh.py +16 -16
  5. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1/src/cardiac_geometriesx.egg-info}/PKG-INFO +1 -1
  6. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/LICENSE +0 -0
  7. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/README.md +0 -0
  8. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/setup.cfg +0 -0
  9. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/__init__.py +0 -0
  10. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/cli.py +0 -0
  11. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/fibers/__init__.py +0 -0
  12. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/fibers/slab.py +0 -0
  13. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/fibers/utils.py +0 -0
  14. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/geometry.py +0 -0
  15. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/gui.py +0 -0
  16. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometries/utils.py +0 -0
  17. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometriesx.egg-info/SOURCES.txt +0 -0
  18. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometriesx.egg-info/dependency_links.txt +0 -0
  19. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometriesx.egg-info/entry_points.txt +0 -0
  20. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometriesx.egg-info/not-zip-safe +0 -0
  21. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometriesx.egg-info/requires.txt +0 -0
  22. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/src/cardiac_geometriesx.egg-info/top_level.txt +0 -0
  23. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/tests/test_cli.py +0 -0
  24. {cardiac_geometriesx-0.2.0 → cardiac_geometriesx-0.3.1}/tests/test_save_load.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cardiac-geometriesx
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: A python library for cardiac geometries
5
5
  Author-email: Henrik Finsberg <henriknf@simula.no>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cardiac-geometriesx"
7
- version = "0.2.0"
7
+ version = "0.3.1"
8
8
  description = "A python library for cardiac geometries"
9
9
  authors = [{name = "Henrik Finsberg", email = "henriknf@simula.no"}]
10
10
  license = {text = "MIT"}
@@ -173,7 +173,7 @@ tag = true
173
173
  sign_tags = false
174
174
  tag_name = "v{new_version}"
175
175
  tag_message = "Bump version: {current_version} → {new_version}"
176
- current_version = "0.2.0"
176
+ current_version = "0.3.1"
177
177
 
178
178
 
179
179
  [[tool.bumpversion.files]]
@@ -7,6 +7,58 @@ from ..utils import space_from_string
7
7
  from . import utils
8
8
 
9
9
 
10
+ def mu_theta(
11
+ x: np.ndarray, y: np.ndarray, z: np.ndarray, long_axis: int = 0
12
+ ) -> tuple[np.ndarray, np.ndarray, list[int]]:
13
+ """Get the angles mu and theta from the coordinates x, y, z
14
+ given the long axis.
15
+
16
+ Parameters
17
+ ----------
18
+ x : np.ndarray
19
+ The x-coordinates
20
+ y : np.ndarray
21
+ The y-coordinates
22
+ z : np.ndarray
23
+ The z-coordinates
24
+ long_axis : int, optional
25
+ The long axis, by default 0 (x-axis)
26
+
27
+ Returns
28
+ -------
29
+ tuple[np.ndarray, np.ndarray, list[int]]
30
+ The angles mu and theta and the permutation of the axes
31
+
32
+ Raises
33
+ ------
34
+ ValueError
35
+ If the long axis is not 0, 1 or 2
36
+ """
37
+ if long_axis == 0:
38
+ a = np.sqrt(y**2 + z**2)
39
+ b = x
40
+ theta = np.pi - np.arctan2(z, -y)
41
+ perm = [0, 1, 2]
42
+ elif long_axis == 1:
43
+ a = np.sqrt(x**2 + z**2)
44
+ b = y
45
+ theta = np.pi - np.arctan2(z, -x)
46
+ perm = [1, 0, 2]
47
+ elif long_axis == 2:
48
+ a = np.sqrt(x**2 + y**2)
49
+ b = z
50
+ theta = np.pi - np.arctan2(x, -y)
51
+ perm = [2, 1, 0]
52
+ else:
53
+ raise ValueError("Invalid long_axis")
54
+
55
+ mu = np.arctan2(a, b)
56
+
57
+ theta[mu < 1e-7] = 0.0
58
+
59
+ return mu, theta, perm
60
+
61
+
10
62
  def compute_system(
11
63
  t_func: dolfinx.fem.Function,
12
64
  r_short_endo=0.025,
@@ -15,8 +67,36 @@ def compute_system(
15
67
  r_long_epi=0.097,
16
68
  alpha_endo: float = -60,
17
69
  alpha_epi: float = 60,
70
+ long_axis: int = 0,
18
71
  **kwargs,
19
72
  ) -> utils.Microstructure:
73
+ """Compute the microstructure for the given time function.
74
+
75
+ Parameters
76
+ ----------
77
+ t_func : dolfinx.fem.Function
78
+ Solution of the Laplace equation
79
+ r_short_endo : float, optional
80
+ Short radius at the endocardium, by default 0.025
81
+ r_short_epi : float, optional
82
+ Short radius at the epicardium, by default 0.035
83
+ r_long_endo : float, optional
84
+ Long radius at the endocardium, by default 0.09
85
+ r_long_epi : float, optional
86
+ Long radius at the epicardium, by default 0.097
87
+ alpha_endo : float, optional
88
+ Angle at the endocardium, by default -60
89
+ alpha_epi : float, optional
90
+ Angle at the epicardium, by default 60
91
+ long_axis : int, optional
92
+ Long axis, by default 0 (x-axis)
93
+
94
+ Returns
95
+ -------
96
+ utils.Microstructure
97
+ The microstructure
98
+ """
99
+
20
100
  V = t_func.function_space
21
101
  element = V.ufl_element()
22
102
  mesh = V.mesh
@@ -40,11 +120,7 @@ def compute_system(
40
120
  y = dof_coordinates[:, 1]
41
121
  z = dof_coordinates[:, 2]
42
122
 
43
- a = np.sqrt(y**2 + z**2) / rs
44
- b = x / rl
45
- mu = np.arctan2(a, b)
46
- theta = np.pi - np.arctan2(z, -y)
47
- theta[mu < 1e-7] = 0.0
123
+ mu, theta, perm = mu_theta(x, y, z, long_axis=long_axis)
48
124
 
49
125
  e_t = np.array(
50
126
  [
@@ -52,7 +128,7 @@ def compute_system(
52
128
  drs_dt * np.sin(mu) * np.cos(theta),
53
129
  drs_dt * np.sin(mu) * np.sin(theta),
54
130
  ],
55
- )
131
+ )[perm]
56
132
  e_t = utils.normalize(e_t)
57
133
 
58
134
  e_mu = np.array(
@@ -61,7 +137,7 @@ def compute_system(
61
137
  rs * np.cos(mu) * np.cos(theta),
62
138
  rs * np.cos(mu) * np.sin(theta),
63
139
  ],
64
- )
140
+ )[perm]
65
141
  e_mu = utils.normalize(e_mu)
66
142
 
67
143
  e_theta = np.array(
@@ -70,7 +146,7 @@ def compute_system(
70
146
  -rs * np.sin(mu) * np.sin(theta),
71
147
  rs * np.sin(mu) * np.cos(theta),
72
148
  ],
73
- )
149
+ )[perm]
74
150
  e_theta = utils.normalize(e_theta)
75
151
 
76
152
  f0 = np.sin(al) * e_mu + np.cos(al) * e_theta
@@ -113,6 +189,7 @@ def create_microstructure(
113
189
  r_long_epi=0.097,
114
190
  alpha_endo: float = -60,
115
191
  alpha_epi: float = 60,
192
+ long_axis: int = 0,
116
193
  outdir: str | Path | None = None,
117
194
  ):
118
195
  endo_marker = markers["ENDO"][0]
@@ -143,6 +220,7 @@ def create_microstructure(
143
220
  r_long_epi=r_long_epi,
144
221
  alpha_endo=alpha_endo,
145
222
  alpha_epi=alpha_epi,
223
+ long_axis=long_axis,
146
224
  )
147
225
  if outdir is not None:
148
226
  utils.save_microstructure(mesh, system, outdir)
@@ -44,6 +44,7 @@ def biv_ellipsoid(
44
44
  fiber_angle_epi: float = -60,
45
45
  fiber_space: str = "P_1",
46
46
  verbose: bool = False,
47
+ comm: MPI.Comm = MPI.COMM_WORLD,
47
48
  ) -> Geometry:
48
49
  """Create BiV ellipsoidal geometry
49
50
 
@@ -99,6 +100,8 @@ def biv_ellipsoid(
99
100
  Function space for fibers of the form family_degree, by default "P_1"
100
101
  verbose : bool, optional
101
102
  If True print information from gmsh, by default False
103
+ comm : MPI.Comm, optional
104
+ MPI communicator, by default MPI.COMM_WORLD
102
105
 
103
106
  Returns
104
107
  -------
@@ -106,7 +109,6 @@ def biv_ellipsoid(
106
109
  A Geometry with the mesh, markers, markers functions and fibers.
107
110
 
108
111
  """
109
- comm = MPI.COMM_WORLD
110
112
  outdir = Path(outdir)
111
113
  mesh_name = outdir / "biv_ellipsoid.msh"
112
114
  if comm.rank == 0:
@@ -202,17 +204,6 @@ def biv_ellipsoid(
202
204
  save_microstructure(
203
205
  mesh=geometry.mesh, functions=(system.f0, system.s0, system.n0), outdir=outdir
204
206
  )
205
- # from .fibers._biv_ellipsoid import create_biv_fibers
206
-
207
- # create_biv_fibers(
208
- # mesh=geometry.mesh,
209
- # ffun=geometry.marker_functions.ffun,
210
- # markers=geometry.markers,
211
- # fiber_space=fiber_space,
212
- # alpha_endo=fiber_angle_endo,
213
- # alpha_epi=fiber_angle_epi,
214
- # outdir=outdir,
215
- # )
216
207
 
217
208
  geo = Geometry.from_folder(comm=comm, folder=outdir)
218
209
  return geo
@@ -249,6 +240,7 @@ def biv_ellipsoid_torso(
249
240
  fiber_angle_epi: float = -60,
250
241
  fiber_space: str = "P_1",
251
242
  verbose: bool = False,
243
+ comm: MPI.Comm = MPI.COMM_WORLD,
252
244
  ) -> Geometry:
253
245
  """Create BiV ellipsoidal geometry
254
246
 
@@ -316,6 +308,8 @@ def biv_ellipsoid_torso(
316
308
  Function space for fibers of the form family_degree, by default "P_1"
317
309
  verbose : bool, optional
318
310
  If True print information from gmsh, by default False
311
+ comm : MPI.Comm, optional
312
+ MPI communicator, by default MPI.COMM_WORLD
319
313
 
320
314
  Returns
321
315
  -------
@@ -323,7 +317,6 @@ def biv_ellipsoid_torso(
323
317
  A Geometry with the mesh, markers, markers functions and fibers.
324
318
 
325
319
  """
326
- comm = MPI.COMM_WORLD
327
320
  outdir = Path(outdir)
328
321
  mesh_name = outdir / "biv_ellipsoid_torso.msh"
329
322
  if comm.rank == 0:
@@ -445,6 +438,7 @@ def lv_ellipsoid(
445
438
  fiber_space: str = "P_1",
446
439
  aha: bool = True,
447
440
  verbose: bool = False,
441
+ comm: MPI.Comm = MPI.COMM_WORLD,
448
442
  ) -> Geometry:
449
443
  """Create an LV ellipsoidal geometry
450
444
 
@@ -482,6 +476,8 @@ def lv_ellipsoid(
482
476
  If True create 17-segment AHA regions
483
477
  verbose : bool, optional
484
478
  If True print information from gmsh, by default False
479
+ comm : MPI.Comm, optional
480
+ MPI communicator, by default MPI.COMM_WORLD
485
481
 
486
482
  Returns
487
483
  -------
@@ -489,7 +485,7 @@ def lv_ellipsoid(
489
485
  A Geometry with the mesh, markers, markers functions and fibers.
490
486
 
491
487
  """
492
- comm = MPI.COMM_WORLD
488
+
493
489
  outdir = Path(outdir)
494
490
  mesh_name = outdir / "lv_ellipsoid.msh"
495
491
  if comm.rank == 0:
@@ -596,6 +592,7 @@ def slab(
596
592
  fiber_angle_epi: float = -60,
597
593
  fiber_space: str = "P_1",
598
594
  verbose: bool = False,
595
+ comm: MPI.Comm = MPI.COMM_WORLD,
599
596
  ) -> Geometry:
600
597
  """Create slab geometry
601
598
 
@@ -621,6 +618,8 @@ def slab(
621
618
  Function space for fibers of the form family_degree, by default "P_1"
622
619
  verbose : bool, optional
623
620
  If True print information from gmsh, by default False
621
+ comm : MPI.Comm, optional
622
+ MPI communicator, by default MPI.COMM_WORLD
624
623
 
625
624
  Returns
626
625
  -------
@@ -628,7 +627,6 @@ def slab(
628
627
  A Geometry with the mesh, markers, markers functions and fibers.
629
628
 
630
629
  """
631
- comm = MPI.COMM_WORLD
632
630
  outdir = Path(outdir)
633
631
  mesh_name = outdir / "slab.msh"
634
632
  if comm.rank == 0:
@@ -698,6 +696,7 @@ def slab_in_bath(
698
696
  bz: float = 0.1,
699
697
  dx: float = 0.001,
700
698
  verbose: bool = False,
699
+ comm: MPI.Comm = MPI.COMM_WORLD,
701
700
  ) -> Geometry:
702
701
  """Create slab geometry
703
702
 
@@ -721,6 +720,8 @@ def slab_in_bath(
721
720
  Element size, by default 0.001
722
721
  verbose : bool, optional
723
722
  If True print information from gmsh, by default False
723
+ comm : MPI.Comm, optional
724
+ MPI communicator, by default MPI.COMM_WORLD
724
725
 
725
726
  Returns
726
727
  -------
@@ -728,7 +729,6 @@ def slab_in_bath(
728
729
  A Geometry with the mesh, markers, markers functions and fibers.
729
730
 
730
731
  """
731
- comm = MPI.COMM_WORLD
732
732
 
733
733
  outdir = Path(outdir)
734
734
  mesh_name = outdir / "slab_in_bath.msh"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cardiac-geometriesx
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: A python library for cardiac geometries
5
5
  Author-email: Henrik Finsberg <henriknf@simula.no>
6
6
  License: MIT