CRNNondim 1.0.0__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.
Files changed (29) hide show
  1. crnnondim-1.0.0/.gitignore +90 -0
  2. crnnondim-1.0.0/CITATION.cff +17 -0
  3. crnnondim-1.0.0/LICENSE +21 -0
  4. crnnondim-1.0.0/PKG-INFO +27 -0
  5. crnnondim-1.0.0/README.md +11 -0
  6. crnnondim-1.0.0/examples/5D_SEIRV_example.py +78 -0
  7. crnnondim-1.0.0/examples/find_optimal_nondim_example.py +53 -0
  8. crnnondim-1.0.0/examples/parse_reactions_examples.py +90 -0
  9. crnnondim-1.0.0/examples/process_CRN_examples.py +69 -0
  10. crnnondim-1.0.0/examples/process_CRN_given_nondimensionalisation_examples.py +81 -0
  11. crnnondim-1.0.0/full_example.py +140 -0
  12. crnnondim-1.0.0/pyproject.toml +51 -0
  13. crnnondim-1.0.0/src/crnnondim/CRN_analyser.py +1344 -0
  14. crnnondim-1.0.0/src/crnnondim/_LEXIWrapper.py +60 -0
  15. crnnondim-1.0.0/src/crnnondim/__init__.py +148 -0
  16. crnnondim-1.0.0/src/crnnondim/_assignment_pool.py +334 -0
  17. crnnondim-1.0.0/src/crnnondim/_integer_search.py +138 -0
  18. crnnondim-1.0.0/src/crnnondim/_parallel_assignments.py +181 -0
  19. crnnondim-1.0.0/src/crnnondim/_polynomial_basis.py +167 -0
  20. crnnondim-1.0.0/src/crnnondim/analyse_results.py +163 -0
  21. crnnondim-1.0.0/src/crnnondim/example_CRNs.py +141 -0
  22. crnnondim-1.0.0/src/crnnondim/factor_generators_columnwise.py +83 -0
  23. crnnondim-1.0.0/src/crnnondim/find_optimal_nondim.py +999 -0
  24. crnnondim-1.0.0/src/crnnondim/objective_function_utils.py +537 -0
  25. crnnondim-1.0.0/src/crnnondim/parse_reactions.py +224 -0
  26. crnnondim-1.0.0/src/crnnondim/poly_system_to_CRN.py +140 -0
  27. crnnondim-1.0.0/src/crnnondim/process_CRN.py +243 -0
  28. crnnondim-1.0.0/src/crnnondim/process_CRN_given_nondimensionalisation.py +503 -0
  29. crnnondim-1.0.0/src/crnnondim/utils.py +1508 -0
