physioblocks 1.0.0__py3-none-any.whl

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.
Files changed (93) hide show
  1. physioblocks/__init__.py +37 -0
  2. physioblocks/base/__init__.py +27 -0
  3. physioblocks/base/operators.py +176 -0
  4. physioblocks/base/registers.py +108 -0
  5. physioblocks/computing/__init__.py +47 -0
  6. physioblocks/computing/assembling.py +291 -0
  7. physioblocks/computing/models.py +811 -0
  8. physioblocks/computing/quantities.py +354 -0
  9. physioblocks/configuration/__init__.py +38 -0
  10. physioblocks/configuration/aliases.py +203 -0
  11. physioblocks/configuration/base.py +123 -0
  12. physioblocks/configuration/computing/__init__.py +27 -0
  13. physioblocks/configuration/computing/quantities.py +56 -0
  14. physioblocks/configuration/constants.py +121 -0
  15. physioblocks/configuration/description/__init__.py +33 -0
  16. physioblocks/configuration/description/blocks.py +239 -0
  17. physioblocks/configuration/description/nets.py +155 -0
  18. physioblocks/configuration/functions.py +695 -0
  19. physioblocks/configuration/simulation/__init__.py +32 -0
  20. physioblocks/configuration/simulation/simulations.py +280 -0
  21. physioblocks/description/__init__.py +34 -0
  22. physioblocks/description/blocks.py +418 -0
  23. physioblocks/description/flux.py +157 -0
  24. physioblocks/description/nets.py +746 -0
  25. physioblocks/io/__init__.py +29 -0
  26. physioblocks/io/aliases.py +73 -0
  27. physioblocks/io/configuration.py +125 -0
  28. physioblocks/launcher/__main__.py +285 -0
  29. physioblocks/launcher/configuration.py +231 -0
  30. physioblocks/launcher/configure/__main__.py +99 -0
  31. physioblocks/launcher/constants.py +105 -0
  32. physioblocks/launcher/files.py +150 -0
  33. physioblocks/launcher/series.py +165 -0
  34. physioblocks/library/__init__.py +27 -0
  35. physioblocks/library/aliases/blocks/c_block.json +5 -0
  36. physioblocks/library/aliases/blocks/rc_block.json +5 -0
  37. physioblocks/library/aliases/blocks/rcr_block.json +5 -0
  38. physioblocks/library/aliases/blocks/spherical_cavity_block.json +5 -0
  39. physioblocks/library/aliases/blocks/valve_rl_block.json +5 -0
  40. physioblocks/library/aliases/flux/heart_flux_dof_couples.jsonc +4 -0
  41. physioblocks/library/aliases/model_components/active_law_macro_huxley_two_moments.json +5 -0
  42. physioblocks/library/aliases/model_components/rheology_fiber_additive.json +5 -0
  43. physioblocks/library/aliases/model_components/spherical_dynamics.json +5 -0
  44. physioblocks/library/aliases/model_components/velocity_law_hht.json +5 -0
  45. physioblocks/library/aliases/nets/circulation_alone_net.json +31 -0
  46. physioblocks/library/aliases/nets/spherical_heart_net.json +93 -0
  47. physioblocks/library/aliases/simulations/circulation_alone_forward_simulation.jsonc +55 -0
  48. physioblocks/library/aliases/simulations/default_forward_simulation.jsonc +7 -0
  49. physioblocks/library/aliases/simulations/default_time.jsonc +8 -0
  50. physioblocks/library/aliases/simulations/newton_method_solver.json +5 -0
  51. physioblocks/library/aliases/simulations/spherical_heart_forward_simulation.jsonc +157 -0
  52. physioblocks/library/aliases/simulations/spherical_heart_with_respiration_forward_simulation.jsonc +45 -0
  53. physioblocks/library/blocks/__init__.py +27 -0
  54. physioblocks/library/blocks/capacitances.py +516 -0
  55. physioblocks/library/blocks/cavity.py +192 -0
  56. physioblocks/library/blocks/valves.py +281 -0
  57. physioblocks/library/functions/__init__.py +27 -0
  58. physioblocks/library/functions/base_operations.py +129 -0
  59. physioblocks/library/functions/first_order.py +113 -0
  60. physioblocks/library/functions/piecewise.py +271 -0
  61. physioblocks/library/functions/trigonometric.py +78 -0
  62. physioblocks/library/functions/watchers.py +113 -0
  63. physioblocks/library/model_components/__init__.py +27 -0
  64. physioblocks/library/model_components/active_law.py +345 -0
  65. physioblocks/library/model_components/dynamics.py +986 -0
  66. physioblocks/library/model_components/rheology.py +160 -0
  67. physioblocks/library/model_components/velocity_law.py +169 -0
  68. physioblocks/references/circulation_alone_sim.jsonc +24 -0
  69. physioblocks/references/spherical_heart_respiration_sim.jsonc +33 -0
  70. physioblocks/references/spherical_heart_sim.jsonc +29 -0
  71. physioblocks/registers/__init__.py +32 -0
  72. physioblocks/registers/load_function_register.py +93 -0
  73. physioblocks/registers/save_function_register.py +106 -0
  74. physioblocks/registers/type_register.py +97 -0
  75. physioblocks/simulation/__init__.py +48 -0
  76. physioblocks/simulation/constants.py +30 -0
  77. physioblocks/simulation/functions.py +71 -0
  78. physioblocks/simulation/runtime.py +484 -0
  79. physioblocks/simulation/saved_quantities.py +129 -0
  80. physioblocks/simulation/setup.py +576 -0
  81. physioblocks/simulation/solvers.py +235 -0
  82. physioblocks/simulation/state.py +340 -0
  83. physioblocks/simulation/time_manager.py +354 -0
  84. physioblocks/utils/__init__.py +27 -0
  85. physioblocks/utils/dynamic_import_utils.py +150 -0
  86. physioblocks/utils/exceptions_utils.py +115 -0
  87. physioblocks/utils/gradient_test_utils.py +337 -0
  88. physioblocks/utils/math_utils.py +109 -0
  89. physioblocks-1.0.0.dist-info/METADATA +127 -0
  90. physioblocks-1.0.0.dist-info/RECORD +93 -0
  91. physioblocks-1.0.0.dist-info/WHEEL +4 -0
  92. physioblocks-1.0.0.dist-info/licenses/licenses/GPL-3.0-only.txt +674 -0
  93. physioblocks-1.0.0.dist-info/licenses/licenses/LGPL-3.0-only.txt +165 -0
