libcuflynx 0.4.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.
- checks/__init__.py +11 -0
- emulators/__init__.py +11 -0
- generators/__init__.py +11 -0
- libcuflynx/__init__.py +1 -0
- libcuflynx/_deprecated_aliases.py +229 -0
- libcuflynx/checks/LumpedModelChecks.py +112 -0
- libcuflynx/checks/__init__.py +1 -0
- libcuflynx/coupler/__init__.py +1 -0
- libcuflynx/emulators/__init__.py +32 -0
- libcuflynx/emulators/emulator_bundle.py +426 -0
- libcuflynx/emulators/emulator_trainer.py +675 -0
- libcuflynx/funcs/__init__.py +19 -0
- libcuflynx/funcs/cost_funcs_user.py +269 -0
- libcuflynx/funcs/modifier_funcs_user.py +43 -0
- libcuflynx/funcs/operation_funcs_user.py +727 -0
- libcuflynx/generators/CVSCellMLGenerator.py +2591 -0
- libcuflynx/generators/CVSCppGenerator.py +3849 -0
- libcuflynx/generators/Python1DModelFilesGenerator.py +741 -0
- libcuflynx/generators/PythonGenerator.py +755 -0
- libcuflynx/generators/__init__.py +0 -0
- libcuflynx/generators/cppGeneratorTemplateFunctions.cpp +360 -0
- libcuflynx/generators/main0dTemplate.cpp +193 -0
- libcuflynx/generators/resources/BG_modules.cellml +21043 -0
- libcuflynx/generators/resources/BG_modules_config.json +19569 -0
- libcuflynx/generators/resources/FitzHugh_Nagumo_module_config.json +56 -0
- libcuflynx/generators/resources/FitzHugh_Nagumo_modules.cellml +73 -0
- libcuflynx/generators/resources/Lotka_Volterra_module_config.json +22 -0
- libcuflynx/generators/resources/Lotka_Volterra_modules.cellml +64 -0
- libcuflynx/generators/resources/TwoMinima_module_config.json +38 -0
- libcuflynx/generators/resources/TwoMinima_modules.cellml +35 -0
- libcuflynx/generators/resources/VanDerPol_module_config.json +19 -0
- libcuflynx/generators/resources/VanDerPol_modules.cellml +55 -0
- libcuflynx/generators/resources/base_script.cellml +13 -0
- libcuflynx/generators/resources/boundary_condition_modules.cellml +592 -0
- libcuflynx/generators/resources/boundary_condition_modules_config.json +234 -0
- libcuflynx/generators/resources/cell_modules.cellml +6209 -0
- libcuflynx/generators/resources/cell_modules_config.json +834 -0
- libcuflynx/generators/resources/control_modules.cellml +2481 -0
- libcuflynx/generators/resources/control_modules_config.json +783 -0
- libcuflynx/generators/resources/control_system_modules.cellml +114 -0
- libcuflynx/generators/resources/control_system_modules_config.json +45 -0
- libcuflynx/generators/resources/coupling_modules.cellml +103 -0
- libcuflynx/generators/resources/coupling_modules_config.json +241 -0
- libcuflynx/generators/resources/delay_modules.cellml +80 -0
- libcuflynx/generators/resources/delay_modules_config.json +29 -0
- libcuflynx/generators/resources/diffusion_volume_modules.cellml +234 -0
- libcuflynx/generators/resources/diffusion_volume_modules_config.json +70 -0
- libcuflynx/generators/resources/elic_modules.cellml +1165 -0
- libcuflynx/generators/resources/elic_modules_config.json +147 -0
- libcuflynx/generators/resources/gas_exchange_modules.cellml +4130 -0
- libcuflynx/generators/resources/gas_exchange_modules_config.json +561 -0
- libcuflynx/generators/resources/heart_modules.cellml +11528 -0
- libcuflynx/generators/resources/heart_modules_config.json +1040 -0
- libcuflynx/generators/resources/input_stimulation_modules.cellml +184 -0
- libcuflynx/generators/resources/input_stimulation_modules_config.json +83 -0
- libcuflynx/generators/resources/ion_channel_modules.cellml +4268 -0
- libcuflynx/generators/resources/ion_channel_modules_config.json +1210 -0
- libcuflynx/generators/resources/lung_modules.cellml +2477 -0
- libcuflynx/generators/resources/lung_modules_config.json +270 -0
- libcuflynx/generators/resources/open_loop_modules.cellml +4552 -0
- libcuflynx/generators/resources/open_loop_modules_config.json +165 -0
- libcuflynx/generators/resources/parasympathetic_modules.cellml +1444 -0
- libcuflynx/generators/resources/parasympathetic_modules_config.json +623 -0
- libcuflynx/generators/resources/test_modules.cellml +143 -0
- libcuflynx/generators/resources/test_modules_config.json +115 -0
- libcuflynx/generators/resources/units.cellml +625 -0
- libcuflynx/generators/resources/vessel_properties_modules.cellml +687 -0
- libcuflynx/generators/resources/vessel_properties_modules_config.json +313 -0
- libcuflynx/identifiabilty_analysis/__init__.py +1 -0
- libcuflynx/identifiabilty_analysis/identifiabilityAnalysis.py +442 -0
- libcuflynx/models/LumpedModels.py +27 -0
- libcuflynx/models/__init__.py +0 -0
- libcuflynx/param_id/__init__.py +1 -0
- libcuflynx/param_id/aadc_backend.py +1038 -0
- libcuflynx/param_id/casadi_backend.py +350 -0
- libcuflynx/param_id/cost_kwargs.py +209 -0
- libcuflynx/param_id/differentiable.py +70 -0
- libcuflynx/param_id/external_funcs.py +99 -0
- libcuflynx/param_id/fd_backend.py +173 -0
- libcuflynx/param_id/fsa_backend.py +395 -0
- libcuflynx/param_id/math_backend.py +209 -0
- libcuflynx/param_id/modifier_funcs.py +155 -0
- libcuflynx/param_id/operation_funcs.py +340 -0
- libcuflynx/param_id/optimisers.py +1897 -0
- libcuflynx/param_id/paramID.py +4435 -0
- libcuflynx/param_id/plot_outputs.py +1268 -0
- libcuflynx/param_id/pymc_backend.py +382 -0
- libcuflynx/param_id/run_history.py +261 -0
- libcuflynx/parsers/ModelParsers.py +613 -0
- libcuflynx/parsers/OMEXParsers.py +421 -0
- libcuflynx/parsers/PrimitiveParsers.py +4487 -0
- libcuflynx/parsers/__init__.py +0 -0
- libcuflynx/protocol_runners/__init__.py +11 -0
- libcuflynx/protocol_runners/protocol_executor.py +196 -0
- libcuflynx/protocol_runners/protocol_runner.py +226 -0
- libcuflynx/scripts/__init__.py +1 -0
- libcuflynx/scripts/_cli.py +99 -0
- libcuflynx/scripts/convert_0d_to_1d.py +148 -0
- libcuflynx/scripts/example_data/example_data_for_conversion.csv +1802 -0
- libcuflynx/scripts/example_format_obs_data_json_file.py +119 -0
- libcuflynx/scripts/generate_modules_files.py +479 -0
- libcuflynx/scripts/generate_obs_json.py +72 -0
- libcuflynx/scripts/generate_omex_analysis_script.py +337 -0
- libcuflynx/scripts/heart_paper_plots.py +483 -0
- libcuflynx/scripts/identifiability_run_script.py +96 -0
- libcuflynx/scripts/param_id_run_script.py +180 -0
- libcuflynx/scripts/plot_param_id_script.py +171 -0
- libcuflynx/scripts/read_and_insert_parameters.py +75 -0
- libcuflynx/scripts/run_multiple_param_id.py +188 -0
- libcuflynx/scripts/script_generate_with_new_architecture.py +293 -0
- libcuflynx/scripts/sensitivity_analysis_run_script.py +47 -0
- libcuflynx/scripts/sequential_param_id_run_script.py +138 -0
- libcuflynx/scripts/train_emulator_run_script.py +66 -0
- libcuflynx/sensitivity_analysis/__init__.py +1 -0
- libcuflynx/sensitivity_analysis/sensitivityAnalysis.py +492 -0
- libcuflynx/sensitivity_analysis/sobolSA.py +884 -0
- libcuflynx/solver1d/Make_files/Makefile +46 -0
- libcuflynx/solver1d/Make_files/MakefilePETSC +59 -0
- libcuflynx/solver1d/Make_files/runCVODE.bash +15 -0
- libcuflynx/solver1d/Make_files/runPETSc.bash +11 -0
- libcuflynx/solver1d/__init__.py +1 -0
- libcuflynx/solver1d/auxCouplingFunctions.py +891 -0
- libcuflynx/solver1d/auxPipeFunctions.py +95 -0
- libcuflynx/solver1d/bcs.py +59 -0
- libcuflynx/solver1d/main1D.py +1441 -0
- libcuflynx/solver1d/model.py +2430 -0
- libcuflynx/solver1d/numerics.py +604 -0
- libcuflynx/solver1d/vessel.py +206 -0
- libcuflynx/solver1d/windkessel.py +699 -0
- libcuflynx/solver_wrappers/__init__.py +302 -0
- libcuflynx/solver_wrappers/aadc_python_solver_helper.py +1787 -0
- libcuflynx/solver_wrappers/casadi_python_solver_helper.py +839 -0
- libcuflynx/solver_wrappers/emulator_solver_helper.py +322 -0
- libcuflynx/solver_wrappers/external_simulation_helper.py +591 -0
- libcuflynx/solver_wrappers/myokit_helper.py +1528 -0
- libcuflynx/solver_wrappers/name_resolver.py +184 -0
- libcuflynx/solver_wrappers/opencor_helper.py +387 -0
- libcuflynx/solver_wrappers/param_grouping.py +56 -0
- libcuflynx/solver_wrappers/python_solver_helper.py +457 -0
- libcuflynx/utilities/__init__.py +0 -0
- libcuflynx/utilities/casadi_solver_diagnostics.py +378 -0
- libcuflynx/utilities/diagnostics.py +117 -0
- libcuflynx/utilities/elic_run.py +56 -0
- libcuflynx/utilities/libcellml_helper_funcs.py +160 -0
- libcuflynx/utilities/libcellml_utilities.py +271 -0
- libcuflynx/utilities/mpi_utils.py +362 -0
- libcuflynx/utilities/obs_data_helpers.py +265 -0
- libcuflynx/utilities/package_resources.py +117 -0
- libcuflynx/utilities/paperPlotSetup.py +60 -0
- libcuflynx/utilities/params_for_id_helpers.py +79 -0
- libcuflynx/utilities/paths.py +145 -0
- libcuflynx/utilities/plot_generated_model_outputs.py +79 -0
- libcuflynx/utilities/protocol_funcs.py +98 -0
- libcuflynx/utilities/protocol_shapes.py +435 -0
- libcuflynx/utilities/stat_distributions.py +35 -0
- libcuflynx/utilities/utility_funcs.py +528 -0
- libcuflynx-0.4.0.dist-info/METADATA +266 -0
- libcuflynx-0.4.0.dist-info/RECORD +170 -0
- libcuflynx-0.4.0.dist-info/WHEEL +5 -0
- libcuflynx-0.4.0.dist-info/entry_points.txt +8 -0
- libcuflynx-0.4.0.dist-info/licenses/LICENSE +204 -0
- libcuflynx-0.4.0.dist-info/top_level.txt +12 -0
- models/__init__.py +11 -0
- param_id/__init__.py +11 -0
- parsers/__init__.py +11 -0
- protocol_runners/__init__.py +11 -0
- scripts/__init__.py +11 -0
- sensitivity_analysis/__init__.py +11 -0
- solver_wrappers/__init__.py +11 -0
- utilities/__init__.py +11 -0
checks/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Deprecated alias for :mod:`libcuflynx.checks`, removed in 0.5.0.
|
|
2
|
+
|
|
3
|
+
Importing this name emits a single ``DeprecationWarning`` and then hands back the real
|
|
4
|
+
``libcuflynx.checks`` package -- the same module object, not a copy -- so that
|
|
5
|
+
``isinstance`` checks and monkeypatching against classes reached through the old name
|
|
6
|
+
keep working. See ``libcuflynx/_deprecated_aliases.py`` for how, and why it takes a
|
|
7
|
+
meta path finder to make ``import checks.<submodule>`` identical too.
|
|
8
|
+
"""
|
|
9
|
+
from libcuflynx._deprecated_aliases import install_shim
|
|
10
|
+
|
|
11
|
+
install_shim(__name__)
|
emulators/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Deprecated alias for :mod:`libcuflynx.emulators`, removed in 0.5.0.
|
|
2
|
+
|
|
3
|
+
Importing this name emits a single ``DeprecationWarning`` and then hands back the real
|
|
4
|
+
``libcuflynx.emulators`` package -- the same module object, not a copy -- so that
|
|
5
|
+
``isinstance`` checks and monkeypatching against classes reached through the old name
|
|
6
|
+
keep working. See ``libcuflynx/_deprecated_aliases.py`` for how, and why it takes a
|
|
7
|
+
meta path finder to make ``import emulators.<submodule>`` identical too.
|
|
8
|
+
"""
|
|
9
|
+
from libcuflynx._deprecated_aliases import install_shim
|
|
10
|
+
|
|
11
|
+
install_shim(__name__)
|
generators/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Deprecated alias for :mod:`libcuflynx.generators`, removed in 0.5.0.
|
|
2
|
+
|
|
3
|
+
Importing this name emits a single ``DeprecationWarning`` and then hands back the real
|
|
4
|
+
``libcuflynx.generators`` package -- the same module object, not a copy -- so that
|
|
5
|
+
``isinstance`` checks and monkeypatching against classes reached through the old name
|
|
6
|
+
keep working. See ``libcuflynx/_deprecated_aliases.py`` for how, and why it takes a
|
|
7
|
+
meta path finder to make ``import generators.<submodule>`` identical too.
|
|
8
|
+
"""
|
|
9
|
+
from libcuflynx._deprecated_aliases import install_shim
|
|
10
|
+
|
|
11
|
+
install_shim(__name__)
|
libcuflynx/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""libcuflynx — generation, simulation, calibration and analysis of CellML physiology models."""
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"""Machinery behind the deprecated flat top-level import names.
|
|
2
|
+
|
|
3
|
+
Before the rename every module in this project sat at the top level of ``src/`` and was
|
|
4
|
+
reached with a ``sys.path.insert(0, 'src')`` followed by ``from param_id.paramID import
|
|
5
|
+
CVS0DParamID``. 0.4.0 moved all of it under :mod:`libcuflynx`. The shim packages in
|
|
6
|
+
``src/<name>/`` keep the old spellings working for exactly one release; they are removed
|
|
7
|
+
in 0.5.0 (see :data:`REMOVAL_VERSION`).
|
|
8
|
+
|
|
9
|
+
Object identity is the whole difficulty
|
|
10
|
+
---------------------------------------
|
|
11
|
+
``param_id.paramID.CVS0DParamID`` has to *be* ``libcuflynx.param_id.paramID.CVS0DParamID``,
|
|
12
|
+
not a second class object that happens to have the same source. Otherwise user code that
|
|
13
|
+
did ``isinstance(x, CVS0DParamID)`` against the old name, or monkeypatched an attribute on
|
|
14
|
+
it, silently stops matching the object the package itself uses -- the worst kind of
|
|
15
|
+
deprecation, one that does not raise.
|
|
16
|
+
|
|
17
|
+
A shim written as ``from libcuflynx.param_id import *`` fails that: it creates a second
|
|
18
|
+
module object and copies references into it, so ``param_id.paramID`` is a different module
|
|
19
|
+
from ``libcuflynx.param_id.paramID`` even though the classes inside happen to be shared,
|
|
20
|
+
and anything imported lazily or added later is simply absent.
|
|
21
|
+
|
|
22
|
+
Nor is ``sys.modules['param_id'] = libcuflynx.param_id`` enough on its own. That fixes the
|
|
23
|
+
package object, but the *submodules* are then resolved through that package's ``__path__``
|
|
24
|
+
by the ordinary path finder, which loads ``paramID.py`` a second time under the name
|
|
25
|
+
``param_id.paramID`` -- a genuinely distinct module holding a genuinely distinct
|
|
26
|
+
``CVS0DParamID``.
|
|
27
|
+
|
|
28
|
+
So the shim does both:
|
|
29
|
+
|
|
30
|
+
1. :class:`_AliasFinder` goes on ``sys.meta_path``. ``sys.meta_path`` is consulted before
|
|
31
|
+
the parent package's ``__path__``, so the finder gets first refusal on *submodules* of
|
|
32
|
+
a root that was aliased and answers with a loader that hands back the module that is
|
|
33
|
+
*already* imported under its ``libcuflynx.`` name rather than loading anything.
|
|
34
|
+
2. :func:`install_shim` rebinds ``sys.modules[<root>]`` to the real package, and is the
|
|
35
|
+
one-line body of each ``src/<root>/__init__.py``. Those directories exist so that the
|
|
36
|
+
old names are found at all (and so setuptools' ``packages.find`` ships them); the
|
|
37
|
+
finder they install is what makes everything below them resolve correctly.
|
|
38
|
+
|
|
39
|
+
Scope: the finder claims as little as it can get away with
|
|
40
|
+
----------------------------------------------------------
|
|
41
|
+
``SHIM_ROOTS`` is eleven very ordinary words -- ``models``, ``scripts``, ``utilities``,
|
|
42
|
+
``checks``. A finder at ``sys.meta_path[0]`` that answered for any name whose root is in
|
|
43
|
+
that set would mean that importing *one* shim rebinds all eleven process-wide, so a
|
|
44
|
+
downstream project with its own ``utilities.py`` on ``sys.path`` would silently get ours
|
|
45
|
+
from the moment anything did ``import param_id``. Nothing announces that; it is the same
|
|
46
|
+
class of failure the identity work above exists to prevent.
|
|
47
|
+
|
|
48
|
+
So :meth:`_AliasFinder.find_spec` declines twice over. It declines the *root* name, because
|
|
49
|
+
the physical ``src/<root>/__init__.py`` shim is the correct resolver for it and the ordinary
|
|
50
|
+
path finder locates that -- respecting whatever else is earlier on ``sys.path``. And it
|
|
51
|
+
declines a submodule whose root was not actually aliased in this process, which is the only
|
|
52
|
+
case where first refusal is needed at all.
|
|
53
|
+
|
|
54
|
+
Exactly one :exc:`DeprecationWarning` is emitted per shim root per process -- not one per
|
|
55
|
+
attribute access and not one per submodule -- because :func:`_warn_once` records the roots
|
|
56
|
+
it has already warned about.
|
|
57
|
+
"""
|
|
58
|
+
import importlib
|
|
59
|
+
import importlib.util
|
|
60
|
+
import sys
|
|
61
|
+
import warnings
|
|
62
|
+
from importlib.machinery import ModuleSpec
|
|
63
|
+
|
|
64
|
+
#: Release that deletes these shims. 0.3.0 is already published, the rename ships in
|
|
65
|
+
#: 0.4.0, so users get the whole of 0.4.x to migrate. Stated in the warning text; keep the
|
|
66
|
+
#: release notes saying the same number.
|
|
67
|
+
REMOVAL_VERSION = "0.5.0"
|
|
68
|
+
|
|
69
|
+
#: The package the flat names now live in.
|
|
70
|
+
PACKAGE = "libcuflynx"
|
|
71
|
+
|
|
72
|
+
#: The flat top-level names that used to be importable. Every one of these has a matching
|
|
73
|
+
#: ``src/<name>/__init__.py`` shim and a matching ``src/libcuflynx/<name>/`` package.
|
|
74
|
+
#: Deliberately not the full list of subpackages: ``coupler``, ``solver1d``,
|
|
75
|
+
#: ``identifiabilty_analysis`` and ``obsolete`` were never imported flat by user code.
|
|
76
|
+
SHIM_ROOTS = frozenset({
|
|
77
|
+
"checks",
|
|
78
|
+
"emulators",
|
|
79
|
+
"generators",
|
|
80
|
+
"models",
|
|
81
|
+
"param_id",
|
|
82
|
+
"parsers",
|
|
83
|
+
"protocol_runners",
|
|
84
|
+
"scripts",
|
|
85
|
+
"sensitivity_analysis",
|
|
86
|
+
"solver_wrappers",
|
|
87
|
+
"utilities",
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
# Roots already warned about in this process.
|
|
91
|
+
_warned = set()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _warn_once(root):
|
|
95
|
+
"""Emit the deprecation warning for ``root``, at most once per process."""
|
|
96
|
+
if root in _warned:
|
|
97
|
+
return
|
|
98
|
+
_warned.add(root)
|
|
99
|
+
warnings.warn(
|
|
100
|
+
"`{root}` is now `{pkg}.{root}`; this shim is removed in {version}. "
|
|
101
|
+
"Import `{pkg}.{root}` instead.".format(
|
|
102
|
+
root=root, pkg=PACKAGE, version=REMOVAL_VERSION
|
|
103
|
+
),
|
|
104
|
+
DeprecationWarning,
|
|
105
|
+
# The importing frame is buried under importlib's bookkeeping, so no stacklevel
|
|
106
|
+
# points reliably at the user's import statement. The message names the module.
|
|
107
|
+
stacklevel=3,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _reset_warnings():
|
|
112
|
+
"""Forget which roots have been warned about. For tests only."""
|
|
113
|
+
_warned.clear()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class _AliasLoader:
|
|
117
|
+
"""Loader that "loads" an alias name by handing back an already-imported module.
|
|
118
|
+
|
|
119
|
+
``create_module`` returning an existing module object is exactly what makes the alias
|
|
120
|
+
identical to the real thing rather than a copy of it.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
def __init__(self, real_name):
|
|
124
|
+
self._real_name = real_name
|
|
125
|
+
self._real_spec = None
|
|
126
|
+
|
|
127
|
+
def create_module(self, spec):
|
|
128
|
+
module = importlib.import_module(self._real_name)
|
|
129
|
+
# importlib.util.module_from_spec() overwrites __spec__ unconditionally (unlike
|
|
130
|
+
# __name__/__loader__/__package__/__path__/__file__, which it leaves alone on an
|
|
131
|
+
# already-initialised module). Left as-is, the real module would end up claiming
|
|
132
|
+
# the alias name in its own spec, which breaks importlib.reload() and misleads
|
|
133
|
+
# anything that introspects it. Stash it and put it back in exec_module().
|
|
134
|
+
self._real_spec = getattr(module, "__spec__", None)
|
|
135
|
+
return module
|
|
136
|
+
|
|
137
|
+
def exec_module(self, module):
|
|
138
|
+
# Nothing to execute: the module body ran when it was first imported under its
|
|
139
|
+
# real name, and running it again would create fresh class objects -- the very
|
|
140
|
+
# thing this shim exists to avoid.
|
|
141
|
+
if self._real_spec is not None:
|
|
142
|
+
module.__spec__ = self._real_spec
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class _AliasFinder:
|
|
146
|
+
"""Resolve ``<root>[.<sub>...]`` to the already-imported ``libcuflynx.<root>...``."""
|
|
147
|
+
|
|
148
|
+
def find_spec(self, fullname, path=None, target=None):
|
|
149
|
+
root, dot, _ = fullname.partition(".")
|
|
150
|
+
if root not in SHIM_ROOTS:
|
|
151
|
+
return None
|
|
152
|
+
if not dot:
|
|
153
|
+
# The root itself. Declining is not a gap: the physical ``src/<root>/__init__.py``
|
|
154
|
+
# shim is found by the ordinary path finder and calls install_shim() itself, so
|
|
155
|
+
# ``import parsers`` still resolves to ``libcuflynx.parsers``. Claiming it here
|
|
156
|
+
# instead would mean that importing *one* shim silently rebinds all eleven names
|
|
157
|
+
# process-wide -- ``models``, ``scripts``, ``utilities``, ``checks`` are generic
|
|
158
|
+
# enough that a downstream project has its own, and it would get ours.
|
|
159
|
+
return None
|
|
160
|
+
if not self._root_is_aliased(root):
|
|
161
|
+
# A submodule of a root this process never aliased. Someone else's ``models``
|
|
162
|
+
# package with a ``models.io`` inside it is theirs, not ours; only the path
|
|
163
|
+
# finder can know where it lives.
|
|
164
|
+
return None
|
|
165
|
+
real_name = PACKAGE + "." + fullname
|
|
166
|
+
try:
|
|
167
|
+
real_spec = importlib.util.find_spec(real_name)
|
|
168
|
+
except (ImportError, AttributeError, ValueError):
|
|
169
|
+
# No such module under libcuflynx (or its parent is not a package). Decline,
|
|
170
|
+
# so the ordinary finders produce the ordinary ModuleNotFoundError.
|
|
171
|
+
return None
|
|
172
|
+
if real_spec is None:
|
|
173
|
+
return None
|
|
174
|
+
_warn_once(root)
|
|
175
|
+
return ModuleSpec(
|
|
176
|
+
fullname,
|
|
177
|
+
_AliasLoader(real_name),
|
|
178
|
+
origin=real_spec.origin,
|
|
179
|
+
is_package=real_spec.submodule_search_locations is not None,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
@staticmethod
|
|
183
|
+
def _root_is_aliased(root):
|
|
184
|
+
"""Did ``install_shim`` actually take ``root`` over in this process?
|
|
185
|
+
|
|
186
|
+
``sys.modules[root] is sys.modules['libcuflynx.' + root]`` is the state
|
|
187
|
+
:func:`install_shim` leaves behind and nothing else produces, so it answers the
|
|
188
|
+
question without a second piece of bookkeeping to keep in step. Both being absent
|
|
189
|
+
must not read as "yes", hence the explicit ``None`` check.
|
|
190
|
+
"""
|
|
191
|
+
real = sys.modules.get(PACKAGE + "." + root)
|
|
192
|
+
return real is not None and sys.modules.get(root) is real
|
|
193
|
+
|
|
194
|
+
def __repr__(self):
|
|
195
|
+
return "<{} for the pre-{} flat import names>".format(
|
|
196
|
+
type(self).__name__, PACKAGE
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def install_finder():
|
|
201
|
+
"""Put a single :class:`_AliasFinder` at the front of ``sys.meta_path``."""
|
|
202
|
+
for finder in sys.meta_path:
|
|
203
|
+
if isinstance(finder, _AliasFinder):
|
|
204
|
+
return finder
|
|
205
|
+
finder = _AliasFinder()
|
|
206
|
+
# Ahead of the path finder, so that a submodule of an aliased root is never loaded a
|
|
207
|
+
# second time off disk.
|
|
208
|
+
sys.meta_path.insert(0, finder)
|
|
209
|
+
return finder
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def install_shim(alias):
|
|
213
|
+
"""Body of every ``src/<alias>/__init__.py``.
|
|
214
|
+
|
|
215
|
+
Warns, installs the finder, and replaces the half-built shim module in
|
|
216
|
+
``sys.modules`` with the real package, so that ``import parsers`` yields
|
|
217
|
+
``libcuflynx.parsers`` itself.
|
|
218
|
+
"""
|
|
219
|
+
if alias not in SHIM_ROOTS:
|
|
220
|
+
raise ImportError(
|
|
221
|
+
"{!r} is not a deprecated {} import name".format(alias, PACKAGE)
|
|
222
|
+
)
|
|
223
|
+
install_finder()
|
|
224
|
+
_warn_once(alias)
|
|
225
|
+
real = importlib.import_module(PACKAGE + "." + alias)
|
|
226
|
+
# Rebinding sys.modules[__name__] from inside a module body is honoured by the import
|
|
227
|
+
# system: _load() re-reads sys.modules after exec_module() and returns what it finds.
|
|
228
|
+
sys.modules[alias] = real
|
|
229
|
+
return real
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'''
|
|
2
|
+
Created on 01/11/2021
|
|
3
|
+
@summary: Defines check routines for a lumped parameter model.
|
|
4
|
+
@author: Finbar Argus, Gonzalo D. Maso Talou
|
|
5
|
+
'''
|
|
6
|
+
|
|
7
|
+
from abc import ABC, abstractmethod
|
|
8
|
+
|
|
9
|
+
class AbstractLumpedCheck(ABC):
|
|
10
|
+
'''
|
|
11
|
+
Abstract class of a check condition
|
|
12
|
+
'''
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def execute(self,model_0D):
|
|
16
|
+
'''
|
|
17
|
+
Runs the check activities
|
|
18
|
+
:param model_0D: model to be checked.
|
|
19
|
+
'''
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class LumpedCompositeCheck(AbstractLumpedCheck):
|
|
23
|
+
'''
|
|
24
|
+
Class that performs multiple checks on a lumped parameter model
|
|
25
|
+
'''
|
|
26
|
+
|
|
27
|
+
def __init__(self, check_list=[]):
|
|
28
|
+
"""
|
|
29
|
+
Constructor
|
|
30
|
+
|
|
31
|
+
:param check_list: initial checking list.
|
|
32
|
+
"""
|
|
33
|
+
self.checks_list = check_list
|
|
34
|
+
|
|
35
|
+
def add_check(self,check):
|
|
36
|
+
'''
|
|
37
|
+
Adds an additional check to the checking list.
|
|
38
|
+
:param check: check to be added.
|
|
39
|
+
'''
|
|
40
|
+
self.checks_list.append(check)
|
|
41
|
+
|
|
42
|
+
def execute(self, model_0D):
|
|
43
|
+
'''
|
|
44
|
+
Executes all the checks in the checking list.
|
|
45
|
+
:param model_0D:
|
|
46
|
+
'''
|
|
47
|
+
for current_check in self.checks_list:
|
|
48
|
+
current_check.execute(model_0D)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class LumpedBCVesselCheck(AbstractLumpedCheck):
|
|
52
|
+
'''
|
|
53
|
+
Checks if the boundary conditions and vessel types are correct.
|
|
54
|
+
'''
|
|
55
|
+
|
|
56
|
+
def execute(self, model_0D):
|
|
57
|
+
'''
|
|
58
|
+
Executes all check activities.
|
|
59
|
+
:param model_0D: model to be checked.
|
|
60
|
+
'''
|
|
61
|
+
model_0D.vessels_df.apply(self.execute_for_row, args=(model_0D, ), axis=1)
|
|
62
|
+
|
|
63
|
+
def execute_for_row(self, vessel_row, model_0D):
|
|
64
|
+
if (vessel_row["vessel_type"], vessel_row["BC_type"]) not in model_0D.possible_vessel_BC_types:
|
|
65
|
+
print(f'vessel_type, BC_type combo of ({vessel_row["vessel_type"]}, {vessel_row["BC_type"]}) '
|
|
66
|
+
f'is not allowed for vessel {vessel_row["name"]}')
|
|
67
|
+
exit()
|
|
68
|
+
|
|
69
|
+
class LumpedIDParamsCheck(AbstractLumpedCheck):
|
|
70
|
+
'''
|
|
71
|
+
Checks if the boundary conditions and vessel types are correct.
|
|
72
|
+
'''
|
|
73
|
+
|
|
74
|
+
def execute(self, model_0D):
|
|
75
|
+
'''
|
|
76
|
+
Executes all check activities.
|
|
77
|
+
:param model_0D: model to be checked.
|
|
78
|
+
'''
|
|
79
|
+
for const_name, _ in model_0D.param_id_name_and_vals:
|
|
80
|
+
if not const_name in model_0D.parameters_array['variable_name']:
|
|
81
|
+
print(f'ERROR parameter id constant of {const_name} is not defined in the parameters file')
|
|
82
|
+
exit()
|
|
83
|
+
|
|
84
|
+
class LumpedPortVariableCheck(AbstractLumpedCheck):
|
|
85
|
+
'''
|
|
86
|
+
Checks if the port variables are defined in the module config variables.
|
|
87
|
+
# TODO this should be in the json schema for the module_config.json
|
|
88
|
+
'''
|
|
89
|
+
|
|
90
|
+
def execute(self, model_0D):
|
|
91
|
+
'''
|
|
92
|
+
Executes all check activities.
|
|
93
|
+
:param model_0D: model to be checked.
|
|
94
|
+
'''
|
|
95
|
+
model_0D.vessels_df.apply(self.execute_for_row, args=(model_0D, ), axis=1)
|
|
96
|
+
|
|
97
|
+
def execute_for_row(self, vessel_row, model_0D):
|
|
98
|
+
variables_list = [vessel_row["variables_and_units"][II][0] for II in range(len(vessel_row["variables_and_units"]))]
|
|
99
|
+
for port in vessel_row["entrance_ports"] + vessel_row["exit_ports"]:
|
|
100
|
+
for port_variable in port["variables"]:
|
|
101
|
+
if port_variable in ["", None, "None", "none"]:
|
|
102
|
+
continue
|
|
103
|
+
if port_variable not in variables_list:
|
|
104
|
+
print(f'the port variable {port_variable} '
|
|
105
|
+
f'is not a variable for vessel type: {vessel_row["vessel_type"]}, BC_type: {vessel_row["BC_type"]}')
|
|
106
|
+
exit()
|
|
107
|
+
|
|
108
|
+
# Example of usage
|
|
109
|
+
# Contructs a multiple check with only a LumpedBCVesselCheck
|
|
110
|
+
#model_checks = LumpedCompositeCheck(check_list=[LumpedBCVesselCheck()])
|
|
111
|
+
# Executes all checks in the model named model_0D
|
|
112
|
+
#model_checks.execute(model_0D)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Structural and connectivity checks for lumped-parameter models."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""0D-1D coupling sources (C++/JSON; no Python modules)."""
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Surrogate (emulator) models of the forward model -- issue #333.
|
|
2
|
+
|
|
3
|
+
An emulator maps theta (the ``params_for_id`` vector) to the scalar features of the
|
|
4
|
+
``obs_data.json`` data_items, i.e. the same numbers the cost is computed from. Fit it once, and
|
|
5
|
+
Sobol SA, calibration, MCMC and identifiability analysis can all evaluate it instead of the
|
|
6
|
+
simulator, because they all reach the model through that one mapping.
|
|
7
|
+
|
|
8
|
+
Public surface:
|
|
9
|
+
|
|
10
|
+
* :class:`emulators.emulator_trainer.EmulatorTrainer` -- design, simulate, fit, validate, save.
|
|
11
|
+
* :class:`emulators.emulator_bundle.EmulatorBundle` -- the saved artefact and its refusal rules.
|
|
12
|
+
* :func:`emulators.emulator_trainer.emulator_model_names` -- the emulator names the settings
|
|
13
|
+
accept, discovered from autoemulate rather than hardcoded.
|
|
14
|
+
|
|
15
|
+
``autoemulate`` is an optional dependency; importing this package without it works, and only
|
|
16
|
+
fitting (or loading a bundle fitted with it) raises.
|
|
17
|
+
"""
|
|
18
|
+
from libcuflynx.emulators.emulator_bundle import (EmulatorBoundsError, EmulatorBundle,
|
|
19
|
+
EmulatorQualityError, fingerprint)
|
|
20
|
+
from libcuflynx.emulators.emulator_trainer import (EmulatorTrainer, autoemulate_available,
|
|
21
|
+
emulator_model_names, resolve_emulator_dir)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
'autoemulate_available',
|
|
25
|
+
'EmulatorBoundsError',
|
|
26
|
+
'EmulatorBundle',
|
|
27
|
+
'EmulatorQualityError',
|
|
28
|
+
'EmulatorTrainer',
|
|
29
|
+
'emulator_model_names',
|
|
30
|
+
'fingerprint',
|
|
31
|
+
'resolve_emulator_dir',
|
|
32
|
+
]
|