PyAntiGen 1.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.
framework/pyantigen.py ADDED
@@ -0,0 +1,51 @@
1
+ import os
2
+ from framework.isotopomer_tools import ensure_isotopes_format
3
+ from framework.model_generation import generate_model
4
+
5
+ class PyAntiGen:
6
+ def __init__(self, name, isotopes=None):
7
+ self.name = name
8
+ self.isotopes = ensure_isotopes_format(isotopes or [''])
9
+ self.reactions = []
10
+ self.rules = []
11
+ self.counter = 0
12
+
13
+ def add_reaction(
14
+ self,
15
+ name,
16
+ reactants,
17
+ products,
18
+ rate_type,
19
+ rate_eqtn,
20
+ compartment=None,
21
+ compartment_reverse=None,
22
+ ):
23
+ from framework.reaction_creation import reaction_creation
24
+ self.counter, self.reactions = reaction_creation(
25
+ self.reactions,
26
+ self.counter,
27
+ name,
28
+ reactants,
29
+ products,
30
+ rate_type,
31
+ rate_eqtn,
32
+ compartment=compartment,
33
+ compartment_reverse=compartment_reverse,
34
+ )
35
+
36
+ def add_rule(self, rule):
37
+ self.rules.append(rule)
38
+
39
+ def generate(self, calling_file_path, model_name=None):
40
+ """
41
+ Generates the Antimony model. This wraps the existing model_generation logic.
42
+ """
43
+ if model_name is None:
44
+ model_name = self.name
45
+
46
+ def build_reactions_wrapper(Isotopes):
47
+ # The isotopes passed in here by generate_model are essentially self.isotopes
48
+ # because we formatted them earlier. So we can just return our state.
49
+ return self.reactions, self.rules
50
+
51
+ generate_model(build_reactions_wrapper, self.isotopes, calling_file_path, model_name)
framework/rate_laws.py ADDED
@@ -0,0 +1,101 @@
1
+ """
2
+ Rate law semantics and volumetric scaling for PyAntiGen.
3
+
4
+ Each rate type has defined units and explicit volume scaling behavior so that
5
+ generated Antimony has correct [amount/time] ODE terms.
6
+
7
+ Units summary:
8
+ - MA / RMA: User supplies [concentration]^n / time; framework multiplies by V_compartment
9
+ to yield [amount/time]. Single-compartment reactions.
10
+ - UDF / BDF: User supplies [volume/time] (flow rate); framework uses concentration
11
+ of species (no global V multiplier). Trans-compartment transport.
12
+ - custom_conc_per_time: User equation in [concentration]^n/time; framework multiplies
13
+ by V_compartment. Set species_names_are_conc_per_time=True (default).
14
+ - custom_amt_per_time: User equation already in [amount/time]; no volume scaling.
15
+ - custom: Raw expression as-is; user must include volume scaling if needed.
16
+ """
17
+ from abc import ABC, abstractmethod
18
+ from typing import Optional
19
+
20
+
21
+ class RateLaw(ABC):
22
+ """Base for rate law semantics (units and volume scaling)."""
23
+
24
+ @property
25
+ @abstractmethod
26
+ def multiplies_by_volume(self) -> bool:
27
+ """Whether the framework multiplies the rate expression by compartment volume."""
28
+ pass
29
+
30
+ @property
31
+ @abstractmethod
32
+ def user_units_description(self) -> str:
33
+ """Expected units of the user-supplied rate expression."""
34
+ pass
35
+
36
+
37
+ class MassActionLaw(RateLaw):
38
+ """MA / RMA: [concentration]^n / time; framework multiplies by V_compartment."""
39
+ rate_type = "MA"
40
+
41
+ @property
42
+ def multiplies_by_volume(self) -> bool:
43
+ return True
44
+
45
+ @property
46
+ def user_units_description(self) -> str:
47
+ return "[concentration]^n / time → framework multiplies by V_compartment to yield amount/time"
48
+
49
+
50
+ class VolumeTransportLaw(RateLaw):
51
+ """UDF / BDF: [volume/time]; species appear as concentration; no V multiplier on expression."""
52
+ rate_type = "UDF"
53
+
54
+ @property
55
+ def multiplies_by_volume(self) -> bool:
56
+ return False
57
+
58
+ @property
59
+ def user_units_description(self) -> str:
60
+ return "[volume/time]; species in equation are concentrations; no V_compartment multiplier"
61
+
62
+
63
+ class CustomLaw(RateLaw):
64
+ """
65
+ custom_conc_per_time / custom_amt_per_time / custom.
66
+ custom_conc_per_time: equation in conc/time → we multiply by V.
67
+ custom_amt_per_time: equation already in amount/time → no scaling.
68
+ custom: as-is; user must include volume scaling if needed.
69
+ """
70
+ def __init__(
71
+ self,
72
+ rate_type: str = "custom",
73
+ species_names_are_conc_per_time: Optional[bool] = None,
74
+ ):
75
+ self.rate_type = rate_type
76
+ self._mult_vol = (
77
+ species_names_are_conc_per_time
78
+ if species_names_are_conc_per_time is not None
79
+ else (rate_type == "custom_conc_per_time")
80
+ )
81
+
82
+ @property
83
+ def multiplies_by_volume(self) -> bool:
84
+ return self._mult_vol
85
+
86
+ @property
87
+ def user_units_description(self) -> str:
88
+ if self.multiplies_by_volume:
89
+ return "[concentration]^n/time → framework multiplies by V_compartment"
90
+ return "Equation already in [amount/time]; no volume scaling applied"
91
+
92
+
93
+ def get_rate_law_info(rate_type: str) -> str:
94
+ """Return a short docstring for the given rate type (units and scaling)."""
95
+ if rate_type in ("MA", "RMA"):
96
+ return MassActionLaw(rate_type).user_units_description
97
+ if rate_type in ("UDF", "BDF"):
98
+ return VolumeTransportLaw(rate_type).user_units_description
99
+ if rate_type in ("custom_conc_per_time", "custom_amt_per_time", "custom"):
100
+ return CustomLaw(rate_type).user_units_description
101
+ return "Unknown rate type"
@@ -0,0 +1,43 @@
1
+ from framework.models import (
2
+ reaction_from_args,
3
+ VALID_RATE_TYPES,
4
+ RATE_TYPES_TWO_CONSTANTS,
5
+ )
6
+
7
+
8
+ def reaction_creation(
9
+ all_reactions,
10
+ counter,
11
+ Reaction_name,
12
+ Reactants,
13
+ Products,
14
+ Rate_type,
15
+ Rate_eqtn_prototype,
16
+ compartment=None,
17
+ compartment_reverse=None,
18
+ ):
19
+ """
20
+ Create and append a validated reaction to all_reactions.
21
+ Accepts reactants/products as either list of strings or bracket string (e.g. "[A, B]").
22
+ Validates required fields and rate type at call time; raises on invalid input.
23
+ """
24
+ try:
25
+ reaction = reaction_from_args(
26
+ name=Reaction_name,
27
+ reactants=Reactants,
28
+ products=Products,
29
+ rate_type=Rate_type,
30
+ rate_eqtn=Rate_eqtn_prototype,
31
+ compartment=compartment,
32
+ compartment_reverse=compartment_reverse,
33
+ )
34
+ except ValueError as e:
35
+ raise ValueError(f"add_reaction validation failed: {e}") from e
36
+
37
+ if reaction.Rate_type in RATE_TYPES_TWO_CONSTANTS:
38
+ counter += 2
39
+ else:
40
+ counter += 1
41
+
42
+ all_reactions.append(reaction.to_dict())
43
+ return counter, all_reactions
@@ -0,0 +1,23 @@
1
+ import sys
2
+ from pathlib import Path
3
+
4
+ # Use location: import Modules from the same folder as this script (model folder)
5
+ _project_dir = Path(__file__).resolve().parent
6
+ if str(_project_dir) not in sys.path:
7
+ sys.path.insert(0, str(_project_dir))
8
+
9
+ MODEL_NAME = _project_dir.name
10
+
11
+ # Add PyAntiGen root to sys.path if running from within the framework template
12
+ if _project_dir.parent.name == "template":
13
+ _pyantigen_root = _project_dir.parents[2]
14
+ if str(_pyantigen_root) not in sys.path:
15
+ sys.path.insert(0, str(_pyantigen_root))
16
+
17
+ if _project_dir.name == "scripts":
18
+ REPO_ROOT = str(_project_dir.parent)
19
+ else:
20
+ REPO_ROOT = str(_project_dir.parents[1])
21
+
22
+ if REPO_ROOT not in sys.path:
23
+ sys.path.insert(0, REPO_ROOT)
@@ -0,0 +1,30 @@
1
+ """
2
+ Example model builder. Outputs go to antimony_models/Example/ and generated/Example/.
3
+ """
4
+ import os
5
+ import sys
6
+
7
+ import AntiGen_paths
8
+
9
+
10
+ from framework.pyantigen import PyAntiGen
11
+ from antimony_modules.Basic.ma_reaction import BasicMAReaction
12
+
13
+ def generate_antimony_model(Isotopes=['']):
14
+ MODEL_NAME = AntiGen_paths.MODEL_NAME
15
+ model = PyAntiGen(name=MODEL_NAME, isotopes=Isotopes)
16
+ BasicMAReaction(model)
17
+
18
+ print(f"Reactions generated: {model.counter}")
19
+ print(f"Rules generated: {len(model.rules)}")
20
+
21
+ model.generate(__file__, model_name=MODEL_NAME)
22
+
23
+ print("\nModel generated successfully.")
24
+ print("Next steps:")
25
+ print(f" 1. Optionally edit parameters in antimony_models/{MODEL_NAME}/{MODEL_NAME}_parameters.csv")
26
+ print(f" 2. From scripts/{MODEL_NAME}/, run: python {MODEL_NAME}_run.py")
27
+
28
+ if __name__ == "__main__":
29
+ Isotopes = ['']
30
+ generate_antimony_model(Isotopes)
@@ -0,0 +1,37 @@
1
+ import os
2
+ import sys
3
+
4
+ from Engine.Model_simulate import setup_simulation
5
+ from Engine.Model_optimize import setup_optimization_from_groups
6
+ from Modules.Plots import *
7
+ from Modules.Experiment import get_experiment
8
+ from Modules.Optimizer_settings import OPTIMIZATION_SETTINGS
9
+ from AntiGen_paths import MODEL_NAME
10
+
11
+
12
+ EXPERIMENT_dict = {
13
+ "Example": {'EXPERIMENT': get_experiment('EXPERIMENT_Example'), 'plot': plot_results, 'opt_settings_key': 'Example'},
14
+ }
15
+
16
+ run_settings = {
17
+ "run_steady_state_first" : True,
18
+ "Verbose" : True,
19
+ }
20
+
21
+
22
+ if __name__ == "__main__":
23
+ print("Run_settings: ", run_settings)
24
+
25
+ run_optimization = True
26
+ run_name = "Example"
27
+
28
+ if run_optimization:
29
+ opt_key = EXPERIMENT_dict[run_name].get('opt_settings_key', run_name)
30
+ experiment_arg = {
31
+ "EXPERIMENT": EXPERIMENT_dict[run_name]['EXPERIMENT'],
32
+ "plot": EXPERIMENT_dict[run_name]['plot'],
33
+ }
34
+ setup_optimization_from_groups(run_settings, OPTIMIZATION_SETTINGS[opt_key], experiment_arg)
35
+ else:
36
+ setup_simulation(run_settings, EXPERIMENT_dict[run_name])
37
+
@@ -0,0 +1,36 @@
1
+ import pandas as pd
2
+ import os
3
+
4
+
5
+ def load_no_data(replicate, data_path):
6
+ data_dict = {}
7
+ return data_dict
8
+
9
+
10
+ def load_ad_data(replicate, data_path):
11
+ def reshape_df(df):
12
+ return pd.concat([
13
+ df[['time', 'B1']].rename(columns={'B1': 'B'}),
14
+ df[['time', 'B2']].rename(columns={'B2': 'B'}),
15
+ df[['time', 'B3']].rename(columns={'B3': 'B'})
16
+ ], ignore_index=True)
17
+
18
+ treatment_path = os.path.join(data_path, 'ADneg.csv')
19
+ df_neg = pd.read_csv(treatment_path)
20
+ df_neg_early = reshape_df(df_neg[df_neg['Treatment'] == 'Early'])
21
+ df_neg_late = reshape_df(df_neg[df_neg['Treatment'] == 'Late'])
22
+ treatment_path = os.path.join(data_path, 'ADpos.csv')
23
+ df_pos = pd.read_csv(treatment_path)
24
+ df_pos_early = reshape_df(df_pos[df_pos['Treatment'] == 'Early'])
25
+ df_pos_late = reshape_df(df_pos[df_pos['Treatment'] == 'Late'])
26
+
27
+ data_dict = {
28
+ "ADneg__Early": df_neg_early,
29
+ "ADneg__Late": df_neg_late,
30
+ "ADpos__Early": df_pos_early,
31
+ "ADpos__Late": df_pos_late,
32
+ }
33
+ return data_dict
34
+
35
+
36
+
@@ -0,0 +1,14 @@
1
+ from framework.data_interpolation import generate_antimony_piecewise
2
+
3
+ def generate_no_events(replicate, df_dict):
4
+ events = ''
5
+ return events
6
+
7
+ def Example_event(replicate, df_dict):
8
+ dose = replicate["dose"]
9
+ delay = replicate["delay"]
10
+ events = f'at (time >= {delay}): A_Comp1 = {dose}'
11
+ return events
12
+
13
+
14
+
@@ -0,0 +1,160 @@
1
+ """Experiment registry: one 'replicate' entry per simulation,
2
+ simulations are optimized together if in the same opt_group.
3
+ """
4
+ from .Data import *
5
+ from .Events import *
6
+ from .Loss_config import *
7
+ from .Observed_species import *
8
+ from .Solver_settings import *
9
+ from .Update_parameters import *
10
+
11
+ from dataclasses import dataclass, field
12
+
13
+ @dataclass
14
+ class Experiment:
15
+ replicates: dict = field(default_factory=dict)
16
+
17
+ @property
18
+ def opt_groups(self):
19
+ """Return {opt_group: [replicate_key, ...]} by scanning replicates."""
20
+ groups = {}
21
+ for key, rep in self.replicates.items():
22
+ og = rep.get("Opt_group")
23
+ if og is not None:
24
+ groups.setdefault(og, []).append(key)
25
+ return groups
26
+
27
+
28
+ def make_replicate(config, **meta):
29
+ """
30
+ Build a single replicate entry dict from an explicit config dict.
31
+
32
+ config keys (all required unless noted):
33
+ "Label" : str
34
+ "Events" : callable(replicate, df_dict) -> str
35
+ "Data" : callable(replicate, data_path) -> Dict of DataFrame or None
36
+ "Observed_species" : callable(RoadRunner_instance or None) -> list[str]
37
+ "Solver_settings" : callable(replicate) -> dict
38
+ "Update_parameters": callable(RoadRunner_instance, replicate, mode) -> dict
39
+ "Loss_config" : callable(replicate) -> dict
40
+ "Opt_group" : str
41
+
42
+ 'callable' functions are contained in separate files with the same name as the key.
43
+ For example, "Events" is contained in the file "Events.py", "Data" is contained in
44
+ the file "Data.py", etc.
45
+
46
+ 'replicate' is the output of make_replicate. It contains the dictionary above plus
47
+ any optional keyword arguments.
48
+
49
+ Any arguments required by the 'callable' functions should be passed as keyword arguments.
50
+
51
+ Keyword arguments are stored in 'replicate' as additional keys. Example arguments:
52
+ Age = 70, Status = True, Population = "Amyloid_negative", Drug = "Lecanemab",
53
+ dose_nmol = 10, Schedule = "default", Type = "default", …
54
+
55
+ Example::
56
+
57
+ make_replicate(
58
+ {
59
+ "Label": "Example_1",
60
+ "Events": generate_no_events,
61
+ "Data": load_data_Example,
62
+ "Observed_species": observed_Example,
63
+ "Solver_settings": solver_settings_Example,
64
+ "Update_parameters": update_no_parameters,
65
+ "Loss_config": Example_loss_config,
66
+ "Opt_group": opt_group
67
+ },
68
+ )
69
+ """
70
+ entry = dict(config)
71
+ return {**entry, **meta}
72
+
73
+ # ***************************************************************************
74
+ # USER DEFINED OPTIMIZATION
75
+ # ***************************************************************************
76
+
77
+ # Build each replicate so that each element described in the
78
+ # make_replicate function has a value.
79
+ # It can be helpful (but not required) to define experimental groups
80
+ # and treatments (conditions) as separate dictionaries, and then
81
+ # build each replicate by combining elements from the experimental groups
82
+ # and treatments. "params" are used to pass arguments to the 'callable' functions.
83
+ # The "opt_group" is a string that defines which replicates are optimized
84
+ # together, each contributing to the total loss function value when their
85
+ # "Opt_group" valuse are the same. For example, if "Opt_group" is "ADneg" for
86
+ # "Early" and "Late", then the loss function will be calculated for both
87
+ # "Early" and "Late" replicates.
88
+ # The "Label" should be unique for each replicate, although not required.
89
+ # The "replicate" designation implies an experimental replicate, but it is rare
90
+ # to optimize at the replicate level. Typically, replicates are handled at
91
+ # the "Data" level, with all replicates' data fit simultaneously.
92
+
93
+
94
+
95
+ def _build_experiment():
96
+ # Initialize Experiment class object
97
+ exp = Experiment()
98
+
99
+ # Treatments are typically linked to events, but other settings can also be linked.
100
+ # In the example below, "loss_config" is also linked to the treatment because
101
+ # the data loaded depends on the treatment.
102
+ # Treatment types may also comprise the 'opt_group' in some cases.
103
+ treatments = {
104
+ "Early": {"params": {"dose": 10, "delay": 5}},
105
+ "Late": {"params": {"dose": 5, "delay": 10}},
106
+ }
107
+
108
+ # Experimental groups are not always necessary but are natural for some
109
+ # experimental designs. For example, when studying the effect of a treatment
110
+ # in different populations.
111
+ exp_groups = {
112
+ "ADneg": {"opt_group": "ADneg", "params": {"amyloid_positive": False}},
113
+ "ADpos": {"opt_group": "ADpos", "params": {"amyloid_positive": True}}
114
+ }
115
+
116
+ for exp_group_name, exp_group_data in exp_groups.items():
117
+ opt_group = exp_group_data.get("opt_group", exp_group_name)
118
+ exp_params = exp_group_data.get("params", {})
119
+ for treatment_name, treatment_data in treatments.items():
120
+ treatment_params = treatment_data.get("params", {})
121
+
122
+ key = f"{exp_group_name}__{treatment_name}"
123
+
124
+ replicate = make_replicate(
125
+ {
126
+ "Label": key,
127
+ "Events": Example_event,
128
+ "Data": load_ad_data,
129
+ "Observed_species": all_species,
130
+ "Solver_settings": solver_settings_Example,
131
+ "Update_parameters": update_Example,
132
+ "Loss_config": Example_loss_config_AD,
133
+ "Opt_group": opt_group,
134
+ },
135
+ **exp_params,
136
+ **treatment_params
137
+ )
138
+
139
+ # Store replicate in the flat registry and nested structure
140
+ exp.replicates[key] = replicate
141
+
142
+ return exp
143
+
144
+ EXPERIMENT_Example = _build_experiment()
145
+
146
+ # ***************************************************************************
147
+ # END USER DEFINED EXPERIMENTS
148
+ # ***************************************************************************
149
+
150
+ # ---------------------------------------------------------------------------
151
+ # Registry accessors
152
+ # ---------------------------------------------------------------------------
153
+
154
+ def get_experiments():
155
+ """Returns a dict mapping experiment name -> experiment dict."""
156
+ return {k: v for k, v in globals().items() if k.startswith('EXPERIMENT_')}
157
+
158
+ def get_experiment(name):
159
+ """Returns an experiment dict by name."""
160
+ return globals().get(name)
@@ -0,0 +1,12 @@
1
+ def no_optimization(replicate):
2
+ return {}
3
+
4
+ def Example_loss_config_AD(replicate):
5
+ label = replicate["Label"]
6
+ return {"observables": [{
7
+ "observed_variable": "predicted_B",
8
+ "data_column": "B",
9
+ "time_column": "time",
10
+ "data_dict_key": label,
11
+ }]}
12
+
@@ -0,0 +1,3 @@
1
+ def all_species(r):
2
+ observed_species = ['time'] + list(r.getFloatingSpeciesIds()) + list(r.getBoundarySpeciesIds()) + list(r.getAssignmentRuleIds()) + list(r.getGlobalParameterIds())
3
+ return observed_species
@@ -0,0 +1,25 @@
1
+ OPTIMIZATION_SETTINGS = {
2
+
3
+ "Example": {
4
+ "ADneg": {
5
+ "param_names": ["k_A_to_B", "SF"],
6
+ "x0": [0.5, 2.0],
7
+ "bounds": [(0.01, 10.0), (0.01, 10.0)],
8
+ "method": "Nelder-Mead",
9
+ "optimizer_kwargs": {"options": {"maxiter": 500}},
10
+ "wald_analysis": False,
11
+ "slice_analysis": True,
12
+ "profile_likelihood_analysis": False,
13
+ },
14
+ "ADpos": {
15
+ "param_names": ["k_A_to_B", "SF"],
16
+ "x0": [0.5, 2.0],
17
+ "bounds": [(0.01, 10.0), (0.01, 10.0)],
18
+ "method": "Nelder-Mead",
19
+ "optimizer_kwargs": {"options": {"maxiter": 500}},
20
+ "wald_analysis": False,
21
+ "slice_analysis": False,
22
+ "profile_likelihood_analysis": False,
23
+ },
24
+ }
25
+ }
@@ -0,0 +1,51 @@
1
+ import matplotlib.pyplot as plt
2
+ import matplotlib.gridspec as gridspec
3
+ import os
4
+ import numpy as np
5
+
6
+
7
+ def plot_results(paths, results_dict):
8
+ """
9
+ Plot simulation results for N experiments.
10
+
11
+ Args:
12
+ plot_path: Directory to save the plot.
13
+ MODEL_NAME: Model name for title/filename.
14
+ results: List of dicts from Experiment.run_all: each has "result", "data", "label".
15
+ """
16
+
17
+ plot_path = paths["plot_path"]
18
+ MODEL_NAME = paths["MODEL_NAME"]
19
+ repo_root = paths["repo_root"]
20
+ n = max(len(results_dict), 1)
21
+ color_A = ["blue","green","cyan","black"]
22
+ color_B = ["red","orange","purple","brown"]
23
+ fig = plt.figure(figsize=(10, 10))
24
+ gs = gridspec.GridSpec(1, 1, figure=fig, hspace=0.5, wspace=0.35)
25
+ ax = fig.add_subplot(gs[0, 0])
26
+ for i, (label, item) in enumerate(results_dict.items()):
27
+
28
+ results = item["results"]
29
+ data_dict = item["data"]
30
+
31
+ data = data_dict[f"{label}"]
32
+
33
+ time_points = results["time"]
34
+
35
+ ax.plot(time_points, results["predicted_A"], label=f"[A] {label}", color=color_A[i])
36
+ ax.plot(time_points, results["predicted_B"], label=f"[B] {label}", color=color_B[i])
37
+ if "time" in data.columns and "B" in data.columns:
38
+ ax.scatter(data["time"], data["B"], color=color_B[i], s=30, zorder=5, label=f"Measured [B] {label}")
39
+
40
+
41
+
42
+ ax.set_xlabel("Time")
43
+ ax.set_ylabel("Concentration")
44
+ ax.set_title("Simulation Results for " + MODEL_NAME)
45
+ ax.legend(loc="center left", bbox_to_anchor=(1.02, 0.5))
46
+ plt.subplots_adjust(right=0.65)
47
+ plot_name = os.path.join(plot_path, MODEL_NAME + ".png")
48
+ plt.savefig(plot_name, bbox_inches="tight")
49
+ print(f"Plot saved to: {plot_name}")
50
+ plt.show()
51
+
@@ -0,0 +1,15 @@
1
+ def make_solver_settings(blocks, abs_tol=1e-10, rel_tol=1e-10):
2
+ """Factory for solver settings dicts. Reduces boilerplate across all figure settings."""
3
+ return {
4
+ 'integrator': 'cvode',
5
+ 'absolute_tolerance': abs_tol,
6
+ 'relative_tolerance': rel_tol,
7
+ 'stiff': True,
8
+ 'variable_step_size': True,
9
+ 'simulation_blocks': blocks,
10
+ }
11
+
12
+ def solver_settings_Example(replicate):
13
+ return make_solver_settings(
14
+ {'block1': {'start': 0, 'end': 48, 'n_points': 1000, 'abs_tol':1e-12, 'rel_tol':1e-12}}
15
+ )
@@ -0,0 +1,26 @@
1
+ # Update_parameters.py is used in these cases:
2
+ # 1. The base parameters change from one treatment to another
3
+ # 2. The base parameters change from one replicate to another
4
+ # 3. The base parameters are modified by events during the treatment
5
+ # Update_parameters is called after the parameters are set, but before the simulation is run.
6
+ # The function does not need to return anything, but modifies the parameters in the
7
+ # RoadRunner instance (r).
8
+ # Keyword arguments are passed to the function as meta data.
9
+ #
10
+ # Example:
11
+ #
12
+ # def update_parameters(r, replicate):
13
+ # dose = replicate.get("dose", 10)
14
+ # r.A_Comp1 = dose
15
+ #
16
+
17
+
18
+
19
+ def update_no_parameters(r, replicate, mode):
20
+ return {}
21
+
22
+ def update_Example(r, replicate, mode):
23
+ if mode == "Simulator":
24
+ if replicate["amyloid_positive"]:
25
+ r['k_A_to_B'] = 0.2
26
+ return {}
@@ -0,0 +1,27 @@
1
+ Treatment,time,B1,B2,B3
2
+ Early,0,0.38342206790138894,0.091549388,0.5900498343353935
3
+ Early,4,0.2703454588887822,0.17383910077895837,0.6020884589334081
4
+ Early,8,2.296824911197708,2.487658225541256,2.293891968985253
5
+ Early,12,5.277374209126811,5.601574235385922,5.1235773990747475
6
+ Early,16,6.294924781277804,6.741032603463997,6.207362167461668
7
+ Early,20,7.627622224028859,7.827731764768038,7.637070537276994
8
+ Early,24,8.095154334660107,8.483255473019799,8.632232828229437
9
+ Early,28,8.824407618146214,9.305510261116316,8.776431868004604
10
+ Early,32,9.577892749513929,9.121325348548881,9.481106334
11
+ Early,36,9.803956887789985,8.999973449725445,9.596915791033005
12
+ Early,40,9.972862529,9.945594885,9.674311540321838
13
+ Early,44,9.367666080270844,10.008398237577786,9.880527147349609
14
+ Early,48,9.655247074718085,10.145675796028533,9.929383743361324
15
+ Late,0,0.1791263071636229,0.10003528830134165,0.12159208964547695
16
+ Late,4,0.19491688193363405,0.12378603847264884,0.2462734469696091
17
+ Late,8,0.092482469,0.29851688388349296,0.19202822519921844
18
+ Late,12,0.7697289334950888,0.6124998769902201,1.318366837872463
19
+ Late,16,2.418552127081854,2.4872151677545156,2.5537485789706498
20
+ Late,20,2.5945616441206996,2.6845832675225005,3.1989915955519637
21
+ Late,24,3.5197094831506863,4.049684883564003,3.848379545818031
22
+ Late,28,4.095113399003736,4.132972884332342,3.9449664938773834
23
+ Late,32,4.557037667813649,4.4178217770342565,4.252760815246755
24
+ Late,36,4.498622402962995,4.424129799453062,4.968822520193124
25
+ Late,40,4.796580380353387,4.575674896370977,4.614222306643472
26
+ Late,44,4.9971092743924075,4.492494963763387,5.129134868989082
27
+ Late,48,5.067487553321051,5.042477656094307,4.6794104140856545