@@ -0,0 +1,160 @@
1
+ # SPDX-FileCopyrightText: Copyright INRIA
2
+ #
3
+ # SPDX-License-Identifier: LGPL-3.0-only
4
+ #
5
+ # Copyright INRIA
6
+ #
7
+ # This file is part of PhysioBlocks, a library mostly developed by the
8
+ # [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
9
+ #
10
+ # Authors:
11
+ # - Colin Drieu
12
+ # - Dominique Chapelle
13
+ # - François Kimmig
14
+ # - Philippe Moireau
15
+ #
16
+ # PhysioBlocks is free software: you can redistribute it and/or modify it under the
17
+ # terms of the GNU Lesser General Public License as published by the Free Software
18
+ # Foundation, version 3 of the License.
19
+ #
20
+ # PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
21
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
+ # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
23
+ #
24
+ # You should have received a copy of the GNU Lesser General Public License along with
25
+ # PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
26
+
27
+ """
28
+ Describes rheology models
29
+ """
30
+
31
+ from dataclasses import dataclass
32
+ from typing import Any
33
+
34
+ import numpy as np
35
+
36
+ from physioblocks.computing import Expression, ModelComponent, Quantity, diff, mid_point
37
+ from physioblocks.registers import register_type
38
+ from physioblocks.simulation import Time
39
+
40
+ # Constant for the rheology model type id
41
+ RHEOLOGY_FIBER_ADDITIVE_TYPE_ID = "rheology_fiber_additive"
42
+
43
+
44
+ @register_type(RHEOLOGY_FIBER_ADDITIVE_TYPE_ID)
45
+ @dataclass
46
+ class RheologyFiberAdditiveModelComponent(ModelComponent):
47
+ r"""
48
+ Describes a Fiber Additive Rheology model implementation.
49
+
50
+ **Internal Equation:**
51
+
52
+ .. math::
53
+
54
+ \dot{e}_c + T_c - k_s \Bigl( \frac{y}{R_0}-e_c \Bigr) = 0
55
+
56
+
57
+ **Discretised:**
58
+
59
+ .. math::
60
+
61
+ \mu \frac{e_c^{n+1}-e_c^n}{\Delta t^n}
62
+ - k_s \Bigl( \frac{y^{n + \frac{1}{2}}}{R_0}-e_c^{n + \frac{1}{2}} \Bigr)
63
+ + T_c^{{n + \frac{1}{2}}\sharp} = 0
64
+
65
+ """
66
+
67
+ fib_deform: Quantity[np.float64]
68
+ """:math:`e_c` the fiber deformation"""
69
+
70
+ disp: Quantity[np.float64]
71
+ """:math:`y` the displacement"""
72
+
73
+ active_tension_discr: Quantity[np.float64]
74
+ """:math:`T_c^{{n + \frac{1}{2}}\\sharp}` the active tension discretisation"""
75
+
76
+ radius: Quantity[np.float64]
77
+ """:math:`R_0` sphere initial radius"""
78
+
79
+ damping_parallel: Quantity[np.float64]
80
+ """:math:`\\mu` the damping parallel"""
81
+
82
+ series_stiffness: Quantity[np.float64]
83
+ """:math:`k_s` the series stiffness"""
84
+
85
+ time: Time
86
+ """:math:`t` the simulation time"""
87
+
88
+ def initialize(self) -> None:
89
+ """
90
+ Initialize model's radius inverse
91
+ """
92
+ self._inv_radius = 1 / self.radius.current
93
+
94
+ def fib_deform_equation(self) -> Any:
95
+ """
96
+ Compute the equation representing the fiber deformation.
97
+
98
+ :return: the relation value
99
+ :rtype: np.float64
100
+ """
101
+
102
+ disp_mid_pt = mid_point(self.disp)
103
+ fib_deform_mid_pt = mid_point(self.fib_deform)
104
+
105
+ return (
106
+ self.active_tension_discr.new
107
+ + (self.damping_parallel.current * self.time.inv_dt * diff(self.fib_deform))
108
+ - (
109
+ self.series_stiffness.current
110
+ * (disp_mid_pt * self._inv_radius - fib_deform_mid_pt)
111
+ )
112
+ )
113
+
114
+ def dfib_deform_equation_dfib_deform(self) -> Any:
115
+ """
116
+ Compute the equation partial derivative for ``fib_deform``
117
+
118
+ :return: the partial derivative value
119
+ :rtype: np.float64
120
+ """
121
+
122
+ return (
123
+ self.damping_parallel.current * self.time.inv_dt
124
+ + self.series_stiffness.current * 0.5
125
+ )
126
+
127
+ def dfib_deform_equation_ddisp(self) -> np.float64:
128
+ """
129
+ Compute the equation partial derivative for ``disp``
130
+
131
+ :return: the partial derivative value
132
+ :rtype: np.float64
133
+ """
134
+ return -self.series_stiffness.current * self._inv_radius * 0.5
135
+
136
+ def dfib_deform_equation_dactive_tension_discr(self) -> Any:
137
+ """
138
+ Compute the equation partial derivative for the ``active_tension_discr``
139
+
140
+ :return: the partial derivative value
141
+ :rtype: np.float64
142
+ """
143
+ return 1.0
144
+
145
+
146
+ # Define the expression of the equation of the model.
147
+ _fib_deform_equation_expr = Expression(
148
+ 1,
149
+ RheologyFiberAdditiveModelComponent.fib_deform_equation,
150
+ {
151
+ "fib_deform": RheologyFiberAdditiveModelComponent.dfib_deform_equation_dfib_deform, # noqa: E501
152
+ "disp": RheologyFiberAdditiveModelComponent.dfib_deform_equation_ddisp,
153
+ "active_tension_discr": RheologyFiberAdditiveModelComponent.dfib_deform_equation_dactive_tension_discr, # noqa: E501
154
+ },
155
+ )
156
+
157
+ RheologyFiberAdditiveModelComponent.declares_internal_expression(
158
+ "fib_deform",
159
+ _fib_deform_equation_expr,
160
+ )
@@ -0,0 +1,169 @@
1
+ # SPDX-FileCopyrightText: Copyright INRIA
2
+ #
3
+ # SPDX-License-Identifier: LGPL-3.0-only
4
+ #
5
+ # Copyright INRIA
6
+ #
7
+ # This file is part of PhysioBlocks, a library mostly developed by the
8
+ # [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
9
+ #
10
+ # Authors:
11
+ # - Colin Drieu
12
+ # - Dominique Chapelle
13
+ # - François Kimmig
14
+ # - Philippe Moireau
15
+ #
16
+ # PhysioBlocks is free software: you can redistribute it and/or modify it under the
17
+ # terms of the GNU Lesser General Public License as published by the Free Software
18
+ # Foundation, version 3 of the License.
19
+ #
20
+ # PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
21
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
+ # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
23
+ #
24
+ # You should have received a copy of the GNU Lesser General Public License along with
25
+ # PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
26
+
27
+ """
28
+ Module describing a discretized Velocity Law Block.
29
+
30
+ It defines two residual giving a dynamics on the velocity and acceleration.
31
+ """
32
+
33
+ from dataclasses import dataclass
34
+
35
+ import numpy as np
36
+ from numpy.typing import NDArray
37
+
38
+ from physioblocks.computing import (
39
+ Expression,
40
+ ModelComponent,
41
+ Quantity,
42
+ diff,
43
+ mid_alpha,
44
+ mid_point,
45
+ )
46
+ from physioblocks.registers import register_type
47
+ from physioblocks.simulation import Time
48
+
49
+ # Constant for the velocity law hht type name
50
+ VELOCITY_LAW_HHT_TYPE_ID = "velocity_law_hht"
51
+
52
+
53
+ @dataclass
54
+ @register_type(VELOCITY_LAW_HHT_TYPE_ID)
55
+ class VelocityLawHHTModelComponent(ModelComponent):
56
+ r"""
57
+ Velocity law HHT quantities and equation definitions
58
+
59
+ Implement the extended version of the **HHT time integration scheme**.
60
+ Velocity and acceleration unknowns are introduced and solved for by
61
+
62
+ **Discretised Internal Equations:**
63
+
64
+ .. math::
65
+
66
+ \frac{\dot{y}^{n+1}-\dot{y}^n}{\Delta t^n}
67
+ - (\tfrac{1}{2}+\alpha)\, \ddot{y}^{n+1}
68
+ - (\tfrac{1}{2}-\alpha)\, \ddot{y}^n = 0
69
+
70
+ .. math::
71
+
72
+ \frac{y^{n+1}-y^n}{\Delta t^n}
73
+ - \dot{y}^{n + \frac{1}{2}}
74
+ - \frac{\alpha^2}{4}\Delta t^n\, (\ddot{y}^{n+1}-\ddot{y}^n) = 0
75
+ """
76
+
77
+ scheme_ts_hht: Quantity[np.float64]
78
+ """:math:`\\alpha` the time shift scheme"""
79
+
80
+ accel: Quantity[np.float64]
81
+ """:math:`\\ddot{y}` the acceleration"""
82
+
83
+ vel: Quantity[np.float64]
84
+ """:math:`\\dot{y}` the velocity"""
85
+
86
+ disp: Quantity[np.float64]
87
+ """:math:`y` the displacement"""
88
+
89
+ time: Time
90
+ """:math:`t` the time"""
91
+
92
+ def velocity_law_residual(self) -> NDArray[np.float64]:
93
+ """
94
+ Compute the velocity law residual
95
+
96
+ :return: the residual value
97
+ :rtype: NDArray[np.float64]
98
+ """
99
+ accel_mid_alpha = mid_alpha(self.accel, self.scheme_ts_hht.current)
100
+ vel_mid_point = mid_point(self.vel)
101
+
102
+ return np.array(
103
+ [
104
+ (self.time.inv_dt * diff(self.vel) - accel_mid_alpha),
105
+ (
106
+ self.time.inv_dt * diff(self.disp)
107
+ - vel_mid_point
108
+ - np.power(self.scheme_ts_hht.current, 2)
109
+ * self.time.dt
110
+ / 4.0
111
+ * diff(self.accel)
112
+ ),
113
+ ],
114
+ )
115
+
116
+ def velocity_law_residual_daccel(self) -> NDArray[np.float64]:
117
+ """
118
+ Compute the velocity law residual partial derivative for ``accel``
119
+
120
+ :return: the partial derivative for accel
121
+ :rtype: NDArray[np.float64]
122
+ """
123
+ return np.array(
124
+ [
125
+ -(0.5 + self.scheme_ts_hht.current),
126
+ -np.power(self.scheme_ts_hht.current, 2) * self.time.dt * 0.25,
127
+ ],
128
+ )
129
+
130
+ def velocity_law_residual_dvel(self) -> NDArray[np.float64]:
131
+ """
132
+ Compute the velocity law residual partial derivative for ``vel``
133
+
134
+ :return: the partial derivative for vel
135
+ :rtype: NDArray[np.float64]
136
+ """
137
+ return np.array(
138
+ [self.time.inv_dt, -0.5],
139
+ )
140
+
141
+ def velocity_law_residual_ddisp(self) -> NDArray[np.float64]:
142
+ """
143
+ Compute the velocity law residual partial derivative for ``disp``
144
+
145
+ :return: the partial derivative for disp
146
+ :rtype: NDArray[np.float64]
147
+ """
148
+ return np.array(
149
+ [0.0, self.time.inv_dt],
150
+ )
151
+
152
+
153
+ # Define the residual expression of the velocity law and its partial derivatives
154
+ _velocity_law_hht_expression = Expression(
155
+ 2,
156
+ VelocityLawHHTModelComponent.velocity_law_residual,
157
+ {
158
+ "accel": VelocityLawHHTModelComponent.velocity_law_residual_daccel,
159
+ "vel": VelocityLawHHTModelComponent.velocity_law_residual_dvel,
160
+ "disp": VelocityLawHHTModelComponent.velocity_law_residual_ddisp,
161
+ },
162
+ )
163
+
164
+ VelocityLawHHTModelComponent.declares_internal_expression(
165
+ "vel", _velocity_law_hht_expression, 1, 0
166
+ )
167
+ VelocityLawHHTModelComponent.declares_internal_expression(
168
+ "accel", _velocity_law_hht_expression, 1, 1
169
+ )
@@ -0,0 +1,24 @@
1
+ {
2
+ "type": "circulation_alone_forward_simulation",
3
+ "time": {
4
+ "start": 0.0,
5
+ "duration": 25.0
6
+ },
7
+ "variables_initialization": {
8
+ "aorta_proximal.blood_pressure": 10760.0,
9
+ "aorta_distal.blood_pressure": 10760.0
10
+ },
11
+ "parameters": {
12
+ "heart_rate": 60.0, // in beats / min
13
+ "aorta_proximal.resistance": 7.0e6,
14
+ "aorta_distal.resistance": 1.1e8,
15
+ "aorta_distal.time_constant": 2.0,
16
+ "venous.blood_pressure": 1600.0,
17
+ "aorta_proximal.blood_flow.min": 0.0,
18
+ "aorta_proximal.blood_flow.max": 0.5e-3
19
+
20
+ },
21
+ "output_functions":{
22
+ "aorta_proximal.blood_flow": {"type": "watch_quantity", "quantity": "aorta_proximal.blood_flow"}
23
+ }
24
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "type": "spherical_heart_with_respiration_forward_simulation",
3
+ "time": {
4
+ "start": 0.0,
5
+ "duration": 25.0
6
+ },
7
+ "variables_initialization": {
8
+ "cavity.blood_pressure": "atrial.blood_pressure.max", // Initialization with an open atrial valve
9
+ "aorta_proximal.blood_pressure": 10760.0,
10
+ "aorta_distal.blood_pressure": 10760.0
11
+ },
12
+ "parameters": {
13
+ "heart_radius": 0.0340, // in m
14
+ "heart_thickness": 0.0113, // in m
15
+ "heart_contractility": 90000.0,
16
+ "heart_rate": 60.0, // in beats / min
17
+ "respiration.period": 5.0, // in seconds
18
+ "venous.blood_pressure": 1600.0,
19
+ "atrial.blood_pressure.min": 450.0,
20
+ "atrial.blood_pressure.max": 900.0,
21
+ "pleural.pressure.min": 0.0,
22
+ "pleural.pressure.max": 300.0,
23
+ "circulation_aorta_proximal.resistance": 7.0e6,
24
+ "circulation_aorta_distal.resistance": 1.1e8,
25
+ "circulation_aorta_distal.time_constant": 2.0,
26
+ "cavity.dynamics.hyperelastic_cst": [444.0, 2.9, 69.0, 6.5]
27
+ },
28
+ "output_functions": {
29
+ "atrial.blood_pressure": {"type": "watch_quantity", "quantity": "atrial.blood_pressure"},
30
+ "active_law.activation": {"type": "watch_quantity", "quantity": "cavity.rheology.active_law.activation"},
31
+ "pleural.pressure": {"type": "watch_quantity", "quantity": "pleural.pressure"}
32
+ }
33
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "type": "spherical_heart_forward_simulation",
3
+ "time": {
4
+ "start": 0.0,
5
+ "duration": 25.0
6
+ },
7
+ "variables_initialization": {
8
+ "cavity.blood_pressure": "atrial.blood_pressure.max", // Initialization with an open atrial valve
9
+ "aorta_proximal.blood_pressure": 10760.0,
10
+ "aorta_distal.blood_pressure": 10760.0
11
+ },
12
+ "parameters": {
13
+ "heart_radius": 0.0340,
14
+ "heart_thickness": 0.0113,
15
+ "heart_contractility": 90000.0,
16
+ "heart_rate": 60.0, // in beats / min
17
+ "venous.blood_pressure": 1600.0,
18
+ "atrial.blood_pressure.min": 450.0,
19
+ "atrial.blood_pressure.max": 900.0,
20
+ "circulation_aorta_proximal.resistance": 7.0e6,
21
+ "circulation_aorta_distal.resistance": 1.1e8,
22
+ "circulation_aorta_distal.time_constant": 2.0,
23
+ "cavity.dynamics.hyperelastic_cst": [444.0, 2.9, 69.0, 6.5]
24
+ },
25
+ "output_functions": {
26
+ "atrial.blood_pressure": {"type": "watch_quantity", "quantity": "atrial.blood_pressure"},
27
+ "active_law.activation": {"type": "watch_quantity", "quantity": "cavity.rheology.active_law.activation"}
28
+ }
29
+ }
@@ -0,0 +1,32 @@
1
+ # SPDX-FileCopyrightText: Copyright INRIA
2
+ #
3
+ # SPDX-License-Identifier: LGPL-3.0-only
4
+ #
5
+ # Copyright INRIA
6
+ #
7
+ # This file is part of PhysioBlocks, a library mostly developed by the
8
+ # [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
9
+ #
10
+ # Authors:
11
+ # - Colin Drieu
12
+ # - Dominique Chapelle
13
+ # - François Kimmig
14
+ # - Philippe Moireau
15
+ #
16
+ # PhysioBlocks is free software: you can redistribute it and/or modify it under the
17
+ # terms of the GNU Lesser General Public License as published by the Free Software
18
+ # Foundation, version 3 of the License.
19
+ #
20
+ # PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
21
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
+ # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
23
+ #
24
+ # You should have received a copy of the GNU Lesser General Public License along with
25
+ # PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
26
+
27
+ """
28
+ Defines functions to access registers
29
+ """
30
+
31
+ __all__ = ["register_type"]
32
+ from physioblocks.registers.type_register import register_type
@@ -0,0 +1,93 @@
1
+ # SPDX-FileCopyrightText: Copyright INRIA
2
+ #
3
+ # SPDX-License-Identifier: LGPL-3.0-only
4
+ #
5
+ # Copyright INRIA
6
+ #
7
+ # This file is part of PhysioBlocks, a library mostly developed by the
8
+ # [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
9
+ #
10
+ # Authors:
11
+ # - Colin Drieu
12
+ # - Dominique Chapelle
13
+ # - François Kimmig
14
+ # - Philippe Moireau
15
+ #
16
+ # PhysioBlocks is free software: you can redistribute it and/or modify it under the
17
+ # terms of the GNU Lesser General Public License as published by the Free Software
18
+ # Foundation, version 3 of the License.
19
+ #
20
+ # PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
21
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
+ # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
23
+ #
24
+ # You should have received a copy of the GNU Lesser General Public License along with
25
+ # PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
26
+
27
+ """
28
+ Define decorators to register any function as a specific load function
29
+ of a configuration object.
30
+ """
31
+
32
+ from collections.abc import Callable
33
+ from typing import Any, TypeVar
34
+
35
+ from physioblocks.base.registers import register
36
+
37
+ __load_functions_register: dict[type, Callable[..., Any]] = {}
38
+
39
+
40
+ T = TypeVar("T")
41
+
42
+
43
+ def loads(
44
+ loaded_type: type[T],
45
+ ) -> Callable[[Callable[..., T]], Callable[..., T]]:
46
+ """
47
+ Decorator to register a method that loads a registered type.
48
+
49
+ :param loaded_type: the loaded type
50
+ :type loaded_type: str
51
+
52
+ :return: the class decorator
53
+ :rtype: Callable
54
+ """
55
+
56
+ def register_decorator(load_function: Callable[..., T]) -> Callable[..., T]:
57
+ register(__load_functions_register, loaded_type, load_function)
58
+ return load_function
59
+
60
+ return register_decorator
61
+
62
+
63
+ def get_load_function(loaded_type: type) -> Callable[..., Any]:
64
+ """
65
+ Get a registered load function.
66
+
67
+ :param type_id: the registered type id
68
+ :type type_id: str
69
+
70
+ :raise KeyError: Raises a key error if the type is not registered.
71
+
72
+ :return: the registered type
73
+ :rtype: type
74
+ """
75
+ key_type = _get_closest_type(loaded_type)
76
+
77
+ if key_type is None:
78
+ raise KeyError(
79
+ str.format(
80
+ "No load function registered for type {0}",
81
+ loaded_type.__name__,
82
+ )
83
+ )
84
+ return __load_functions_register[key_type]
85
+
86
+
87
+ def _get_closest_type(searched_type: type | None) -> None | type:
88
+ if searched_type is None:
89
+ return None
90
+ elif searched_type in __load_functions_register:
91
+ return searched_type
92
+ else:
93
+ return _get_closest_type(searched_type.__base__)
@@ -0,0 +1,106 @@
1
+ # SPDX-FileCopyrightText: Copyright INRIA
2
+ #
3
+ # SPDX-License-Identifier: LGPL-3.0-only
4
+ #
5
+ # Copyright INRIA
6
+ #
7
+ # This file is part of PhysioBlocks, a library mostly developed by the
8
+ # [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
9
+ #
10
+ # Authors:
11
+ # - Colin Drieu
12
+ # - Dominique Chapelle
13
+ # - François Kimmig
14
+ # - Philippe Moireau
15
+ #
16
+ # PhysioBlocks is free software: you can redistribute it and/or modify it under the
17
+ # terms of the GNU Lesser General Public License as published by the Free Software
18
+ # Foundation, version 3 of the License.
19
+ #
20
+ # PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
21
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
+ # PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
23
+ #
24
+ # You should have received a copy of the GNU Lesser General Public License along with
25
+ # PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
26
+
27
+ """
28
+ Define decorators to register any function as a specific save function
29
+ of a configuration object.
30
+ """
31
+
32
+ from collections.abc import Callable
33
+ from typing import Any
34
+
35
+ from physioblocks.base.registers import register
36
+
37
+ __save_functions_register: dict[type, Callable[..., Any]] = {}
38
+
39
+
40
+ def saves(
41
+ saved_type: type,
42
+ ) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
43
+ """
44
+ Decorator to register a method that saves a registered type.
45
+
46
+ :param saved_type: the saved type by the method
47
+ :type saved_type: str
48
+
49
+ :return: the class decorator
50
+ :rtype: Callable
51
+ """
52
+
53
+ def register_decorator(
54
+ save_function: Callable[..., Any],
55
+ ) -> Callable[..., Any]:
56
+ register(__save_functions_register, saved_type, save_function)
57
+ return save_function
58
+
59
+ return register_decorator
60
+
61
+
62
+ def has_save_function(key: type) -> bool:
63
+ """
64
+ Check if the type has a save function
65
+
66
+ :param key: the key to test
67
+ :type key: Any
68
+
69
+ :return: True if the key is registered, False otherwise
70
+ :rtype: bool
71
+ """
72
+ key_type = _get_closest_type(key)
73
+ return key_type in __save_functions_register
74
+
75
+
76
+ def get_save_function(saved_type: type) -> Callable[..., Any]:
77
+ """
78
+ Get a registered save function.
79
+
80
+ :param type_id: the registered type id
81
+ :type type_id: str
82
+
83
+ :raise KeyError: Raises a key error if the type is not registered.
84
+
85
+ :return: the registered type
86
+ :rtype: type
87
+ """
88
+ key_type = _get_closest_type(saved_type)
89
+
90
+ if key_type is None:
91
+ raise KeyError(
92
+ str.format(
93
+ "No save function registered for type {0}",
94
+ saved_type.__name__,
95
+ )
96
+ )
97
+ return __save_functions_register[key_type]
98
+
99
+
100
+ def _get_closest_type(searched_type: type | None) -> None | type:
101
+ if searched_type is None:
102
+ return None
103
+ elif searched_type in __save_functions_register:
104
+ return searched_type
105
+ else:
106
+ return _get_closest_type(searched_type.__base__)