diff --git a/biosimulator_processes/steps/ode_simulation.py b/biosimulator_processes/steps/ode_simulation.py index d24a6675f..9dc5e4c70 100644 --- a/biosimulator_processes/steps/ode_simulation.py +++ b/biosimulator_processes/steps/ode_simulation.py @@ -4,45 +4,89 @@ from process_bigraph.experiments.parameter_scan import RunProcess from biosimulator_processes import CORE +from biosimulator_processes.utils import calc_num_steps, calc_duration, calc_step_size class OdeSimulation(Step, abc.ABC): config_schema = { 'sbml_filepath': 'string', - 'n_steps': 'integer', - 'step_size': 'float', - 'duration': { - '_type': 'string', - '_default': 10} + 'time_config': { + 'step_size': 'maybe[float]', + 'num_steps': 'maybe[float]', + 'duration': 'maybe[float]' + } } def __init__(self, config=None, core=None): super().__init__(config, core) + assert len(list(self.config['time_config'].values())) >= 2, "you must pass two of either: step size, n steps, or duration." + self.step_size = self.config.get('step_size') + self.num_steps = self.config.get('num_steps') + self.duration = self.config.get('duration') + self._set_time_params() + + def _set_time_params(self): + if self.step_size and self.num_steps: + self.duration = calc_duration(self.num_steps, self.step_size) + elif self.step_size and self.duration: + self.num_steps = calc_num_steps(self.duration, self.step_size) + else: + self.step_size = calc_step_size(self.duration, self.num_steps) + @abc.abstractmethod - def inputs(self): + def _set_simulator(self, sbml_fp: str) -> object: + """Load simulator instance""" pass @abc.abstractmethod - def outputs(self): + def _get_floating_species_ids(self) -> list[str]: + """Sim specific method""" pass - def update(self, inputs): + '''@abc.abstractmethod + def _set_floating_species(self): + """Sim specific method for starting values relative to this property.""" pass @abc.abstractmethod - def set_species_list(self): + def _set_global_parameters(self): + """Sim specific method for starting values relative to this property.""" pass @abc.abstractmethod - def set_global_parameters(self): - pass + def _set_reactions(self): + """Sim specific method for starting values relative to this property.""" + pass''' + + def inputs(self): + """For now, none""" + return {} + + def outputs(self): + return { + 'time': 'float', + 'floating_species': { + spec_id: 'float' + for spec_id in self.floating_species_ids + } + } @abc.abstractmethod - def set_reactions(self): + def update(self, inputs): + """Iteratively update over self.floating_species_ids as per the requirements of the simulator library.""" pass + + + + + + + + + class ODEProcess(RunProcess): def __init__(self, address: str, diff --git a/biosimulator_processes/utils.py b/biosimulator_processes/utils.py index c02032a72..4aa29d5ad 100644 --- a/biosimulator_processes/utils.py +++ b/biosimulator_processes/utils.py @@ -8,6 +8,18 @@ import nbformat +def calc_num_steps(dur, step_size): + return dur / step_size + + +def calc_duration(n_steps, step_size): + return n_steps * step_size + + +def calc_step_size(dur, n_steps): + return dur / n_steps + + def register_module(items_to_register: List[Tuple[str, str]], core: ProcessTypes) -> None: for process_name, path in items_to_register: module_name, class_name = path.rsplit('.', 1) diff --git a/demos/ode_process_demo.ipynb b/demos/ode_process_demo.ipynb index 47c7617cb..47cd97db4 100644 --- a/demos/ode_process_demo.ipynb +++ b/demos/ode_process_demo.ipynb @@ -6,13 +6,14 @@ "metadata": { "collapsed": true, "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.234190Z", - "start_time": "2024-05-26T18:47:34.708184Z" + "end_time": "2024-05-26T22:01:18.142414Z", + "start_time": "2024-05-26T22:01:16.150749Z" } }, "source": [ "import sys\n", - "import os \n", + "import os\n", + "import tempfile\n", "\n", "import numpy as np\n", "from process_bigraph import pp\n", @@ -69,8 +70,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.237044Z", - "start_time": "2024-05-26T18:47:36.235328Z" + "end_time": "2024-05-26T22:01:18.145262Z", + "start_time": "2024-05-26T22:01:18.143492Z" } }, "cell_type": "code", @@ -87,8 +88,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.295379Z", - "start_time": "2024-05-26T18:47:36.237603Z" + "end_time": "2024-05-26T22:01:18.206773Z", + "start_time": "2024-05-26T22:01:18.145890Z" } }, "cell_type": "code", @@ -109,8 +110,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.350706Z", - "start_time": "2024-05-26T18:47:36.296031Z" + "end_time": "2024-05-26T22:01:18.262359Z", + "start_time": "2024-05-26T22:01:18.207352Z" } }, "cell_type": "code", @@ -133,21 +134,37 @@ { "metadata": { "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.354084Z", - "start_time": "2024-05-26T18:47:36.352268Z" + "end_time": "2024-05-26T22:01:18.265598Z", + "start_time": "2024-05-26T22:01:18.263847Z" + } + }, + "cell_type": "code", + "source": [ + "def generate_ode_output(process_address: str, model_fp: str, step_size: float, duration: float):\n", + " pass\n" + ], + "id": "d420c3e7fcd6d001", + "outputs": [], + "execution_count": 5 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:01:18.267683Z", + "start_time": "2024-05-26T22:01:18.266336Z" } }, "cell_type": "code", "source": "from biosimulator_processes.instance import plot_ode_output_data", "id": "a7cf4c427f5eeafc", "outputs": [], - "execution_count": 5 + "execution_count": 6 }, { "metadata": { "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.445755Z", - "start_time": "2024-05-26T18:47:36.354856Z" + "end_time": "2024-05-26T22:01:18.360169Z", + "start_time": "2024-05-26T22:01:18.268189Z" } }, "cell_type": "code", @@ -165,20 +182,379 @@ "output_type": "display_data" } ], - "execution_count": 6 + "execution_count": 7 }, { "metadata": { "ExecuteTime": { - "end_time": "2024-05-26T18:47:36.447869Z", - "start_time": "2024-05-26T18:47:36.446498Z" + "end_time": "2024-05-26T22:07:26.656611Z", + "start_time": "2024-05-26T22:07:26.624041Z" } }, "cell_type": "code", - "source": "", + "source": [ + "from basico import *\n", + "\n", + "mod = load_model(model_fp)\n", + "copasi_species = get_species(model=mod)\n", + "\n", + "run_time_course(\n", + " start_time=0,\n", + " duration=duration,\n", + " step_number=400,\n", + " update_model=True,\n", + " model=mod)" + ], "id": "2886af0283eb3da3", + "outputs": [ + { + "data": { + "text/plain": [ + " T E I\n", + "Time \n", + "0.0 1.000000 1.000000 1.000000\n", + "0.1 1.018163 0.999020 0.367911\n", + "0.2 1.036655 0.998079 0.135378\n", + "0.3 1.055484 0.997178 0.049835\n", + "0.4 1.074654 0.996318 0.018366\n", + "... ... ... ...\n", + "9.6 5.629215 1.214479 0.000325\n", + "9.7 5.731456 1.222184 0.000333\n", + "9.8 5.835554 1.230073 0.000342\n", + "9.9 5.941543 1.238147 0.000350\n", + "10.0 6.049457 1.246411 0.000359\n", + "\n", + "[101 rows x 3 columns]" + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TEI
Time
0.01.0000001.0000001.000000
0.11.0181630.9990200.367911
0.21.0366550.9980790.135378
0.31.0554840.9971780.049835
0.41.0746540.9963180.018366
............
9.65.6292151.2144790.000325
9.75.7314561.2221840.000333
9.85.8355541.2300730.000342
9.95.9415431.2381470.000350
10.06.0494571.2464110.000359
\n", + "

101 rows × 3 columns

\n", + "
" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 33 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:05:23.731828Z", + "start_time": "2024-05-26T22:05:23.693209Z" + } + }, + "cell_type": "code", + "source": [ + "import tellurium as te \n", + "\n", + "\n", + "te_species = te.loadSBMLModel(model_fp)\n", + "\n", + "te_species" + ], + "id": "e9951c5649df807d", + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 29 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:08:39.576882Z", + "start_time": "2024-05-26T22:08:39.572141Z" + } + }, + "cell_type": "code", + "source": [ + "results = te.one\n", + "\n", + "results" + ], + "id": "ad4080ec3af147fd", + "outputs": [ + { + "data": { + "text/plain": [ + " time, [T], [E], [I]\n", + " [[ 0, 656918, 89984.6, 13830.3],\n", + " [ 0.2, 668492, 92089.4, 14156.2],\n", + " [ 0.4, 680126, 94227.7, 14487.3],\n", + " [ 0.6, 691817, 96399.7, 14823.6],\n", + " [ 0.8, 703559, 98605.4, 15165.2],\n", + " [ 1, 715348, 100845, 15512.1],\n", + " [ 1.2, 727179, 103118, 15864.2],\n", + " [ 1.4, 739048, 105425, 16221.6],\n", + " [ 1.6, 750949, 107765, 16584.2],\n", + " [ 1.8, 762876, 110139, 16952.1],\n", + " [ 2, 774824, 112547, 17325.2],\n", + " [ 2.2, 786787, 114987, 17703.5],\n", + " [ 2.4, 798760, 117461, 18087],\n", + " [ 2.6, 810736, 119968, 18475.6],\n", + " [ 2.8, 822709, 122507, 18869.4],\n", + " [ 3, 834672, 125079, 19268.3],\n", + " [ 3.2, 846621, 127683, 19672.2],\n", + " [ 3.4, 858546, 130320, 20081.1],\n", + " [ 3.6, 870442, 132988, 20495],\n", + " [ 3.8, 882302, 135687, 20913.9],\n", + " [ 4, 894119, 138418, 21337.6],\n", + " [ 4.2, 905884, 141179, 21766.1],\n", + " [ 4.4, 917591, 143970, 22199.4],\n", + " [ 4.6, 929231, 146792, 22637.4],\n", + " [ 4.8, 940797, 149643, 23080],\n", + " [ 5, 952281, 152522, 23527.1],\n", + " [ 5.2, 963674, 155430, 23978.7],\n", + " [ 5.4, 974968, 158366, 24434.7],\n", + " [ 5.6, 986155, 161330, 24895],\n", + " [ 5.8, 997225, 164319, 25359.5],\n", + " [ 6, 1.00817e+06, 167335, 25828.1],\n", + " [ 6.2, 1.01898e+06, 170376, 26300.7],\n", + " [ 6.4, 1.02965e+06, 173442, 26777.2],\n", + " [ 6.6, 1.04016e+06, 176532, 27257.5],\n", + " [ 6.8, 1.05051e+06, 179645, 27741.4],\n", + " [ 7, 1.06069e+06, 182780, 28228.9],\n", + " [ 7.2, 1.07068e+06, 185937, 28719.8],\n", + " [ 7.4, 1.08049e+06, 189114, 29213.9],\n", + " [ 7.6, 1.09009e+06, 192311, 29711.2],\n", + " [ 7.8, 1.09948e+06, 195527, 30211.5],\n", + " [ 8, 1.10864e+06, 198760, 30714.6],\n", + " [ 8.2, 1.11757e+06, 202010, 31220.4],\n", + " [ 8.4, 1.12626e+06, 205276, 31728.7],\n", + " [ 8.6, 1.13469e+06, 208557, 32239.4],\n", + " [ 8.8, 1.14285e+06, 211850, 32752.3],\n", + " [ 9, 1.15074e+06, 215157, 33267.1],\n", + " [ 9.2, 1.15833e+06, 218474, 33783.8],\n", + " [ 9.4, 1.16563e+06, 221801, 34302.1],\n", + " [ 9.6, 1.17262e+06, 225137, 34821.8],\n", + " [ 9.8, 1.17928e+06, 228480, 35342.7],\n", + " [ 10, 1.1856e+06, 231829, 35864.6]]" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 41 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:18:26.874317Z", + "start_time": "2024-05-26T22:18:26.871998Z" + } + }, + "cell_type": "code", + "source": [ + "dur = 50\n", + "n_steps = 500\n", + "step_size = dur / n_steps" + ], + "id": "15592b512cbb2fea", "outputs": [], - "execution_count": 6 + "execution_count": 42 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:18:28.458298Z", + "start_time": "2024-05-26T22:18:28.454846Z" + } + }, + "cell_type": "code", + "source": "step_size", + "id": "bb0d94a39fa7b883", + "outputs": [ + { + "data": { + "text/plain": [ + "0.1" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 43 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:19:08.183306Z", + "start_time": "2024-05-26T22:19:08.181172Z" + } + }, + "cell_type": "code", + "source": "duration = n_steps * step_size", + "id": "aa9545e2ff029ffe", + "outputs": [], + "execution_count": 45 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:19:09.871208Z", + "start_time": "2024-05-26T22:19:09.867612Z" + } + }, + "cell_type": "code", + "source": "duration", + "id": "73f900a6bb824777", + "outputs": [ + { + "data": { + "text/plain": [ + "50.0" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 46 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2024-05-26T22:19:36.146746Z", + "start_time": "2024-05-26T22:19:36.143214Z" + } + }, + "cell_type": "code", + "source": "num_steps = dur / step_size", + "id": "e290256ae57459be", + "outputs": [ + { + "data": { + "text/plain": [ + "500.0" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 47 + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": "", + "id": "41d39fd666ca1acd" } ], "metadata": {