@@ -0,0 +1,90 @@
1
+ # ------------------------------------------------------------------------------
2
+ # OS files
3
+ # ------------------------------------------------------------------------------
4
+ .DS_Store
5
+ Thumbs.db
6
+
7
+ # ------------------------------------------------------------------------------
8
+ # Python bytecode / cache
9
+ # ------------------------------------------------------------------------------
10
+ __pycache__/
11
+ *.py[cod]
12
+ *$py.class
13
+
14
+ # ------------------------------------------------------------------------------
15
+ # Virtual environments
16
+ # ------------------------------------------------------------------------------
17
+ .venv/
18
+ venv/
19
+ env/
20
+ ENV/
21
+
22
+ # Conda
23
+ .conda/
24
+ conda-env/
25
+ *.conda
26
+
27
+ # ------------------------------------------------------------------------------
28
+ # Build / packaging
29
+ # ------------------------------------------------------------------------------
30
+ build/
31
+ dist/
32
+ *.egg-info/
33
+ .eggs/
34
+ pip-wheel-metadata/
35
+ *.egg
36
+
37
+ # ------------------------------------------------------------------------------
38
+ # Logs / debugging
39
+ # ------------------------------------------------------------------------------
40
+ *.log
41
+ *.tmp
42
+
43
+ # ------------------------------------------------------------------------------
44
+ # Test / coverage artifacts
45
+ # ------------------------------------------------------------------------------
46
+ .pytest_cache/
47
+ .coverage
48
+ .coverage.*
49
+ htmlcov/
50
+ .tox/
51
+ .nox/
52
+ .cache/
53
+
54
+ # ------------------------------------------------------------------------------
55
+ # Notebooks
56
+ # ------------------------------------------------------------------------------
57
+ .ipynb_checkpoints/
58
+
59
+ # ------------------------------------------------------------------------------
60
+ # Editors / IDEs
61
+ # ------------------------------------------------------------------------------
62
+ .vscode/
63
+ .idea/
64
+ *.iml
65
+
66
+ # ------------------------------------------------------------------------------
67
+ # Documentation builds (if using Sphinx, etc.)
68
+ # ------------------------------------------------------------------------------
69
+ docs/_build/
70
+ site/
71
+
72
+ # ------------------------------------------------------------------------------
73
+ # Environment / local config
74
+ # ------------------------------------------------------------------------------
75
+ .env
76
+ .env.*
77
+ *.env
78
+
79
+ # ------------------------------------------------------------------------------
80
+ # uv / Python version files
81
+ # ------------------------------------------------------------------------------
82
+ .python-version
83
+ .uv_cache/
84
+ .uv-cache/
85
+
86
+ # ------------------------------------------------------------------------------
87
+ # Misc
88
+ # ------------------------------------------------------------------------------
89
+ *.swp
90
+ *.swo
@@ -0,0 +1,17 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use this software, please cite the following paper."
3
+ title: "Algorithmic Non-dimensionalisation of Polynomial Dynamical Systems with CRNNondim"
4
+ authors:
5
+ - family-names: "Hawi"
6
+ given-names: "Georgio"
7
+ - family-names: "Wechselberger"
8
+ given-names: "Martin"
9
+ preferred-citation:
10
+ type: article
11
+ authors:
12
+ - family-names: "Hawi"
13
+ given-names: "Georgio"
14
+ - family-names: "Wechselberger"
15
+ given-names: "Martin"
16
+ title: "Algorithmic Non-dimensionalisation of Polynomial Dynamical Systems with CRNNondim"
17
+ year: 2026
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Georgio Hawi and Martin Wechselberger
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.5
2
+ Name: CRNNondim
3
+ Version: 1.0.0
4
+ Summary: Automated non-dimensionalisation of polynomial dynamical systems via chemical reaction networks
5
+ Project-URL: Homepage, https://github.com/georgio-hawi/crnnondim
6
+ Project-URL: Repository, https://github.com/georgio-hawi/crnnondim
7
+ Author-email: Georgio Hawi <georgio.hawi@sydney.edu.au>, Martin Wechselberger <martin.wechselberger@sydney.edu.au>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: CRN,non-dimensionalisation,polynomial dynamical system
11
+ Requires-Python: <3.13,>=3.11.7
12
+ Requires-Dist: numpy<2,>=1.26.4
13
+ Requires-Dist: scipy<2,>=1.14.0
14
+ Requires-Dist: sympy<2,>=1.13.1
15
+ Description-Content-Type: text/markdown
16
+
17
+ # CRNNondim
18
+ CRNNondim is a Python library for automating the non-dimensionalisation of polynomial dynamical systems via chemical reaction networks (CRNs). It was developed by Georgio Hawi and Martin Wechselberger, with an accompanying paper available soon. Please direct all enquiries to georgio.hawi (at) sydney.edu.au.
19
+
20
+ Given a polynomial CRN, CRNNondim helps you move from human-readable reaction lists to carefully chosen dimensionless variables and parameters. You can analyse a proposed non-dimensionalisation, or ask the library to search for one that is optimal under a precise objective (for example, keeping parameters O(1) over a chosen time window).
21
+
22
+ CRNNondim provides tools to automate analysing and non-dimensionalising chemical reaction networks (CRNs).
23
+ CRNNondim includes functions that let you:
24
+ - parse readable reaction network descriptions or a polynomial ODE system into a symbolic CRN-like ODE system (stoichiometry matrix `S`, reaction vector `V`, species vector `X`, and rate constants),
25
+ - analyse CRNs to derive algebraic constraints on concentration and time scales and construct non-dimensionalisations that minimise the number of free parameters,
26
+ - non-dimensionalise a CRN given an explicit choice of species scales, so you can test or refine hand-crafted scalings,
27
+ - search for optimal non-dimensionalisations using typical initial conditions and rate constants, targeting O(1) parameters over a specified time window
@@ -0,0 +1,11 @@
1
+ # CRNNondim
2
+ CRNNondim is a Python library for automating the non-dimensionalisation of polynomial dynamical systems via chemical reaction networks (CRNs). It was developed by Georgio Hawi and Martin Wechselberger, with an accompanying paper available soon. Please direct all enquiries to georgio.hawi (at) sydney.edu.au.
3
+
4
+ Given a polynomial CRN, CRNNondim helps you move from human-readable reaction lists to carefully chosen dimensionless variables and parameters. You can analyse a proposed non-dimensionalisation, or ask the library to search for one that is optimal under a precise objective (for example, keeping parameters O(1) over a chosen time window).
5
+
6
+ CRNNondim provides tools to automate analysing and non-dimensionalising chemical reaction networks (CRNs).
7
+ CRNNondim includes functions that let you:
8
+ - parse readable reaction network descriptions or a polynomial ODE system into a symbolic CRN-like ODE system (stoichiometry matrix `S`, reaction vector `V`, species vector `X`, and rate constants),
9
+ - analyse CRNs to derive algebraic constraints on concentration and time scales and construct non-dimensionalisations that minimise the number of free parameters,
10
+ - non-dimensionalise a CRN given an explicit choice of species scales, so you can test or refine hand-crafted scalings,
11
+ - search for optimal non-dimensionalisations using typical initial conditions and rate constants, targeting O(1) parameters over a specified time window
@@ -0,0 +1,78 @@
1
+ """
2
+ Examples showing how to use poly_system_to_CRN to convert the
3
+ 5D SEIRV epidemic model to a mass-action CRN representation (S, V, X, etc),
4
+ and use process_CRN to analyse it.
5
+ """
6
+ import sympy as sp
7
+ from crnnondim import poly_system_to_CRN, process_CRN, analyse_results
8
+
9
+ # ---------------------------------------------------------------------------
10
+ # Example: 5D SEIRV epidemic model
11
+ # ---------------------------------------------------------------------------
12
+ # STATE VARIABLES (species):
13
+ # S(t): Susceptible individuals
14
+ # E(t): Exposed (infected but not yet infectious)
15
+ # I(t): Infectious
16
+ # R(t): Recovered with immunity
17
+ # V(t): Vaccinated and currently protected
18
+ #
19
+ # PARAMETERS:
20
+ # Lambda : recruitment rate (birth/immigration) into S
21
+ # mu : natural per-capita death rate (applies to all compartments)
22
+ # beta : infection rate (S becomes E via contact with I)
23
+ # sigma : progression rate from exposed to infectious (E -> I)
24
+ # gamma : recovery rate from infectious to recovered (I -> R)
25
+ # nu : vaccination rate of susceptibles (S -> V)
26
+ # omega : waning immunity rate in recovered (R -> S)
27
+ # omega_V : waning vaccine protection rate (V -> S)
28
+ #
29
+ # MODEL EQUATIONS:
30
+ #
31
+ # dS/dt = Lambda - beta*S*I - nu*S + omega*R + omega_V*V - mu*S
32
+ # dE/dt = beta*S*I - sigma*E - mu*E
33
+ # dI/dt = sigma*E - gamma*I - mu*I
34
+ # dR/dt = gamma*I - omega*R - mu*R
35
+ # dV/dt = nu*S - omega_V*V - mu*V
36
+ # ---------------------------------------------------------------------------
37
+
38
+ # Define species (state variables) as SymPy symbols
39
+ S, E, I, R, V = sp.symbols("S E I R V", nonnegative=True)
40
+ X_syms = [S, E, I, R, V]
41
+
42
+ # Define parameters as SymPy symbols (positive)
43
+ Lambda, mu, beta, sigma, gamma, nu, omega, omega_V = sp.symbols(
44
+ "Lambda mu beta sigma gamma nu omega omega_V", positive=True
45
+ )
46
+
47
+ # ODE right-hand sides
48
+ dXdt = [
49
+ Lambda - beta*S*I - nu*S + omega*R + omega_V*V - mu*S,
50
+ beta*S*I - sigma*E - mu*E,
51
+ sigma*E - gamma*I - mu*I,
52
+ gamma*I - omega*R - mu*R,
53
+ nu*S - omega_V*V - mu*V]
54
+
55
+ # Convert the ODE system into objects usable by CRNNondim and print a small summary of the parsed CRN.
56
+ parsed_out = poly_system_to_CRN(
57
+ _X=X_syms,
58
+ ode_rhs=dXdt,
59
+ verbose=True
60
+ )
61
+
62
+ species_names = parsed_out["species"]
63
+ _S = parsed_out['_S']
64
+ _X = parsed_out['_X']
65
+ _V = parsed_out['_V']
66
+ rate_constants = parsed_out['rate_constants']
67
+
68
+ # Map species -> scale symbols. These scale symbols are held fixed when analysing the CRN.
69
+ S_0, I_0 = sp.symbols('S_0 I_0', positive=True)
70
+ fixed_K = {S: S_0, I: I_0}
71
+
72
+ # Analyse the CRN, optionally asking it to construct an explicit example
73
+ # non-dimensionalisation that attains the minimum possible number of
74
+ # free parameters (find_example_nondim=True).
75
+ all_results = process_CRN(_S, _V, _X, fixed_K=fixed_K, find_example_nondim=True, verbose=True, basis_type="Laurent")
76
+
77
+ # Analyse the results and print the analysis (if verbose=True).
78
+ all_transformed_results = analyse_results(all_results, verbose=True)
@@ -0,0 +1,53 @@
1
+ """
2
+ Example showing how to use find_optimal_nondim to find
3
+ the optimal non-dimensionalisation given numerical values for
4
+ typical initial conditions and rate constants.
5
+ """
6
+
7
+ from crnnondim import find_optimal_nondim, analyse_results, Kim_ForgerExample
8
+ import sympy as sp
9
+
10
+ def Kim_Forger_example():
11
+ # Instantiate the Kim-Forger example.
12
+ kf_example = Kim_ForgerExample()
13
+
14
+ # Example dimensional initial conditions for the species.
15
+ x_0_num = {kf_example.X: 1.0, kf_example.Y: 1.0, kf_example.Z: 0.06128, kf_example.S: 0.06128, kf_example.C: 0.0}
16
+
17
+ # Characteristic concentration scales for each species with non-zero initial condition.
18
+ x0, y0, z0, s0 = sp.symbols('x_0 y_0 z_0 s_0', positive=True)
19
+
20
+ # Map species -> scale symbols. These scale symbols are held fixed when searching for
21
+ # optimal non-dimensionalisations.
22
+ fixed_K = {kf_example.X: x0, kf_example.Y: y0, kf_example.Z: z0, kf_example.S: s0}
23
+
24
+ # Example dimensional rate constants used to evaluate O(1) deviation penalty.
25
+ k_num = {kf_example.k1: 0.07, kf_example.k2: 0.07, kf_example.k3: 0.05, kf_example.k4: 0.05, kf_example.k5: 0.05, kf_example.k6: 0.05, kf_example.kf: 1.0, kf_example.kb: 1.0, kf_example.ku: 0.05}
26
+
27
+ # Time window (in dimensional time) over which we want to consider a penalty.
28
+ T_max = 12
29
+ T_min = T_max/2
30
+
31
+ # Non-dimensionalisation metric
32
+ nondim_metric = "deviation" #"maximum"
33
+
34
+ # Dimensioanlly consistent sets
35
+ # Optional: list of sets of dimensionally consistent state variables
36
+ # default=None assumes all state variables have the same dimensions.
37
+ dimensionally_consistent_sets=None
38
+
39
+ # Compute the optimal non-dimensionalisation for this CRN.
40
+ solver_opts=dict(method="Radau", atol=1e-12, rtol=1e-9)
41
+ res = find_optimal_nondim(kf_example._S, kf_example._V, kf_example._X, fixed_K=fixed_K,
42
+ dimensionally_consistent_sets=dimensionally_consistent_sets,
43
+ k_numeric=k_num, x0_numeric=x_0_num, T_min=T_min, T_max=T_max, nondim_metric=nondim_metric, solver_opts=solver_opts, basis_type="Polynomial", n_jobs=None,
44
+ # export results to a pickle format.
45
+ export_results=True,
46
+ output_path=f"out/Kim_Forger_{nondim_metric}_nondim.pkl")
47
+ return res
48
+
49
+ # Run the example.
50
+ all_results = Kim_Forger_example()
51
+
52
+ # Analyse the results and print the analysis (if verbose=True).
53
+ all_transformed_results = analyse_results(all_results, verbose=True)
@@ -0,0 +1,90 @@
1
+ """
2
+ Examples showing how to use build_mass_action_system to convert
3
+ a list of reactions to a mass-action CRN representation (S, V, X, etc).
4
+ """
5
+ from crnnondim import reaction, reversible, build_mass_action_system
6
+
7
+ def Michaelis_Menten_example():
8
+ """
9
+ Defines the reaction list for the reversible Michaelis-Menten scheme.
10
+
11
+ Returns
12
+ -------
13
+ rxns : list
14
+ List of reaction objects (forward + reverse) that can be passed to
15
+ build_mass_action_system.
16
+ """
17
+ rxns = []
18
+ # E + S <-> C with forward rate k1 and reverse rate km1
19
+ rxns += reversible("E + S <-> C", kf="k1", kr="km1")
20
+ # C <-> P + E with forward rate k2 and reverse rate km2
21
+ rxns += reversible("C <-> P + E", kf="k2", kr="km2")
22
+ return rxns
23
+
24
+ def Kim_Forger_example():
25
+ """
26
+ Defines the reaction list for the Kim-Forger (KF) model, a simplified
27
+ circadian clock model.
28
+ """
29
+ rxns = [
30
+ # S -> X + S : basal production of X driven by S (rate constant k1)
31
+ reaction("S -> X + S", k="k1"),
32
+ # X -> 0 : degradation/removal of X (rate constant k2)
33
+ reaction("X -> 0", k="k2"),
34
+ # X -> X + Y : production of Y catalysed by X (rate constant k3)
35
+ reaction("X -> X + Y", k="k3"),
36
+ # Y -> 0 : degradation/removal of Y (rate constant k4)
37
+ reaction("Y -> 0", k="k4"),
38
+ # Y -> Y + Z : production of Z catalysed by Y (rate constant k5)
39
+ reaction("Y -> Y + Z", k="k5"),
40
+ # Z -> 0 : degradation/removal of Z (rate constant k6)
41
+ reaction("Z -> 0", k="k6"),
42
+ # C -> S : conversion/decay of complex C back to free S
43
+ reaction("C -> S", k="ku")]
44
+ # Reversible binding/unbinding between S and Z to form complex C.
45
+ # Forward binding S + Z -> C has rate constant kf,
46
+ # reverse unbinding C -> S + Z has rate constant kb.
47
+ rxns+= reversible("S + Z <-> C", kf="kf", kr="kb")
48
+ return rxns
49
+
50
+ def McKeithan_example(n=6):
51
+ """
52
+ Defines the reaction list for the McKeithan TCR proofreading chain with n
53
+ intermediate ligand-receptor complexes.
54
+
55
+ Parameters
56
+ ----------
57
+ n : int
58
+ Number of proofreading steps (C0 -> C1 -> ... -> Cn).
59
+ """
60
+ rxns = []
61
+ # Association/dissociation of the first complex C0.
62
+ rxns.extend(reversible("T + M <-> C0", kf="k1", kr="km1"))
63
+ # Forward proofreading step through the chain of complexes.
64
+ for i in range(n):
65
+ rxns.append(reaction(f"C{i} -> C{i+1}", k=f"k2")) # forward proofreading step
66
+ # Each complex can dissociate back to T + M with the same rate km1.
67
+ for i in range(1,n+1):
68
+ rxns.append(reaction(f"C{i} -> T + M", k=f"km1"))
69
+ return rxns
70
+
71
+ # Select which example to parse and convert into a mass-action CRN.
72
+ example_name = "McKeithan"
73
+
74
+ match example_name:
75
+ case "Michaelis-Menten":
76
+ reactions = Michaelis_Menten_example()
77
+ case "Kim-Forger":
78
+ reactions = Kim_Forger_example()
79
+ case _:
80
+ reactions = McKeithan_example()
81
+
82
+ # Convert the reaction list into objects usable by CRNNondim and print a small summary of the parsed CRN.
83
+ parsed_out = build_mass_action_system(reactions, verbose=True)
84
+
85
+ species_names = parsed_out["species"]
86
+ _S = parsed_out['_S']
87
+ _X = parsed_out['_X']
88
+ _V = parsed_out['_V']
89
+ rate_constants = parsed_out['rate_constants']
90
+ expanded_ODEs = parsed_out['expanded_ODEs']
@@ -0,0 +1,69 @@
1
+ """
2
+ Examples showing how to use process_CRN to analyse CRNs, derive restrictions
3
+ on scaling factors so that the number of free parameters in the resulting non-dimensional
4
+ system is minimised, and construct an example non-dimensionalisation that attains this minimum.
5
+ """
6
+ from crnnondim import process_CRN, analyse_results, Michaelis_MentenExample, Kim_ForgerExample, McKeithanExample
7
+ import sympy as sp
8
+
9
+ def Michaelis_Menten_example(find_example_nondim=False):
10
+ # Instantiate the Michaelis-Menten example.
11
+ mm_example = Michaelis_MentenExample()
12
+
13
+ # Characteristic concentration scales for S and E.
14
+ s0, e0 = sp.symbols('s_0 e_0', positive=True)
15
+
16
+ # Map species -> scale symbols. These scale symbols are held fixed when analysing the CRN.
17
+ fixed_K = {mm_example.S: s0, mm_example.E: e0}
18
+
19
+ # Analyse the CRN, optionally asking it to construct an explicit example
20
+ # non-dimensionalisation that attains the minimum possible number of
21
+ # free parameters (find_example_nondim=True).
22
+ res = process_CRN(mm_example._S, mm_example._V, mm_example._X, fixed_K=fixed_K, find_example_nondim=find_example_nondim, verbose=True, basis_type="Laurent")
23
+ return res
24
+
25
+ def Kim_Forger_example(find_example_nondim=False):
26
+ # Instantiate the Kim-Forger example.
27
+ kf_example = Kim_ForgerExample()
28
+
29
+ # Characteristic concentration scales for X, Y, Z, S.
30
+ x0, y0, z0, s0 = sp.symbols('x_0 y_0 z_0 s_0', positive=True)
31
+
32
+ # Map species -> scale symbols. These scale symbols are held fixed when analysing the CRN.
33
+ fixed_K = {kf_example.X: x0, kf_example.Y: y0, kf_example.Z: z0, kf_example.S: s0}
34
+
35
+ # Analyse the CRN, optionally asking it to construct an explicit example
36
+ # non-dimensionalisation that attains the minimum possible number of
37
+ # free parameters (find_example_nondim=True).
38
+ res = process_CRN(kf_example._S, kf_example._V, kf_example._X, fixed_K=fixed_K, find_example_nondim=find_example_nondim, verbose=True, basis_type="Laurent")
39
+ return res
40
+
41
+ def McKeithan_example(find_example_nondim=False):
42
+ # Instantiate the McKeithan TCR proofreading example.
43
+ m_example = McKeithanExample()
44
+
45
+ # Characteristic concentration scales for T and M.
46
+ T_0, M_0 = sp.symbols('T_0 M_0', positive=True)
47
+
48
+ # Map species -> scale symbols. These scale symbols are held fixed when analysing the CRN.
49
+ fixed_K = {m_example.T: T_0, m_example.M: M_0}
50
+
51
+ # Analyse the CRN, optionally asking it to construct an explicit example
52
+ # non-dimensionalisation that attains the minimum possible number of
53
+ # free parameters (find_example_nondim=True).
54
+ res = process_CRN(m_example._S, m_example._V, m_example._X, fixed_K=fixed_K, find_example_nondim=find_example_nondim, verbose=True, basis_type="Laurent")
55
+ return res
56
+
57
+ # Choose which example to run.
58
+ example_name = "McKeithan"
59
+ find_example_nondim = True
60
+ match example_name:
61
+ case "Michaelis-Menten":
62
+ all_results = Michaelis_Menten_example(find_example_nondim=find_example_nondim)
63
+ case "Kim-Forger":
64
+ all_results = Kim_Forger_example(find_example_nondim=find_example_nondim)
65
+ case _:
66
+ all_results = McKeithan_example(find_example_nondim=find_example_nondim)
67
+
68
+ # Analyse the results and print the analysis (if verbose=True).
69
+ all_transformed_results = analyse_results(all_results, verbose=True)
@@ -0,0 +1,81 @@
1
+ """
2
+ Examples showing how to use process_CRN_given_nondimensionalisation to
3
+ non-dimensionalise a CRN given a specific non-dimensionalisation.
4
+ """
5
+ from crnnondim import process_CRN_given_nondimensionalisation, analyse_results, Michaelis_MentenExample, Kim_ForgerExample, McKeithanExample
6
+ import sympy as sp
7
+
8
+ def Michaelis_Menten_example(return_all_families=False):
9
+ # Instantiate the Michaelis-Menten example.
10
+ mm_example = Michaelis_MentenExample()
11
+
12
+ # Characteristic concentration scales for S and E.
13
+ s_0, e_0 = sp.symbols('s_0 e_0', positive=True)
14
+
15
+ #Give an explicit choice of non-dimensionalisation.
16
+ nondim = {mm_example.S: s_0, mm_example.E: e_0, mm_example.C: e_0, mm_example.P: e_0}
17
+
18
+ # Non-dimensionalise the CRN given this particular non-dimensionalisation.
19
+ # Time scaling, via K_T, can be provided if desired.
20
+ res = process_CRN_given_nondimensionalisation(
21
+ mm_example._S,
22
+ mm_example._V,
23
+ mm_example._X,
24
+ nondim=nondim,
25
+ basis_type="Laurent",
26
+ return_all_families=return_all_families
27
+ )
28
+ return res
29
+
30
+ def Kim_Forger_example(return_all_families=False):
31
+ # Instantiate the Kim-Forger example.
32
+ kf_example = Kim_ForgerExample()
33
+
34
+ # Characteristic concentration scales for X, Y, Z, S.
35
+ x_0, y_0, z_0, s_0 = sp.symbols('x_0 y_0 z_0 s_0', positive=True)
36
+
37
+ #Give an explicit choice of non-dimensionalisation.
38
+ nondim1 = {kf_example.X: x_0, kf_example.Y: y_0, kf_example.Z: z_0, kf_example.S: s_0, kf_example.C:z_0}
39
+
40
+ # Non-dimensionalise the CRN given this particular non-dimensionalisation.
41
+ # Time scaling, via K_T, can be provided if desired.
42
+ res1 = process_CRN_given_nondimensionalisation(kf_example._S, kf_example._V, kf_example._X, nondim=nondim1, basis_type="Laurent", return_all_families=return_all_families)
43
+
44
+ # Second choice of non-dimensionalisation.
45
+ nondim2 = {kf_example.X: x_0, kf_example.Y: y_0, kf_example.Z: z_0, kf_example.S: s_0, kf_example.C:x_0} # species-keyed
46
+ res2 = process_CRN_given_nondimensionalisation(kf_example._S, kf_example._V, kf_example._X, nondim=nondim2, basis_type="Laurent", return_all_families=return_all_families)
47
+
48
+ return [res1, res2]
49
+
50
+ def McKeithan_example(return_all_families=False):
51
+ # Instantiate the McKeithan TCR proofreading example.
52
+ m_example = McKeithanExample()
53
+
54
+ # Characteristic concentration scales for T and M.
55
+ T_0, M_0 = sp.symbols('T_0 M_0', positive=True)
56
+
57
+ # consider a dimensionalisation where the scaling factors for C0, C1, C2, C3, C4, C5, C6 are T_0.
58
+ nondim = {m_example.T: T_0, m_example.M: M_0}
59
+ for sym in [m_example.C0, m_example.C1, m_example.C2, m_example.C3, m_example.C4, m_example.C5, m_example.C6]:
60
+ # All complexes share the same concentration scale T_0.
61
+ nondim[sym] = T_0
62
+
63
+ # Non-dimensionalise the CRN given this particular non-dimensionalisation.
64
+ # Time scaling, via K_T, can be provided if desired.
65
+ res = process_CRN_given_nondimensionalisation(m_example._S, m_example._V, m_example._X, nondim=nondim, basis_type="Laurent", return_all_families=return_all_families)
66
+ return res
67
+
68
+ # Choose which example to run and whether to return all families. If return_all_families is true,
69
+ # all families where K_T is chosen to minimise the number of free parameters will be printed.
70
+ example_name = "Michaelis-Menten"
71
+ return_all_families = True
72
+ match example_name:
73
+ case "Michaelis-Menten":
74
+ all_results = Michaelis_Menten_example(return_all_families=return_all_families)
75
+ case "Kim-Forger":
76
+ all_results = Kim_Forger_example(return_all_families=return_all_families)
77
+ case _:
78
+ all_results = McKeithan_example(return_all_families=return_all_families)
79
+
80
+ # Analyse the results and print the analysis (if verbose=True).
81
+ all_transformed_results = analyse_results(all_results, verbose=True)