diff --git a/notebooks/comets.ipynb b/notebooks/comets.ipynb new file mode 100644 index 0000000..c188587 --- /dev/null +++ b/notebooks/comets.ipynb @@ -0,0 +1,1711 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0094fcaa-a07c-454d-803a-9fd2bb3bb535", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/Users/eranagmon/code/process-bigraph/venv/bin/python'" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import sys\n", + "sys.executable" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "initial_id", + "metadata": { + "ExecuteTime": { + "end_time": "2024-07-09T22:07:58.941647Z", + "start_time": "2024-07-09T22:07:52.700195Z" + } + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "from process_bigraph import Process, ProcessTypes, Composite\n", + "import matplotlib.pyplot as plt\n", + "import cobra\n", + "from cobra.io import load_model\n", + "from scipy.ndimage import convolve\n", + "\n", + "core = ProcessTypes()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3e25a40151d79237", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:02.085129Z", + "start_time": "2024-06-18T22:20:02.082276Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "# create new types\n", + "def apply_non_negative(schema, current, update, core):\n", + " new_value = current + update\n", + " return max(0, new_value)\n", + "\n", + "positive_float = {\n", + " '_type': 'positive_float',\n", + " '_inherit': 'float',\n", + " '_apply': apply_non_negative\n", + "}\n", + "core.register('positive_float', positive_float)\n", + "\n", + "bounds_type = {\n", + " 'lower': 'maybe[float]',\n", + " 'upper': 'maybe[float]'\n", + "}\n", + "core.register_process('bounds', bounds_type)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "c943852149550230", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:02.089537Z", + "start_time": "2024-06-18T22:20:02.085807Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'_type': 'positive_float',\n", + " '_check': 'check_float',\n", + " '_apply': 'apply_non_negative',\n", + " '_serialize': 'to_string',\n", + " '_description': '64-bit floating point precision number',\n", + " '_default': '0.0',\n", + " '_deserialize': 'deserialize_float',\n", + " '_divide': 'divide_float',\n", + " '_dataclass': 'dataclass_float',\n", + " '_inherit': ['float']}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "core.access('positive_float')" + ] + }, + { + "cell_type": "markdown", + "id": "bf3158b287046687", + "metadata": { + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "source": [ + "## Dynamic FBA Process" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "50a4fb171d2aafa5", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:02.096869Z", + "start_time": "2024-06-18T22:20:02.090609Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "class DynamicFBA(Process):\n", + " \"\"\"\n", + " Performs dynamic FBA.\n", + "\n", + " Parameters:\n", + " - model: The metabolic model for the simulation.\n", + " - kinetic_params: Kinetic parameters (Km and Vmax) for each substrate.\n", + " - biomass_reaction: The identifier for the biomass reaction in the model.\n", + " - substrate_update_reactions: A dictionary mapping substrates to their update reactions.\n", + " - biomass_identifier: The identifier for biomass in the current state.\n", + "\n", + " TODO -- check units\n", + " \"\"\"\n", + "\n", + " config_schema = {\n", + " 'model_file': 'string',\n", + " 'kinetic_params': 'map[tuple[float,float]]',\n", + " 'biomass_reaction': {\n", + " '_type': 'string',\n", + " '_default': 'Biomass_Ecoli_core'\n", + " },\n", + " 'substrate_update_reactions': 'map[string]',\n", + " 'biomass_identifier': 'string',\n", + " 'bounds': 'map[bounds]',\n", + " }\n", + "\n", + " def __init__(self, config, core):\n", + " super().__init__(config, core)\n", + "\n", + " if not 'xml' in self.config['model_file']:\n", + " # use the textbook model if no model file is provided\n", + " self.model = load_model(self.config['model_file'])\n", + " else:\n", + " self.model = cobra.io.read_sbml_model(self.config['model_file'])\n", + "\n", + " for reaction_id, bounds in self.config['bounds'].items():\n", + " if bounds['lower'] is not None:\n", + " self.model.reactions.get_by_id(reaction_id).lower_bound = bounds['lower']\n", + " if bounds['upper'] is not None:\n", + " self.model.reactions.get_by_id(reaction_id).upper_bound = bounds['upper']\n", + "\n", + " def inputs(self):\n", + " return {\n", + " 'substrates': 'map[positive_float]'\n", + " }\n", + "\n", + " def outputs(self):\n", + " return {\n", + " 'substrates': 'map[positive_float]'\n", + " }\n", + "\n", + " # TODO -- can we just put the inputs/outputs directly in the function?\n", + " def update(self, state, interval):\n", + " substrates_input = state['substrates']\n", + "\n", + " for substrate, reaction_id in self.config['substrate_update_reactions'].items():\n", + " Km, Vmax = self.config['kinetic_params'][substrate]\n", + " substrate_concentration = substrates_input[substrate]\n", + " uptake_rate = Vmax * substrate_concentration / (Km + substrate_concentration)\n", + " self.model.reactions.get_by_id(reaction_id).lower_bound = -uptake_rate\n", + "\n", + " substrate_update = {}\n", + "\n", + " solution = self.model.optimize()\n", + " if solution.status == 'optimal':\n", + " current_biomass = substrates_input[self.config['biomass_identifier']]\n", + " biomass_growth_rate = solution.fluxes[self.config['biomass_reaction']]\n", + " substrate_update[self.config['biomass_identifier']] = biomass_growth_rate * current_biomass * interval\n", + "\n", + " for substrate, reaction_id in self.config['substrate_update_reactions'].items():\n", + " flux = solution.fluxes[reaction_id]\n", + " substrate_update[substrate] = flux * current_biomass * interval\n", + " # TODO -- assert not negative?\n", + " else:\n", + " # Handle non-optimal solutions if necessary\n", + " # print('Non-optimal solution, skipping update')\n", + " for substrate, reaction_id in self.config['substrate_update_reactions'].items():\n", + " substrate_update[substrate] = 0\n", + "\n", + " return {\n", + " 'substrates': substrate_update,\n", + " }\n", + "\n", + "core.register_process('DynamicFBA', DynamicFBA)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ef2fc9363b163d21", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:02.118565Z", + "start_time": "2024-06-18T22:20:02.098708Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "from process_bigraph.experiments.parameter_scan import RunProcess\n", + "\n", + "def dfba_config(\n", + " model_file='textbook',\n", + " kinetic_params={\n", + " 'glucose': (0.5, 1),\n", + " 'acetate': (0.5, 2)},\n", + " biomass_reaction='Biomass_Ecoli_core',\n", + " substrate_update_reactions={\n", + " 'glucose': 'EX_glc__D_e',\n", + " 'acetate': 'EX_ac_e'},\n", + " biomass_identifier='biomass',\n", + " bounds={\n", + " 'EX_o2_e': {'lower': -2, 'upper': None},\n", + " 'ATPM': {'lower': 1, 'upper': 1}}\n", + "):\n", + " return {\n", + " 'model_file': model_file,\n", + " 'kinetic_params': kinetic_params,\n", + " 'biomass_reaction': biomass_reaction,\n", + " 'substrate_update_reactions': substrate_update_reactions,\n", + " 'biomass_identifier': biomass_identifier,\n", + " 'bounds': bounds\n", + " }\n", + "\n", + "\n", + "# TODO -- this should be imported, or just part of Process?\n", + "def run_process(\n", + " address,\n", + " config,\n", + " core_type,\n", + " initial_state,\n", + " observables,\n", + " timestep=1,\n", + " runtime=10\n", + "):\n", + " config = {\n", + " 'process_address': address,\n", + " 'process_config': config,\n", + " 'observables': observables,\n", + " 'timestep': timestep,\n", + " 'runtime': runtime}\n", + "\n", + " run = RunProcess(config, core_type)\n", + " return run.update(initial_state)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "33923108a654be95", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:03.448389Z", + "start_time": "2024-06-18T22:20:02.119565Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "n_bins = (5, 5)\n", + "\n", + "initial_glucose = np.random.uniform(low=0, high=20, size=n_bins)\n", + "initial_acetate = np.random.uniform(low=0, high=0, size=n_bins)\n", + "initial_biomass = np.random.uniform(low=0, high=0.1, size=n_bins)\n", + "\n", + "dfba_processes_dict = {}\n", + "for i in range(n_bins[0]):\n", + " for j in range(n_bins[1]):\n", + " dfba_processes_dict[f'[{i},{j}]'] = {\n", + " '_type': 'process',\n", + " 'address': 'local:DynamicFBA',\n", + " 'config': dfba_config(),\n", + " 'inputs': {\n", + " 'substrates': {\n", + " 'glucose': ['..', 'fields', 'glucose', i, j],\n", + " 'acetate': ['..', 'fields', 'acetate', i, j],\n", + " 'biomass': ['..', 'fields', 'biomass', i, j],\n", + " }\n", + " },\n", + " 'outputs': {\n", + " 'substrates': {\n", + " 'glucose': ['..', 'fields', 'glucose', i, j],\n", + " 'acetate': ['..', 'fields', 'acetate', i, j],\n", + " 'biomass': ['..', 'fields', 'biomass', i, j]\n", + " }\n", + " }\n", + " }\n", + "\n", + "composite_state = {\n", + " 'fields': {\n", + " '_type': 'map',\n", + " '_value': {\n", + " '_type': 'array',\n", + " '_shape': n_bins,\n", + " '_data': 'positive_float'\n", + " },\n", + " 'glucose': initial_glucose,\n", + " 'acetate': initial_acetate,\n", + " 'biomass': initial_biomass,\n", + " },\n", + " 'spatial_dfba': dfba_processes_dict,\n", + " 'emitter': {\n", + " '_type': 'step',\n", + " 'address': 'local:ram-emitter',\n", + " 'config': {\n", + " 'emit': {\n", + " 'fields': 'map',\n", + " 'time': 'float',\n", + " }\n", + " },\n", + " 'inputs': {\n", + " 'fields': ['fields'],\n", + " 'time': ['global_time']\n", + " }\n", + " }\n", + "}\n", + "\n", + "sim = Composite({'state': composite_state}, core=core)\n", + "\n", + "sim.update({}, 10.0)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e6157d21-e613-45dd-83cf-67e136c63d1e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'fields': {'glucose': array([[ 8.5526694 , 17.5842017 , 15.39583692, 7.60193967, 19.13203451],\n", + " [12.65809497, 12.21049038, 5.7792075 , 10.33968228, 19.25409282],\n", + " [ 3.14530227, 13.69455267, 1.14230224, 5.90495666, 10.12746262],\n", + " [13.03804887, 19.10655932, 10.22930332, 3.11076213, 8.7102663 ],\n", + " [ 1.26206527, 7.72923753, 3.72448763, 7.74081364, 3.94338213]]),\n", + " 'acetate': array([[0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0.]]),\n", + " 'biomass': array([[0.03124297, 0.0828025 , 0.06932402, 0.05347029, 0.06634931],\n", + " [0.06510462, 0.01836797, 0.07575297, 0.09252517, 0.05390586],\n", + " [0.03899395, 0.05617419, 0.00645221, 0.09252719, 0.02600646],\n", + " [0.08406056, 0.08744284, 0.04027866, 0.01781626, 0.08739853],\n", + " [0.08358264, 0.04685661, 0.01132015, 0.03643865, 0.02227665]])},\n", + " 'time': 0.0},\n", + " {'fields': {'glucose': array([[ 8.52315205, 17.50368856, 15.32869347, 7.55176922, 19.06737503],\n", + " [12.59546429, 12.19284496, 5.70948658, 10.251425 , 19.20155138],\n", + " [ 3.11165685, 13.64035721, 1.13781441, 5.81965257, 10.10267971],\n", + " [12.95709292, 19.02134642, 10.1909017 , 3.09541297, 8.6276124 ],\n", + " [ 1.20219987, 7.68522788, 3.7145073 , 7.70658586, 3.9236122 ]]),\n", + " 'acetate': array([[0.003308 , 0.01332736, 0.01063111, 0.0049695 , 0.01096793],\n", + " [0.00913333, 0.00252771, 0.00433095, 0.01147866, 0.00892789],\n", + " [0. , 0.0081917 , 0. , 0.00557878, 0.00317853],\n", + " [0.01197159, 0.01444904, 0.0049588 , 0. , 0.00941867],\n", + " [0. , 0.00444414, 0. , 0.00346225, 0. ]]),\n", + " 'biomass': array([[0.03371375, 0.08945563, 0.07488205, 0.05768298, 0.07168708],\n", + " [0.0703048 , 0.01983397, 0.0816589 , 0.09988102, 0.05824295],\n", + " [0.04187947, 0.06066822, 0.00683072, 0.09974753, 0.0280729 ],\n", + " [0.09077895, 0.09447744, 0.04347998, 0.01913251, 0.09431406],\n", + " [0.08864454, 0.05055028, 0.01217735, 0.03931123, 0.02397542]])},\n", + " 'time': 1.0},\n", + " {'fields': {'glucose': array([[ 8.49130648, 17.4167173 , 15.25617681, 7.49766825, 18.99751976],\n", + " [12.52784381, 12.17379229, 5.63440301, 10.156189 , 19.14478656],\n", + " [ 3.0755752 , 13.58183421, 1.13306901, 5.72779689, 10.07593067],\n", + " [12.86968687, 18.92928883, 10.14945523, 3.07894115, 8.53846475],\n", + " [ 1.13959356, 7.63776549, 3.70377465, 7.66966974, 3.90234672]]),\n", + " 'acetate': array([[0.00686545, 0.02770348, 0.02209462, 0.01028624, 0.02280618],\n", + " [0.01897066, 0.005255 , 0.00885379, 0.02379438, 0.01856625],\n", + " [0. , 0.0170224 , 0. , 0.01138304, 0.00660346],\n", + " [0.02485972, 0.03003947, 0.0102972 , 0. , 0.01949003],\n", + " [0. , 0.00920563, 0. , 0.00717758, 0. ]]),\n", + " 'biomass': array([[0.03637966, 0.09664283, 0.08088524, 0.06222654, 0.07745399],\n", + " [0.07591975, 0.02141693, 0.08802192, 0.10781993, 0.06292881],\n", + " [0.04497362, 0.06552139, 0.00723092, 0.10752648, 0.0303034 ],\n", + " [0.09803336, 0.10207748, 0.0469354 , 0.02054496, 0.10177467],\n", + " [0.09393191, 0.05453437, 0.01309914, 0.0424098 , 0.02580262]])},\n", + " 'time': 2.0},\n", + " {'fields': {'glucose': array([[ 8.45694987, 17.32277147, 15.17785835, 7.43933201, 18.92205202],\n", + " [12.45483781, 12.15322029, 5.55355554, 10.05342809, 19.08345941],\n", + " [ 3.03689058, 13.51863926, 1.12805199, 5.6289032 , 10.04705993],\n", + " [12.77531976, 18.82983825, 10.10472349, 3.06126644, 8.44232016],\n", + " [ 1.07430652, 7.58658182, 3.69223353, 7.6298555 , 3.87947466]]),\n", + " 'acetate': array([[0.01068995, 0.04320862, 0.03445366, 0.01596958, 0.03558261],\n", + " [0.02956363, 0.00819743, 0.01355585, 0.03699953, 0.02897083],\n", + " [0. , 0.02654028, 0. , 0.01738944, 0.0102933 ],\n", + " [0.03873023, 0.04685932, 0.01604279, 0. , 0.03024829],\n", + " [0. , 0.01430361, 0. , 0.01116245, 0. ]]),\n", + " 'biomass': array([[0.03925604, 0.10440688, 0.08736915, 0.06712679, 0.0836845 ],\n", + " [0.08198246, 0.02312616, 0.09487678, 0.1163878 , 0.06799145],\n", + " [0.0482906 , 0.07076236, 0.00765398, 0.11590632, 0.03271095],\n", + " [0.10586641, 0.11028832, 0.05066504, 0.02206048, 0.10982292],\n", + " [0.09943808, 0.05883157, 0.01409035, 0.04575207, 0.02776778]])},\n", + " 'time': 3.0},\n", + " {'fields': {'glucose': array([[ 8.41988519, 17.22129361, 15.09327559, 7.3764327 , 18.84052189],\n", + " [12.37601951, 12.13100798, 5.46651521, 9.94255451, 19.0172039 ],\n", + " [ 2.99542668, 13.45040077, 1.12274866, 5.52245259, 10.01589969],\n", + " [12.6734407 , 18.72240274, 10.05644724, 3.04230324, 8.33863787],\n", + " [ 1.00644999, 7.53138786, 3.67982372, 7.58691726, 3.8548771 ]]),\n", + " 'acetate': array([[0.01480011, 0.05992874, 0.04777577, 0.0220389 , 0.04937014],\n", + " [0.04096711, 0.01137172, 0.01841789, 0.05114784, 0.04020164],\n", + " [0. , 0.03679688, 0. , 0.02356413, 0.01426783],\n", + " [0.05365283, 0.06500295, 0.02222491, 0. , 0.04172688],\n", + " [0. , 0.01975762, 0. , 0.01543398, 0. ]]),\n", + " 'biomass': array([[0.04235947, 0.11279397, 0.09437219, 0.07241151, 0.09041582],\n", + " [0.0885285 , 0.02497173, 0.10226073, 0.12563407, 0.07346113],\n", + " [0.05184546, 0.07642203, 0.00810113, 0.12493234, 0.03530958],\n", + " [0.11432403, 0.11915894, 0.05469059, 0.0236864 , 0.11850461],\n", + " [0.10515175, 0.06346632, 0.01515613, 0.04935712, 0.0298811 ]])},\n", + " 'time': 4.0},\n", + " {'fields': {'glucose': array([[ 8.37990017, 17.11168209, 15.00192946, 7.30861792, 18.75244354],\n", + " [12.29092874, 12.10702476, 5.37282403, 9.82293593, 18.94562472],\n", + " [ 2.95099741, 13.3767178 , 1.11714364, 5.40789247, 9.98226898],\n", + " [12.56345585, 18.60634328, 10.00434704, 3.0219602 , 8.22683705],\n", + " [ 0.93619876, 7.47187268, 3.66648059, 7.54061181, 3.82842676]]),\n", + " 'acetate': array([[0.01921559, 0.07795583, 0.06213311, 0.02851334, 0.06424711],\n", + " [0.05323936, 0.01479586, 0.02341231, 0.06629397, 0.05232322],\n", + " [0. , 0.04784719, 0. , 0.02985999, 0.01854821],\n", + " [0.06970111, 0.0845715 , 0.02887467, 0. , 0.05395769],\n", + " [0. , 0.02558745, 0. , 0.02000991, 0. ]]),\n", + " 'biomass': array([[0.04570778, 0.12185397, 0.1019358 , 0.07811061, 0.09768813],\n", + " [0.09559626, 0.02696451, 0.1102137 , 0.13561199, 0.07937054],\n", + " [0.05565404, 0.08253375, 0.00857366, 0.13465297, 0.03811443],\n", + " [0.12345581, 0.12874225, 0.05903544, 0.02543052, 0.12786904],\n", + " [0.11105582, 0.06846497, 0.01630204, 0.05324548, 0.03215349]])},\n", + " 'time': 5.0},\n", + " {'fields': {'glucose': array([[ 8.33676605, 16.99328758, 14.90328149, 7.23550887, 18.65729244],\n", + " [12.19906936, 12.08112967, 5.27199369, 9.69389242, 18.86829502],\n", + " [ 2.90340684, 13.29715787, 1.11122084, 5.28463552, 9.94597259],\n", + " [12.44472528, 18.48097012, 9.94812165, 3.00013996, 8.10629421],\n", + " [ 0.86380604, 7.40770187, 3.65213488, 7.49067736, 3.79998749]]),\n", + " 'acetate': array([[0.02395706, 0.09738818, 0.0776027 , 0.03541136, 0.08029759],\n", + " [0.06644207, 0.01848921, 0.02850097, 0.08249279, 0.06540494],\n", + " [0. , 0.05974987, 0. , 0.03621289, 0.023157 ],\n", + " [0.08695249, 0.10567323, 0.03602504, 0. , 0.06696997],\n", + " [0. , 0.03181291, 0. , 0.02490847, 0. ]]),\n", + " 'biomass': array([[0.04932024, 0.13164072, 0.11010473, 0.08425628, 0.10554484],\n", + " [0.10322715, 0.02911622, 0.11877841, 0.14637892, 0.08575497],\n", + " [0.059733 , 0.08913352, 0.00907291, 0.14511998, 0.04114182],\n", + " [0.13331518, 0.13909536, 0.06372483, 0.02730116, 0.1379692 ],\n", + " [0.11712613, 0.07385585, 0.01753402, 0.0574393 , 0.03459663]])},\n", + " 'time': 6.0},\n", + " {'fields': {'glucose': array([[ 8.29023643, 16.86540947, 14.79675083, 7.15669867, 18.55450228],\n", + " [12.09990657, 12.05317058, 5.16350448, 9.55469323, 18.78475384],\n", + " [ 2.85244932, 13.21125449, 1.10496347, 5.15205911, 9.90680004],\n", + " [12.3165595 , 18.34553884, 9.88744641, 2.97673881, 7.9763406 ],\n", + " [ 0.78962082, 7.33851589, 3.63671231, 7.4368322 , 3.76941373]]),\n", + " 'acetate': array([[0.0290462 , 0.11833076, 0.09426657, 0.04275031, 0.09761177],\n", + " [0.08064041, 0.02247253, 0.03363235, 0.09979852, 0.07952137],\n", + " [0. , 0.07256737, 0. , 0.04253712, 0.02811824],\n", + " [0.10548815, 0.12842389, 0.04371079, 0. , 0.08078901],\n", + " [0. , 0.0384535 , 0. , 0.03014831, 0. ]]),\n", + " 'biomass': array([[0.05321758, 0.14221233, 0.11892726, 0.09088314, 0.11403282],\n", + " [0.11146583, 0.03143953, 0.12800058, 0.15799656, 0.09265255],\n", + " [0.06409982, 0.0962602 , 0.00960029, 0.15638862, 0.04440935],\n", + " [0.14395979, 0.15027993, 0.06878596, 0.02930719, 0.14886208],\n", + " [0.12332984, 0.07966947, 0.01885844, 0.06196242, 0.03722298]])},\n", + " 'time': 7.0},\n", + " {'fields': {'glucose': array([[ 8.24004594, 16.72729184, 14.68171091, 7.0717504 , 18.44346175],\n", + " [11.99286402, 12.02298331, 5.04680438, 9.40455353, 18.69450351],\n", + " [ 2.79790965, 13.11850455, 1.09835399, 5.00950515, 9.86452435],\n", + " [12.17821587, 18.19924606, 9.82197146, 2.95164638, 7.83625956],\n", + " [ 0.71410729, 7.26392834, 3.62013327, 7.37877326, 3.73655001]]),\n", + " 'acetate': array([[0.03450567, 0.1408954 , 0.11221202, 0.05054576, 0.11628631],\n", + " [0.09590296, 0.02676814, 0.03873807, 0.11826354, 0.09475253],\n", + " [0. , 0.08636606, 0. , 0.04871937, 0.03345753],\n", + " [0.12539278, 0.15294713, 0.05196857, 0. , 0.09543436],\n", + " [0. , 0.04552804, 0. , 0.03574824, 0. ]]),\n", + " 'biomass': array([[0.05742216, 0.15363154, 0.12845549, 0.09802844, 0.12320266],\n", + " [0.12036046, 0.0339481 , 0.13792902, 0.17053134, 0.10010445],\n", + " [0.06877275, 0.10395568, 0.01015726, 0.16851771, 0.04793603],\n", + " [0.15545178, 0.16236255, 0.07424818, 0.03145803, 0.16060888],\n", + " [0.12962371, 0.08593869, 0.02028211, 0.0668405 , 0.04004587]])},\n", + " 'time': 8.0},\n", + " {'fields': {'glucose': array([[ 8.18590879, 16.57811926, 14.55748602, 6.98019527, 18.32351094],\n", + " [11.87732073, 11.99039064, 4.92130856, 9.24263093, 18.59700669],\n", + " [ 2.73956361, 13.01836558, 1.09137415, 4.8562808 , 9.81890083],\n", + " [12.02889476, 18.04122493, 9.75131988, 2.9247453 , 7.68528383],\n", + " [ 0.63786589, 7.18352414, 3.6023125 , 7.31617456, 3.70123038]]),\n", + " 'acetate': array([[0.04035902, 0.16520109, 0.13153169, 0.05881069, 0.13642472],\n", + " [0.11230171, 0.03139999, 0.04372831, 0.13793684, 0.11118436],\n", + " [0. , 0.10121632, 0. , 0.05461097, 0.03920208],\n", + " [0.14675422, 0.17937477, 0.06083682, 0. , 0.11091752],\n", + " [0. , 0.05305413, 0. , 0.04172708, 0. ]]),\n", + " 'biomass': array([[0.06195807, 0.16596604, 0.13874564, 0.10573221, 0.13310902],\n", + " [0.12996297, 0.03665667, 0.1486158 , 0.18405467, 0.10815514],\n", + " [0.0737708 , 0.11226519, 0.01074534, 0.18156979, 0.05174234],\n", + " [0.1678581 , 0.17541506, 0.08014311, 0.03376371, 0.17327532],\n", + " [0.13595225, 0.09269881, 0.02181236, 0.0721012 , 0.0430795 ]])},\n", + " 'time': 9.0},\n", + " {'fields': {'glucose': array([[ 8.1275173 , 16.41701224, 14.42334757, 6.88153054, 18.19393764],\n", + " [11.75260781, 11.95520137, 4.78639939, 9.0680221 , 18.49168328],\n", + " [ 2.67717872, 12.91025271, 1.08400493, 4.69166025, 9.76966565],\n", + " [11.8677355 , 17.87054027, 9.6750857 , 2.89591097, 7.52259307],\n", + " [ 0.56165366, 7.09685764, 3.58315868, 7.24868567, 3.66327788]]),\n", + " 'acetate': array([[0.04663064, 0.1913742 , 0.15232374, 0.06755452, 0.15813769],\n", + " [0.12991183, 0.03639377, 0.04848602, 0.15886193, 0.12890896],\n", + " [0. , 0.11719266, 0. , 0.06001774, 0.04538073],\n", + " [0.16966296, 0.20784714, 0.07035575, 0. , 0.12723903],\n", + " [0. , 0.06104751, 0. , 0.04810332, 0. ]]),\n", + " 'biomass': array([[0.06685127, 0.17928891, 0.14985837, 0.11403747, 0.14381089],\n", + " [0.14032936, 0.03958117, 0.16011636, 0.19864332, 0.11685262],\n", + " [0.07911362, 0.1212375 , 0.01136611, 0.19561115, 0.05585039],\n", + " [0.18125093, 0.18951505, 0.08650483, 0.03623486, 0.1869319 ],\n", + " [0.1422459 , 0.09998782, 0.02345702, 0.07777426, 0.04633903]])},\n", + " 'time': 10.0}]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "results = sim.gather_results()[('emitter',)]\n", + "results" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e220f9251bb22532", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:03.452506Z", + "start_time": "2024-06-18T22:20:03.449442Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "# plot results\n", + "def plot_results(results):\n", + " fig, ax = plt.subplots()\n", + " for key, value in results['substrates'].items():\n", + " ax.plot(results['time'], value, label=key)\n", + " ax.legend()\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7ccc1e363e9bb98e", + "metadata": { + "ExecuteTime": { + "end_time": "2024-06-18T22:20:03.595004Z", + "start_time": "2024-06-18T22:20:03.453198Z" + }, + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } + }, + "outputs": [], + "source": [ + "# plot_results(results['results'])" + ] + }, + { + "cell_type": "markdown", + "id": "5ef5f3a7-6865-45a0-ab14-fb8c6d5b7eaf", + "metadata": {}, + "source": [ + "## Diffusion Advection Process" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "7264d1ae-f8b7-49bf-9550-a98cf5f95baf", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Laplacian for 2D diffusion\n", + "LAPLACIAN_2D = np.array([[0, 1, 0],\n", + " [1, -4, 1],\n", + " [0, 1, 0]])\n", + "\n", + "\n", + "class DiffusionAdvection(Process):\n", + " config_schema = {\n", + " 'n_bins': 'tuple[integer,integer]',\n", + " 'bounds': 'tuple[float,float]',\n", + " 'default_diffusion_rate': {'_type': 'float', '_default': 1e-1},\n", + " 'default_diffusion_dt': {'_type': 'float', '_default': 1e-1},\n", + " 'diffusion_coeffs': 'map[float]',\n", + " 'advection_coeffs': 'map[tuple[float,float]]',\n", + " }\n", + "\n", + " def __init__(self, config, core):\n", + " super().__init__(config, core)\n", + "\n", + " # get diffusion rates\n", + " bins_x = self.config['n_bins'][0]\n", + " bins_y = self.config['n_bins'][1]\n", + " length_x = self.config['bounds'][0]\n", + " length_y = self.config['bounds'][1]\n", + " dx = length_x / bins_x\n", + " dy = length_y / bins_y\n", + " dx2 = dx * dy\n", + "\n", + " # general diffusion rate\n", + " diffusion_rate = self.config['default_diffusion_rate']\n", + " self.diffusion_rate = diffusion_rate / dx2\n", + "\n", + " # diffusion rates for each individual molecules\n", + " self.molecule_specific_diffusion = {\n", + " mol_id: diff_rate / dx2\n", + " for mol_id, diff_rate in self.config['diffusion_coeffs'].items()}\n", + "\n", + " # get diffusion timestep\n", + " diffusion_dt = 0.5 * dx ** 2 * dy ** 2 / (2 * diffusion_rate * (dx ** 2 + dy ** 2))\n", + " self.diffusion_dt = min(diffusion_dt, self.config['default_diffusion_dt'])\n", + "\n", + " def inputs(self):\n", + " return {\n", + " 'fields': {\n", + " '_type': 'map',\n", + " '_value': {\n", + " '_type': 'array',\n", + " '_shape': self.config['n_bins'],\n", + " '_data': 'positive_float'\n", + " },\n", + " }\n", + " }\n", + "\n", + " def outputs(self):\n", + " return {\n", + " 'fields': {\n", + " '_type': 'map',\n", + " '_value': {\n", + " '_type': 'array',\n", + " '_shape': self.config['n_bins'],\n", + " '_data': 'positive_float'\n", + " },\n", + " }\n", + " }\n", + "\n", + " def update(self, state, interval):\n", + " fields = state['fields']\n", + "\n", + " fields_update = {}\n", + " for species, field in fields.items():\n", + " fields_update[species] = self.diffusion_delta(\n", + " field,\n", + " interval,\n", + " diffusion_coeff=self.config['diffusion_coeffs'][species],\n", + " advection_coeff=self.config['advection_coeffs'][species]\n", + " )\n", + "\n", + " return {\n", + " 'fields': fields_update\n", + " }\n", + "\n", + " def diffusion_delta(self, state, interval, diffusion_coeff, advection_coeff):\n", + " t = 0.0\n", + " dt = min(interval, self.diffusion_dt)\n", + " updated_state = state.copy()\n", + "\n", + " while t < interval:\n", + "\n", + " # Diffusion\n", + " laplacian = convolve(\n", + " updated_state,\n", + " LAPLACIAN_2D,\n", + " mode='reflect',\n", + " ) * diffusion_coeff\n", + "\n", + " # Advection\n", + " advective_flux_x = convolve(\n", + " updated_state,\n", + " np.array([[-1, 0, 1]]),\n", + " mode='reflect',\n", + " ) * advection_coeff[0]\n", + " advective_flux_y = convolve(\n", + " updated_state,\n", + " np.array([[-1], [0], [1]]),\n", + " mode='reflect',\n", + " ) * advection_coeff[1]\n", + "\n", + " # Update the current state\n", + " updated_state += (laplacian + advective_flux_x + advective_flux_y) * dt\n", + "\n", + " # # Ensure non-negativity\n", + " # current_states[species] = np.maximum(updated_state, 0)\n", + "\n", + " # Update time\n", + " t += dt\n", + "\n", + " return updated_state - state\n", + "\n", + "core.register_process('DiffusionAdvection', DiffusionAdvection)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "dbc094e9-29c5-4d32-a3cc-60c15be6f3f5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[{'fields': {'glucose': array([[ 6.3778075 , 19.22653031, 18.34401593, 13.04759822],\n", + " [10.70063161, 1.34591456, 6.24732449, 8.15221775],\n", + " [15.57146219, 15.31785191, 7.82161606, 9.84856477],\n", + " [13.48377254, 16.31984105, 19.90598232, 10.41022059]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[1.22492592e-03, 6.32134456e-02, 8.07464051e-02, 2.18643878e-02],\n", + " [9.20626967e-02, 6.95026218e-05, 1.68679860e-02, 8.04637811e-02],\n", + " [5.71227249e-02, 3.67712875e-02, 6.85828083e-02, 1.84582320e-02],\n", + " [8.11143656e-02, 6.03052318e-02, 8.00668469e-02, 9.89941840e-02]])}, 'time': 0.0}, {'fields': {'glucose': array([[ 7.91099702, 16.42347263, 16.69270908, 13.03018209],\n", + " [10.10414476, 5.32156803, 7.43431668, 8.64163127],\n", + " [14.79321719, 13.72409232, 9.48771404, 9.69451891],\n", + " [13.9305705 , 16.12325668, 17.63446039, 11.17450021]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.01499548, 0.0539746 , 0.06817446, 0.03211996],\n", + " [0.07313834, 0.01842942, 0.03059766, 0.06502197],\n", + " [0.05982446, 0.04092131, 0.05912082, 0.03501529],\n", + " [0.0768812 , 0.06182664, 0.07803044, 0.08985677]])}, 'time': 1.0}, {'fields': {'glucose': array([[ 8.88250739, 14.68883607, 15.40050922, 12.9156302 ],\n", + " [10.01878253, 7.63189584, 8.4914099 , 9.09241534],\n", + " [14.13395173, 13.00326241, 10.38607144, 9.80297837],\n", + " [14.1850187 , 15.73394296, 16.15443844, 11.59970126]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.02383926, 0.04884306, 0.06026169, 0.03816278],\n", + " [0.0621857 , 0.02947781, 0.0381447 , 0.05693893],\n", + " [0.06038576, 0.04454673, 0.05530037, 0.04443401],\n", + " [0.07376569, 0.06270954, 0.07535618, 0.08357661]])}, 'time': 2.0}, {'fields': {'glucose': array([[ 9.52353716, 13.58898269, 14.42021479, 12.7536738 ],\n", + " [10.15129236, 9.02446067, 9.32938312, 9.50793614],\n", + " [13.63494591, 12.67972186, 10.9047692 , 10.0183668 ],\n", + " [14.28932825, 15.30787258, 15.15299432, 11.83387216]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.02968054, 0.04608875, 0.05523553, 0.04176338],\n", + " [0.05588051, 0.03623581, 0.04242723, 0.05285241],\n", + " [0.06003233, 0.04750067, 0.05409858, 0.04986906],\n", + " [0.0713422 , 0.06314009, 0.07276781, 0.07901391]])}, 'time': 3.0}, {'fields': {'glucose': array([[ 9.96476277, 12.87798395, 13.68747009, 12.57797178],\n", + " [10.36239773, 9.89472631, 9.96061424, 9.88105796],\n", + " [13.27826088, 12.53477254, 11.22705095, 10.26604967],\n", + " [14.28850769, 14.90627406, 14.45314213, 11.96030906]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.0336664 , 0.04470941, 0.05203662, 0.043944 ],\n", + " [0.05229687, 0.04046768, 0.04496786, 0.05092062],\n", + " [0.05935924, 0.04979924, 0.05403216, 0.05304451],\n", + " [0.06937532, 0.06325873, 0.07050836, 0.07554179]])}, 'time': 4.0}, {'fields': {'glucose': array([[10.28172785, 12.41194967, 13.14338435, 12.40857953],\n", + " [10.58785311, 10.45786217, 10.42543865, 10.20694295],\n", + " [13.03105568, 12.46847644, 11.44150121, 10.5106188 ],\n", + " [14.21976218, 14.54916954, 13.95052667, 12.02650301]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.03648696, 0.0441248 , 0.05001641, 0.04529864],\n", + " [0.05031372, 0.04320128, 0.04656477, 0.05013391],\n", + " [0.05863781, 0.05152941, 0.05439108, 0.05491384],\n", + " [0.0677308 , 0.0631663 , 0.06861617, 0.07280292]])}, 'time': 5.0}, {'fields': {'glucose': array([[10.51907603, 12.10411416, 12.7404631 , 12.25593999],\n", + " [10.79982929, 10.83448471, 10.76513213, 10.48518271],\n", + " [12.86205722, 12.43561799, 11.59245833, 10.73610307],\n", + " [14.11067167, 14.2394434 , 13.58110706, 12.05967095]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.03856191, 0.04399849, 0.04876863, 0.04617397],\n", + " [0.04927475, 0.04503581, 0.04763857, 0.04993995],\n", + " [0.05797842, 0.052798 , 0.0548499 , 0.05601205],\n", + " [0.06632822, 0.06293382, 0.06705248, 0.07058386]])}, 'time': 6.0}, {'fields': {'glucose': array([[10.70376468, 11.90065818, 12.44244505, 12.12435717],\n", + " [10.98795633, 11.09429338, 11.01375248, 10.71876916],\n", + " [12.74638559, 12.41607494, 11.70320766, 10.93632915],\n", + " [13.98041623, 13.9734732 , 13.30411946, 12.07534915]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.04014958, 0.04413473, 0.0480334 , 0.04677266],\n", + " [0.04879322, 0.04632166, 0.04841246, 0.05003843],\n", + " [0.0574151 , 0.05370681, 0.05527121, 0.05664465],\n", + " [0.0651161 , 0.06261103, 0.0657578 , 0.06874997]])}, 'time': 7.0}, {'fields': {'glucose': array([[10.85242367, 11.76732391, 12.22233319, 12.01451846],\n", + " [11.15000747, 11.27878495, 11.19707384, 10.91258499],\n", + " [12.66587602, 12.40114555, 11.78674724, 11.11008001],\n", + " [13.84172161, 13.74568581, 13.09276736, 12.08227773]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.04141106, 0.04441906, 0.04764126, 0.04721304],\n", + " [0.04863966, 0.04726504, 0.04900614, 0.05026807],\n", + " [0.05694828, 0.05434274, 0.05560703, 0.0569897 ],\n", + " [0.06405899, 0.06223282, 0.06467462, 0.06721129]])}, 'time': 8.0}, {'fields': {'glucose': array([[10.97553809, 11.68179112, 12.06023242, 11.92516335],\n", + " [11.28733743, 11.41337804, 11.33380562, 11.07220892],\n", + " [12.60793625, 12.38726462, 11.85085481, 11.25858713],\n", + " [13.70267295, 13.55040462, 12.9289401 , 12.08523633]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.04244828, 0.04478404, 0.04747983, 0.04756377],\n", + " [0.04867703, 0.04798847, 0.04948485, 0.05054411],\n", + " [0.05656569, 0.05477555, 0.05584977, 0.0571535 ],\n", + " [0.06313081, 0.06182364, 0.06375495, 0.06590451]])}, 'time': 9.0}, {'fields': {'glucose': array([[11.07987203, 11.62921223, 11.9415101 , 11.8541192 ],\n", + " [11.40267456, 11.5140617 , 11.43725166, 11.20315459],\n", + " [12.56415326, 12.37313277, 11.90052251, 11.38419853],\n", + " [13.56815585, 13.38251566, 12.80010375, 12.0867134 ]]), 'acetate': array([[0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.],\n", + " [0., 0., 0., 0.]]), 'biomass': array([[0.04332671, 0.04518964, 0.04747347, 0.04786426],\n", + " [0.04882299, 0.04856568, 0.0498851 , 0.05082378],\n", + " [0.05625195, 0.05505925, 0.05600839, 0.05720113],\n", + " [0.06231129, 0.06140061, 0.0629614 , 0.06478314]])}, 'time': 10.0}]\n" + ] + } + ], + "source": [ + " n_bins = (4, 4)\n", + "\n", + "initial_glucose = np.random.uniform(low=0, high=20, size=n_bins)\n", + "initial_acetate = np.random.uniform(low=0, high=0, size=n_bins)\n", + "initial_biomass = np.random.uniform(low=0, high=0.1, size=n_bins)\n", + "\n", + "composite_state = {\n", + " 'fields': {\n", + " 'glucose': initial_glucose,\n", + " 'acetate': initial_acetate,\n", + " 'biomass': initial_biomass,\n", + " },\n", + " 'diffusion': {\n", + " '_type': 'process',\n", + " 'address': 'local:DiffusionAdvection',\n", + " 'config': {\n", + " 'n_bins': n_bins,\n", + " 'bounds': (10, 10),\n", + " 'default_diffusion_rate': 1e-1,\n", + " 'default_diffusion_dt': 1e-1,\n", + " 'diffusion_coeffs': {\n", + " 'glucose': 1e-1,\n", + " 'acetate': 1e-1,\n", + " 'biomass': 1e-1,\n", + " },\n", + " 'advection_coeffs': {\n", + " 'glucose': (0, 0),\n", + " 'acetate': (0, 0),\n", + " 'biomass': (0, 0),\n", + " },\n", + " },\n", + " 'inputs': {\n", + " 'fields': ['fields']\n", + " },\n", + " 'outputs': {\n", + " 'fields': ['fields']\n", + " }\n", + " },\n", + " 'emitter': {\n", + " '_type': 'step',\n", + " 'address': 'local:ram-emitter',\n", + " 'config': {\n", + " 'emit': {\n", + " 'fields': 'map',\n", + " 'time': 'float',\n", + " }\n", + " },\n", + " 'inputs': {\n", + " 'fields': ['fields'],\n", + " 'time': ['global_time'],\n", + " }\n", + " }\n", + "}\n", + "\n", + "sim = Composite({'state': composite_state}, core=core)\n", + "# sim.add_emitter()\n", + "\n", + "sim.update({}, 10.0)\n", + "\n", + "data = sim.gather_results()[('emitter',)]\n", + "\n", + "print(data)" + ] + }, + { + "cell_type": "markdown", + "id": "654b6495-4d6e-4a54-a3da-097dcef50903", + "metadata": {}, + "source": [ + "## COMETS" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "e84f5056-e953-4038-bdf7-a973eae4ff6a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{('emitter',): [{'fields': {'glucose': array([[ 3.82126173, 3.12636203, 8.22889632, 17.56733378, 9.73343781,\n", + " 0.31601036, 8.1821953 , 3.08994108, 8.06914903, 14.99527261],\n", + " [10.07156141, 3.52828765, 1.31190908, 4.24779386, 18.99041128,\n", + " 2.46544413, 14.21736908, 18.56246038, 12.40297421, 2.21408072],\n", + " [18.94420483, 13.70246869, 4.57396732, 10.8122537 , 7.38989862,\n", + " 16.78092721, 4.98489295, 2.59636159, 19.55761987, 0.90474753],\n", + " [11.92760396, 18.17486444, 10.97201684, 2.11927962, 9.38597731,\n", + " 6.02713358, 1.53960068, 13.74875238, 5.21003044, 9.44833266],\n", + " [ 9.32633965, 9.76796857, 16.73425389, 19.5525409 , 5.45817916,\n", + " 9.99496607, 5.82465315, 14.28741657, 14.42171748, 10.16918618],\n", + " [ 9.10862658, 6.84781818, 11.62278588, 11.4607051 , 3.95802964,\n", + " 4.72677715, 10.51982268, 2.64383585, 11.64272948, 12.69519414],\n", + " [ 5.69885288, 4.48548957, 6.36648647, 0.20539891, 13.15649957,\n", + " 1.44902334, 12.6504334 , 15.15818063, 12.13369899, 0.07686751],\n", + " [ 7.01522932, 19.29669429, 0.76477955, 10.75726936, 7.46574612,\n", + " 8.55671029, 3.59279893, 9.65385724, 15.3714715 , 5.46855368],\n", + " [18.04089068, 17.62155866, 16.31874208, 6.9022857 , 3.07346873,\n", + " 4.25060792, 17.52441299, 2.62862301, 16.8026227 , 3.21312078],\n", + " [ 3.07183598, 4.42490798, 9.05821636, 17.91323437, 17.87274517,\n", + " 5.111423 , 0.29492852, 9.89584752, 13.66735216, 5.6826724 ]]), 'acetate': array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n", + " [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]), 'biomass': array([[0.08604086, 0.03302994, 0.06807024, 0.02809788, 0.03389805,\n", + " 0.00923769, 0.00387872, 0.01822238, 0.00526079, 0.01046659],\n", + " [0.00499364, 0.08351803, 0.06797482, 0.01127102, 0.09864247,\n", + " 0.03226925, 0.06828779, 0.01183665, 0.01748456, 0.07014272],\n", + " [0.00811581, 0.07239723, 0.03976824, 0.08165344, 0.06025926,\n", + " 0.04980458, 0.05151466, 0.02476535, 0.03394666, 0.02144946],\n", + " [0.07002669, 0.02121687, 0.01639185, 0.01690746, 0.09933419,\n", + " 0.05369704, 0.0630521 , 0.08130519, 0.07991097, 0.04929892],\n", + " [0.01008635, 0.00442297, 0.04971321, 0.0338883 , 0.02937761,\n", + " 0.06892877, 0.06698683, 0.0230541 , 0.02004484, 0.08789833],\n", + " [0.08523132, 0.03232749, 0.09910479, 0.01961684, 0.00139808,\n", + " 0.09434443, 0.07528768, 0.06671021, 0.00926822, 0.01007608],\n", + " [0.04812355, 0.08222086, 0.00042157, 0.06016274, 0.0385797 ,\n", + " 0.06955171, 0.0639717 , 0.0221655 , 0.03210612, 0.08435087],\n", + " [0.02210327, 0.08541766, 0.03999851, 0.0276389 , 0.09508208,\n", + " 0.07644128, 0.02193961, 0.05804431, 0.03867814, 0.08293876],\n", + " [0.00557096, 0.02256939, 0.00293057, 0.07195997, 0.02510287,\n", + " 0.04244563, 0.06480956, 0.00126045, 0.01197891, 0.06278026],\n", + " [0.05300538, 0.01336124, 0.0616027 , 0.08464584, 0.07881536,\n", + " 0.06058593, 0.03211505, 0.04638376, 0.09872545, 0.09189502]])}, 'time': 0.0}, {'fields': {'glucose': array([[ 4.31163516, 3.76368257, 7.88176905, 14.79010774, 10.16892358,\n", + " 2.32273191, 7.6274915 , 5.31774104, 8.66839193, 13.15507089],\n", + " [ 9.68786348, 4.7730571 , 2.90223274, 6.74027721, 14.59206534,\n", + " 5.68941109, 12.12567673, 14.94154897, 11.99310578, 4.23387897],\n", + " [16.91094428, 12.69794049, 6.14107213, 8.95384519, 9.16833498,\n", + " 12.92706052, 6.32028145, 6.30970993, 14.79584837, 3.4091276 ],\n", + " [12.67365613, 15.81143858, 10.81710216, 5.58705546, 8.20073991,\n", + " 6.9955049 , 3.74716603, 11.18264674, 7.95078568, 8.55131687],\n", + " [ 9.65440036, 10.71764668, 15.16337871, 15.82381218, 7.10612713,\n", + " 8.52830637, 6.82584039, 12.43822527, 12.97727851, 10.47259968],\n", + " [ 8.58290636, 7.5875987 , 10.96634819, 10.53376897, 5.58620187,\n", + " 5.3550018 , 9.1518531 , 6.02543584, 11.21379652, 11.285272 ],\n", + " [ 6.14200435, 6.08193604, 6.03278216, 3.55688088, 9.94195783,\n", + " 4.13492919, 10.89619157, 13.0601376 , 11.46538378, 2.83304856],\n", + " [ 8.78308004, 15.24372075, 4.78423402, 8.69381881, 7.66777035,\n", + " 7.26236911, 6.25744152, 9.55921303, 13.60299058, 5.74064977],\n", + " [15.63012577, 16.11764986, 13.78399649, 8.47185674, 5.28809194,\n", + " 5.60879539, 12.60758344, 6.11833374, 13.99659019, 4.79861324],\n", + " [ 4.61060226, 6.03435465, 9.94645575, 15.94976165, 15.2380789 ,\n", + " 5.81242623, 3.02117206, 8.88115552, 12.58961299, 6.18524962]]), 'acetate': array([[0.00000000e+00, 0.00000000e+00, 6.92884034e-03, 4.52100721e-03,\n", + " 4.02044350e-03, 0.00000000e+00, 3.92426855e-04, 0.00000000e+00,\n", + " 5.24276878e-04, 1.58810027e-03],\n", + " [6.07846683e-04, 0.00000000e+00, 0.00000000e+00, 6.64013677e-05,\n", + " 1.62697325e-02, 0.00000000e+00, 1.01287950e-02, 1.93868421e-03,\n", + " 2.42662721e-03, 0.00000000e+00],\n", + " [1.33760496e-03, 1.05602918e-02, 7.71819562e-04, 1.04440664e-02,\n", + " 5.40091879e-03, 7.88842741e-03, 1.75913410e-03, 0.00000000e+00,\n", + " 5.64820845e-03, 0.00000000e+00],\n", + " [9.51154154e-03, 3.45197612e-03, 2.11678127e-03, 0.00000000e+00,\n", + " 1.14408477e-02, 3.39423894e-03, 0.00000000e+00, 1.18782229e-02,\n", + " 3.30228134e-03, 5.70922301e-03],\n", + " [1.15551731e-03, 5.26032725e-04, 7.86617776e-03, 5.63807234e-03,\n", + " 1.42792697e-03, 8.34278750e-03, 3.90629990e-03, 3.42691056e-03,\n", + " 2.99177353e-03, 1.07752964e-02],\n", + " [9.56811473e-03, 2.59568769e-03, 1.32609715e-02, 2.60299132e-03,\n", + " 0.00000000e+00, 2.37371152e-03, 9.45352689e-03, 0.00000000e+00,\n", + " 1.24141132e-03, 1.41569234e-03],\n", + " [2.65214607e-03, 1.30864659e-03, 2.98343130e-05, 0.00000000e+00,\n", + " 5.51905137e-03, 0.00000000e+00, 8.97156659e-03, 3.37803750e-03,\n", + " 4.40296222e-03, 0.00000000e+00],\n", + " [1.84164430e-03, 1.41561690e-02, 0.00000000e+00, 3.52330151e-03,\n", + " 8.63657125e-03, 8.09735947e-03, 0.00000000e+00, 6.83990725e-03,\n", + " 5.92771479e-03, 4.05547303e-03],\n", + " [9.04240383e-04, 3.63519206e-03, 4.59514091e-04, 5.84985660e-03,\n", + " 0.00000000e+00, 2.55348139e-04, 1.04194647e-02, 0.00000000e+00,\n", + " 1.89817804e-03, 0.00000000e+00],\n", + " [0.00000000e+00, 1.79749765e-04, 6.88179745e-03, 1.37075501e-02,\n", + " 1.27539439e-02, 2.31754851e-03, 0.00000000e+00, 5.57198797e-03,\n", + " 1.43834827e-02, 5.02571342e-03]]), 'biomass': array([[0.08057403, 0.04701196, 0.06676388, 0.03387483, 0.03913097,\n", + " 0.0144205 , 0.01151938, 0.01723946, 0.00889548, 0.01615073],\n", + " [0.0201009 , 0.07612373, 0.06613336, 0.03106734, 0.08508503,\n", + " 0.04178906, 0.05910791, 0.01986319, 0.02335611, 0.06060675],\n", + " [0.01983777, 0.06629399, 0.04865253, 0.0724074 , 0.07019419,\n", + " 0.05457981, 0.05512341, 0.03354138, 0.03774312, 0.03054787],\n", + " [0.06085947, 0.02946759, 0.02438046, 0.03136165, 0.08733912,\n", + " 0.06278459, 0.06673004, 0.07599593, 0.07403457, 0.05612464],\n", + " [0.02217408, 0.01462993, 0.04912238, 0.03608968, 0.03905358,\n", + " 0.07134774, 0.06916277, 0.03705505, 0.03215089, 0.07874524],\n", + " [0.07761435, 0.04554835, 0.08232088, 0.03060312, 0.01788119,\n", + " 0.08745378, 0.07880774, 0.06057383, 0.01905003, 0.02429195],\n", + " [0.0550798 , 0.07492648, 0.0231501 , 0.04999575, 0.04741963,\n", + " 0.07251192, 0.06412357, 0.03464356, 0.03754817, 0.07330255],\n", + " [0.03050359, 0.07609367, 0.03980957, 0.04182177, 0.0846782 ,\n", + " 0.07555783, 0.03766505, 0.05136314, 0.04445385, 0.08297112],\n", + " [0.01374176, 0.02669487, 0.01888297, 0.06619059, 0.04244599,\n", + " 0.05055399, 0.05741037, 0.01672299, 0.02706566, 0.06755898],\n", + " [0.04906176, 0.02296113, 0.05951184, 0.08626347, 0.07931574,\n", + " 0.06286657, 0.03940351, 0.049833 , 0.09332323, 0.09616132]])}, 'time': 1.0}, {'fields': {'glucose': array([[ 4.73451365, 4.31985082, 7.61707945, 12.94964984, 10.1216048 ,\n", + " 3.94792143, 7.40437789, 6.65554227, 9.06194312, 11.8989265 ],\n", + " [ 9.3737015 , 5.65011158, 4.24372236, 7.84257288, 12.26670637,\n", + " 7.19740427, 10.8162124 , 12.81596042, 11.3546022 , 5.67337675],\n", + " [15.37270776, 11.93678465, 7.0746198 , 8.3643867 , 9.57829349,\n", + " 10.91425298, 7.16105274, 8.03082641, 12.28641642, 4.96333455],\n", + " [12.89755302, 14.30667671, 10.75041418, 7.34912768, 7.93694404,\n", + " 7.36017572, 5.1999354 , 9.98386051, 9.06772134, 8.27942026],\n", + " [ 9.94750273, 11.1013788 , 13.89185664, 13.5802373 , 7.84452678,\n", + " 7.86738431, 7.31203929, 11.26733319, 12.05259811, 10.43246033],\n", + " [ 8.35332973, 8.12314772, 10.43199054, 9.94773276, 6.49208859,\n", + " 5.87046096, 8.49600637, 7.778592 , 10.89881734, 10.4556254 ],\n", + " [ 6.64906339, 6.93697543, 6.33619528, 5.28228669, 8.39589869,\n", + " 5.48781008, 9.88155451, 11.75756105, 10.9148672 , 4.62390135],\n", + " [ 9.60481243, 13.01284379, 6.77827532, 7.95014123, 7.57211682,\n", + " 6.87122253, 7.42613554, 9.60350178, 12.24563841, 6.12402295],\n", + " [14.00254829, 14.65523066, 12.43416877, 9.19986504, 6.67448943,\n", + " 6.29465931, 10.14786573, 7.74920966, 12.29326806, 5.79306669],\n", + " [ 5.7850367 , 7.22208507, 10.37763455, 14.50025375, 13.42539089,\n", + " 6.39714816, 4.60667953, 8.49056678, 11.59585838, 6.60587695]]), 'acetate': array([[0.00079365, 0.00063565, 0.01192746, 0.00947765, 0.00942783,\n", + " 0.00062893, 0.00220401, 0.00110745, 0.00170609, 0.00366559],\n", + " [0.00305681, 0.00297199, 0.00088045, 0.00495972, 0.02438401,\n", + " 0.00495981, 0.01517374, 0.00532577, 0.00544566, 0.00073139],\n", + " [0.00581644, 0.01678362, 0.00555441, 0.01564483, 0.01494232,\n", + " 0.01405139, 0.00654362, 0.00408087, 0.00999549, 0.00101364],\n", + " [0.01608429, 0.00865739, 0.00574853, 0.00401294, 0.01742337,\n", + " 0.00965285, 0.0018463 , 0.01836883, 0.01151612, 0.01136219],\n", + " [0.00516535, 0.00367071, 0.01432717, 0.0104522 , 0.0063067 ,\n", + " 0.01405117, 0.00986047, 0.00899276, 0.00816554, 0.01857539],\n", + " [0.01584957, 0.00796506, 0.020382 , 0.00711309, 0.00210329,\n", + " 0.00708607, 0.01633369, 0.00537847, 0.00419214, 0.00531083],\n", + " [0.00674526, 0.00735658, 0.00282092, 0.00110087, 0.01015171,\n", + " 0.00210546, 0.01529592, 0.00880261, 0.00880573, 0.00091524],\n", + " [0.00613191, 0.02145854, 0.00264695, 0.00808803, 0.01498621,\n", + " 0.01283013, 0.00525493, 0.01144363, 0.01172984, 0.0081908 ],\n", + " [0.00334625, 0.00781849, 0.00456547, 0.01238384, 0.00422828,\n", + " 0.00459655, 0.01510593, 0.00313645, 0.00702127, 0.00296415],\n", + " [0.00119104, 0.0025634 , 0.01349539, 0.02548505, 0.02282976,\n", + " 0.00660321, 0.00158569, 0.01086409, 0.02459429, 0.01179396]]), 'biomass': array([[0.07828787, 0.05728615, 0.06730756, 0.04033219, 0.04349409,\n", + " 0.02059622, 0.01750581, 0.01812553, 0.01273189, 0.02078817],\n", + " [0.03224072, 0.07278447, 0.06717278, 0.04444826, 0.0784066 ,\n", + " 0.04839362, 0.05465686, 0.02621373, 0.02820923, 0.05524334],\n", + " [0.02939798, 0.06361631, 0.05486396, 0.06943058, 0.0757993 ,\n", + " 0.06026237, 0.05865851, 0.04095297, 0.04195562, 0.03840353],\n", + " [0.05615968, 0.03602776, 0.03239329, 0.04165936, 0.08179929,\n", + " 0.06962602, 0.07101653, 0.07384379, 0.07140837, 0.0612982 ],\n", + " [0.03159802, 0.02438946, 0.04950192, 0.04023096, 0.04712541,\n", + " 0.07433525, 0.07258311, 0.0476838 , 0.04177937, 0.07410668],\n", + " [0.07401344, 0.0539811 , 0.07349332, 0.03848361, 0.03148691,\n", + " 0.08456042, 0.08100537, 0.05958675, 0.02823484, 0.03503521],\n", + " [0.06039637, 0.07211632, 0.03757683, 0.04992837, 0.0541241 ,\n", + " 0.07597169, 0.06669049, 0.04361456, 0.04289043, 0.0717583 ],\n", + " [0.03775617, 0.07017813, 0.04378171, 0.05074528, 0.08009684,\n", + " 0.07626787, 0.04847665, 0.05023119, 0.04996059, 0.083178 ],\n", + " [0.02110775, 0.03158528, 0.03059259, 0.06557963, 0.05487839,\n", + " 0.0575448 , 0.055553 , 0.0286748 , 0.03967752, 0.07316461],\n", + " [0.04733965, 0.03069299, 0.05998583, 0.08735126, 0.0813871 ,\n", + " 0.06610566, 0.04681063, 0.0540446 , 0.09098797, 0.10007066]])}, 'time': 2.0}, {'fields': {'glucose': array([[ 5.09870059, 4.79536488, 7.44357174, 11.66513998, 9.90374229,\n", + " 5.18069452, 7.37519963, 7.46899975, 9.28153863, 11.04065964],\n", + " [ 9.11709354, 6.28117333, 5.28114882, 8.31281756, 10.95261521,\n", + " 7.88959831, 9.97907677, 11.50400584, 10.75654692, 6.66884774],\n", + " [14.17968036, 11.35581898, 7.67721179, 8.25777355, 9.50090063,\n", + " 9.81495417, 7.67733104, 8.782906 , 10.91125328, 5.98956485],\n", + " [12.84072866, 13.3001572 , 10.67217896, 8.2585039 , 7.97129775,\n", + " 7.50907694, 6.15927629, 9.41560137, 9.45362755, 8.25822721],\n", + " [10.16374559, 11.18697652, 12.88930034, 12.16157056, 8.15969543,\n", + " 7.58450961, 7.55919821, 10.51044201, 11.39535461, 10.260533 ],\n", + " [ 8.30708573, 8.48255188, 10.03033454, 9.54187261, 7.00185871,\n", + " 6.27290199, 8.191822 , 8.64979916, 10.63074526, 9.95518916],\n", + " [ 7.11050673, 7.45046465, 6.78339615, 6.23658504, 7.66406746,\n", + " 6.19845134, 9.25776421, 10.91810747, 10.46600159, 5.83027136],\n", + " [ 9.93733374, 11.71575863, 7.79432899, 7.75158489, 7.45869768,\n", + " 6.82077317, 7.91223968, 9.60658616, 11.24237377, 6.50471168],\n", + " [12.85511079, 13.43542002, 11.64380905, 9.51635947, 7.49163992,\n", + " 6.69160366, 8.91701399, 8.47273198, 11.18147744, 6.43939822],\n", + " [ 6.69042175, 8.06310361, 10.56250943, 13.39393439, 12.15952581,\n", + " 6.83758582, 5.58698939, 8.34937465, 10.76832445, 6.92860453]]), 'acetate': array([[0.00306472, 0.00240574, 0.0160008 , 0.01504055, 0.01512404,\n", + " 0.00217912, 0.00467972, 0.00314389, 0.00360355, 0.00606054],\n", + " [0.00693401, 0.00772619, 0.00336847, 0.01170581, 0.02979243,\n", + " 0.01181053, 0.01863367, 0.00936974, 0.00880793, 0.00453851],\n", + " [0.01176542, 0.02164557, 0.01153383, 0.02019676, 0.02426239,\n", + " 0.0202274 , 0.01239253, 0.01009192, 0.0143313 , 0.00405292],\n", + " [0.02151568, 0.01454414, 0.01089444, 0.01045708, 0.02255677,\n", + " 0.01649128, 0.00799233, 0.02332221, 0.01942779, 0.01730589],\n", + " [0.01073636, 0.00887919, 0.01994406, 0.01554396, 0.01237659,\n", + " 0.0192867 , 0.01639851, 0.01570704, 0.014772 , 0.02496166],\n", + " [0.02106779, 0.01458365, 0.0251929 , 0.0122118 , 0.00647165,\n", + " 0.01271082, 0.02233604, 0.0125663 , 0.00891993, 0.0104276 ],\n", + " [0.01220373, 0.01405723, 0.00732657, 0.00545094, 0.01418565,\n", + " 0.0089339 , 0.02088678, 0.01504426, 0.01356348, 0.00426038],\n", + " [0.01160853, 0.02604971, 0.00839208, 0.01302971, 0.02014222,\n", + " 0.0170433 , 0.01220594, 0.01604538, 0.01750037, 0.01290342],\n", + " [0.00701387, 0.01253365, 0.01050113, 0.01926666, 0.01168993,\n", + " 0.0103435 , 0.01822685, 0.00854705, 0.0137655 , 0.00893235],\n", + " [0.0043521 , 0.00661982, 0.02022534, 0.03571037, 0.03160798,\n", + " 0.01226311, 0.00503412, 0.01629229, 0.03263213, 0.01964191]]), 'biomass': array([[0.07823671, 0.06532927, 0.06930746, 0.04700655, 0.04774012,\n", + " 0.02698779, 0.02272274, 0.02023514, 0.01673251, 0.02486293],\n", + " [0.04242112, 0.07220623, 0.06958157, 0.05432052, 0.0758259 ,\n", + " 0.05359934, 0.05324825, 0.03166147, 0.03257718, 0.05252567],\n", + " [0.03761055, 0.06330078, 0.05996397, 0.06991488, 0.07959206,\n", + " 0.06606576, 0.06244224, 0.04741829, 0.04646579, 0.04517719],\n", + " [0.05456271, 0.04185458, 0.04002546, 0.04979219, 0.08018657,\n", + " 0.07541031, 0.07531718, 0.07394782, 0.07102188, 0.06566458],\n", + " [0.03947415, 0.03336537, 0.05114602, 0.04535272, 0.05441355,\n", + " 0.07787297, 0.07670644, 0.0563773 , 0.04991715, 0.07254037],\n", + " [0.07300914, 0.06002127, 0.06951169, 0.04524124, 0.04295746,\n", + " 0.08435025, 0.08311877, 0.06139881, 0.03697098, 0.04406479],\n", + " [0.06492717, 0.07182867, 0.04781958, 0.05287569, 0.06020426,\n", + " 0.07936831, 0.07048902, 0.05093653, 0.04862026, 0.07231265],\n", + " [0.04422066, 0.06723132, 0.04891059, 0.05754926, 0.07907989,\n", + " 0.0782164 , 0.05673306, 0.05233794, 0.05552625, 0.08433791],\n", + " [0.02797106, 0.0368576 , 0.04005501, 0.06775643, 0.06449393,\n", + " 0.06396315, 0.05712321, 0.03874127, 0.05055987, 0.07913669],\n", + " [0.04722979, 0.03735543, 0.06207212, 0.08865991, 0.0844462 ,\n", + " 0.07017507, 0.05358269, 0.05891047, 0.09095112, 0.10397621]])}, 'time': 3.0}, {'fields': {'glucose': array([[ 5.4113536 , 5.19832837, 7.34144348, 10.73407304, 9.64238776,\n", + " 6.08160177, 7.44735273, 7.96522752, 9.37642564, 10.44845156],\n", + " [ 8.90668073, 6.73864904, 6.05008441, 8.49121894, 10.15185781,\n", + " 8.19106658, 9.43305992, 10.65378888, 10.26841865, 7.34491445],\n", + " [13.23497143, 10.90712921, 8.08276578, 8.3092214 , 9.28379024,\n", + " 9.18349463, 7.98147807, 9.0649851 , 10.12163377, 6.69803725],\n", + " [12.63725447, 12.58577294, 10.5638506 , 8.72350755, 8.0696437 ,\n", + " 7.58424998, 6.79310873, 9.13195167, 9.5188979 , 8.3220991 ],\n", + " [10.29921559, 11.11883017, 12.10371221, 11.21911364, 8.27489405,\n", + " 7.47828065, 7.69279264, 10.00268865, 10.89005865, 10.04990545],\n", + " [ 8.3609003 , 8.71356295, 9.73305982, 9.24267405, 7.28989704,\n", + " 6.57837685, 8.05436211, 9.04324909, 10.38280658, 9.64165353],\n", + " [ 7.49567723, 7.79070299, 7.20029595, 6.79868029, 7.33473762,\n", + " 6.59013519, 8.85189988, 10.34586236, 10.10148973, 6.64961863],\n", + " [10.01813145, 10.91639113, 8.32068331, 7.76337513, 7.3932576 ,\n", + " 6.88515081, 8.08697612, 9.53833873, 10.50652243, 6.840072 ],\n", + " [12.01941986, 12.47681581, 11.12812852, 9.62032206, 7.94581874,\n", + " 6.95090258, 8.30437382, 8.74973942, 10.40830875, 6.86843396],\n", + " [ 7.38783855, 8.64140417, 10.60642682, 12.52910571, 11.25425282,\n", + " 7.15336863, 6.22371736, 8.29543839, 10.10679742, 7.16220683]]), 'acetate': array([[0.00644695, 0.00598617, 0.01991831, 0.02110177, 0.02088051,\n", + " 0.0057932 , 0.00765613, 0.00585466, 0.00620474, 0.00894945],\n", + " [0.01196133, 0.01308392, 0.00945355, 0.01904948, 0.03463271,\n", + " 0.01881238, 0.02197009, 0.01382004, 0.01266387, 0.00915809],\n", + " [0.0184527 , 0.02642125, 0.01801523, 0.02548297, 0.03262799,\n", + " 0.02677606, 0.01894841, 0.01678185, 0.01908574, 0.0090935 ],\n", + " [0.02677805, 0.0208681 , 0.01722219, 0.01784728, 0.02818344,\n", + " 0.02366162, 0.01617313, 0.02844449, 0.02672935, 0.02360492],\n", + " [0.01727676, 0.01549312, 0.02538149, 0.02122431, 0.01905734,\n", + " 0.02486915, 0.02342694, 0.02308576, 0.0221735 , 0.03089469],\n", + " [0.02630876, 0.02168257, 0.02948034, 0.01783232, 0.01239764,\n", + " 0.01910507, 0.02830503, 0.02017903, 0.01509969, 0.01643105],\n", + " [0.01862791, 0.02086422, 0.01328475, 0.01136725, 0.01864908,\n", + " 0.01668798, 0.02674987, 0.02173195, 0.01899969, 0.01074133],\n", + " [0.01775758, 0.03003256, 0.01513553, 0.01868815, 0.02511341,\n", + " 0.02196804, 0.01949168, 0.02136788, 0.02348654, 0.01849035],\n", + " [0.01174451, 0.01781292, 0.01757 , 0.026669 , 0.02049369,\n", + " 0.01688343, 0.02162295, 0.01519113, 0.02144779, 0.01653385],\n", + " [0.00861375, 0.01196579, 0.02728667, 0.04486294, 0.03989002,\n", + " 0.01891214, 0.01072236, 0.02217961, 0.03971072, 0.02823807]]), 'biomass': array([[0.07982373, 0.07208608, 0.07242715, 0.05373909, 0.0522047 ,\n", + " 0.03338042, 0.02765878, 0.0232213 , 0.02089314, 0.02867459],\n", + " [0.05133431, 0.07357335, 0.0728173 , 0.06228386, 0.07581297,\n", + " 0.05828211, 0.05388115, 0.03667442, 0.03677213, 0.05172213],\n", + " [0.0450254 , 0.06469907, 0.06472191, 0.07238994, 0.08284261,\n", + " 0.0717578 , 0.0665542 , 0.05334903, 0.05119368, 0.05122563],\n", + " [0.05518944, 0.04744934, 0.04726824, 0.05688211, 0.08107152,\n", + " 0.08075311, 0.07972835, 0.07566716, 0.07226762, 0.06972364],\n", + " [0.0464809 , 0.04160665, 0.05399235, 0.05105343, 0.06135912,\n", + " 0.08194542, 0.08127908, 0.06398566, 0.05721307, 0.07314328],\n", + " [0.07376841, 0.06496389, 0.06865467, 0.05162919, 0.0529567 ,\n", + " 0.08597836, 0.08568503, 0.06495904, 0.04539482, 0.05210087],\n", + " [0.06915099, 0.07311149, 0.05583566, 0.05742189, 0.06613965,\n", + " 0.08300268, 0.07496088, 0.05758862, 0.0546785 , 0.07427525],\n", + " [0.05021423, 0.06663342, 0.05454307, 0.06352656, 0.08038325,\n", + " 0.08113712, 0.06376687, 0.05641904, 0.0613419 , 0.086465 ],\n", + " [0.0345359 , 0.04238628, 0.04828974, 0.07152091, 0.07254616,\n", + " 0.07017194, 0.06082774, 0.04783023, 0.06029436, 0.0853503 ],\n", + " [0.04840328, 0.04344639, 0.06525209, 0.09053041, 0.08820654,\n", + " 0.07490731, 0.06011505, 0.06432512, 0.09267796, 0.10809486]])}, 'time': 4.0}, {'fields': {'glucose': array([[ 5.678529 , 5.53774769, 7.28756421, 10.04022783, 9.38590365,\n", + " 6.72370755, 7.56236464, 8.26494947, 9.38940307, 10.03227003],\n", + " [ 8.73224973, 7.06965452, 6.60615789, 8.53214425, 9.62472721,\n", + " 8.30421173, 9.06878777, 10.0768413 , 9.88887444, 7.79795048],\n", + " [12.47332125, 10.5532126 , 8.35660204, 8.38998604, 9.05356798,\n", + " 8.79955653, 8.14793145, 9.12164537, 9.64243635, 7.20032026],\n", + " [12.3616051 , 12.04613085, 10.42992665, 8.94663597, 8.15310028,\n", + " 7.63281345, 7.20994085, 8.97180527, 9.45015214, 8.40032288],\n", + " [10.36385862, 10.97458741, 11.4846727 , 10.56205944, 8.29403464,\n", + " 7.45182545, 7.76854403, 9.64383246, 10.48059068, 9.83891434],\n", + " [ 8.45949843, 8.85634488, 9.50912062, 9.01200451, 7.45108292,\n", + " 6.80542259, 7.99042794, 9.17841056, 10.14619858, 9.43210046],\n", + " [ 7.80335631, 8.03070128, 7.5372307 , 7.14932987, 7.20395214,\n", + " 6.81793613, 8.57276385, 9.92865073, 9.80216239, 7.20713749],\n", + " [ 9.9725838 , 10.39333916, 8.59254964, 7.84148683, 7.37384388,\n", + " 6.9762511 , 8.1202962 , 9.41313362, 9.96133102, 7.11647561],\n", + " [11.3950835 , 11.73983511, 10.75422845, 9.60947773, 8.17771419,\n", + " 7.13302158, 8.00147534, 8.80620009, 9.84181072, 7.15458939],\n", + " [ 7.92087792, 9.02747656, 10.56572841, 11.83914623, 10.58774202,\n", + " 7.37206382, 6.65241783, 8.26149148, 9.58468337, 7.3219887 ]]), 'acetate': array([[0.01083633, 0.01091549, 0.02437343, 0.02756692, 0.02683491,\n", + " 0.01088712, 0.0112377 , 0.00919595, 0.00947841, 0.01234121],\n", + " [0.01788308, 0.01906987, 0.01701093, 0.02676646, 0.03967462,\n", + " 0.02573254, 0.0257467 , 0.01861606, 0.01700735, 0.01415406],\n", + " [0.02559473, 0.03163592, 0.02505549, 0.03171932, 0.04028468,\n", + " 0.03371204, 0.0260375 , 0.02379445, 0.02442543, 0.0153426 ],\n", + " [0.03238072, 0.02763305, 0.02441324, 0.02575828, 0.03455119,\n", + " 0.03119483, 0.02508015, 0.03427385, 0.03374959, 0.03030425],\n", + " [0.02452166, 0.02303225, 0.03110908, 0.02754372, 0.02623346,\n", + " 0.03110902, 0.03094481, 0.03092726, 0.03005424, 0.03693389],\n", + " [0.03205111, 0.02901506, 0.0340852 , 0.02400943, 0.01937483,\n", + " 0.02611969, 0.03464074, 0.02808204, 0.02239584, 0.02331141],\n", + " [0.02573423, 0.0278329 , 0.02027286, 0.01810585, 0.02390717,\n", + " 0.02459194, 0.03309959, 0.02881669, 0.02533635, 0.01848332],\n", + " [0.02439207, 0.03432623, 0.02246011, 0.02513978, 0.03050944,\n", + " 0.02777472, 0.02686259, 0.02754903, 0.02992951, 0.02509753],\n", + " [0.01736823, 0.02370684, 0.02539183, 0.03462706, 0.02980381,\n", + " 0.02407428, 0.02604887, 0.0226255 , 0.02971182, 0.02519748],\n", + " [0.01372494, 0.01830209, 0.03478105, 0.05340787, 0.04807489,\n", + " 0.02639902, 0.01764103, 0.02873133, 0.0465656 , 0.03736255]]), 'biomass': array([[0.08265826, 0.07819132, 0.07642405, 0.06050814, 0.05703383,\n", + " 0.0397604 , 0.03259627, 0.02688129, 0.02523112, 0.03242972],\n", + " [0.059467 , 0.07635136, 0.07671997, 0.0692559 , 0.07751957,\n", + " 0.06289842, 0.05595673, 0.04155091, 0.04099489, 0.05235358],\n", + " [0.05202226, 0.06740534, 0.06952936, 0.07609387, 0.08617908,\n", + " 0.07734598, 0.07101763, 0.05903517, 0.05611667, 0.05684824],\n", + " [0.05746569, 0.05308624, 0.0542536 , 0.0635413 , 0.08363843,\n", + " 0.08600417, 0.08436452, 0.07858863, 0.07475267, 0.07378681],\n", + " [0.05304636, 0.04929764, 0.05788086, 0.05717815, 0.06821643,\n", + " 0.08653688, 0.08621571, 0.07104015, 0.06409704, 0.07533548],\n", + " [0.07579745, 0.06952316, 0.06992922, 0.05801737, 0.06200491,\n", + " 0.08894195, 0.08891878, 0.06969445, 0.05362924, 0.05960925],\n", + " [0.07335209, 0.07548418, 0.06272798, 0.06291083, 0.07217459,\n", + " 0.08705008, 0.07989955, 0.06409376, 0.06105641, 0.07737333],\n", + " [0.05598723, 0.06786129, 0.06045396, 0.06932377, 0.08329146,\n", + " 0.08488 , 0.07032681, 0.06178497, 0.06750504, 0.08952174],\n", + " [0.04095995, 0.048148 , 0.05588189, 0.07626436, 0.07979021,\n", + " 0.07640705, 0.06593075, 0.05646652, 0.06932618, 0.09177819],\n", + " [0.05063884, 0.04929485, 0.06924188, 0.09310248, 0.09253678,\n", + " 0.08020601, 0.06670399, 0.07025137, 0.0957997 , 0.1125684 ]])}, 'time': 5.0}, {'fields': {'glucose': array([[ 5.90534991, 5.82168068, 7.26286613, 9.51168149, 9.14998427,\n", + " 7.17153684, 7.68544646, 8.44021587, 9.35172256, 9.73180529],\n", + " [ 8.58505149, 7.30654151, 7.00058838, 8.50660978, 9.25160981,\n", + " 8.32584529, 8.81855911, 9.66792331, 9.59651702, 8.09694524],\n", + " [11.84899281, 10.26542626, 8.5350841 , 8.45334304, 8.84850945,\n", + " 8.55052864, 8.22560566, 9.07280899, 9.33218131, 7.55997701],\n", + " [12.05496091, 11.61401248, 10.2787126 , 9.03232629, 8.20166388,\n", + " 7.66750909, 7.47994256, 8.86126179, 9.33037978, 8.46483541],\n", + " [10.37103834, 10.79552067, 10.99025414, 10.08204668, 8.26605673,\n", + " 7.45752592, 7.81057507, 9.37376875, 10.13701661, 9.64100346],\n", + " [ 8.56873487, 8.93904095, 9.33392364, 8.82760164, 7.5376726 ,\n", + " 6.97047736, 7.95402701, 9.17442432, 9.91889185, 9.27832047],\n", + " [ 8.04191621, 8.20411448, 7.79052882, 7.37749322, 7.16851354,\n", + " 6.95722701, 8.36936944, 9.60306594, 9.55068316, 7.58372492],\n", + " [ 9.867205 , 10.02991271, 8.72601548, 7.92581074, 7.38292298,\n", + " 7.0614329 , 8.0897827 , 9.25247952, 9.54817956, 7.33299624],\n", + " [10.91821523, 11.17420196, 10.45812011, 9.53477453, 8.27640338,\n", + " 7.26341012, 7.85060354, 8.7541186 , 9.40852967, 7.34238112],\n", + " [ 8.3226842 , 9.27468402, 10.47257975, 11.27773825, 10.08105163,\n", + " 7.51757748, 6.94630253, 8.22195051, 9.17108785, 7.42293297]]), 'acetate': array([[0.0161695 , 0.01690231, 0.02961903, 0.03441539, 0.0331246 ,\n", + " 0.01701499, 0.01550788, 0.01317153, 0.01339365, 0.0162354 ],\n", + " [0.02454517, 0.02570753, 0.02526867, 0.03477336, 0.04519898,\n", + " 0.03266708, 0.03017779, 0.02378501, 0.02183912, 0.01947902],\n", + " [0.03311711, 0.03752458, 0.03266602, 0.03882378, 0.04764009,\n", + " 0.04101612, 0.03355247, 0.03105994, 0.03038026, 0.02238442],\n", + " [0.03858251, 0.03489834, 0.03228059, 0.03409035, 0.04163886,\n", + " 0.03913406, 0.03429798, 0.04089687, 0.04082212, 0.03741811],\n", + " [0.03236097, 0.03121678, 0.03740007, 0.03451011, 0.03390916,\n", + " 0.03809371, 0.03894695, 0.03918082, 0.03830361, 0.04339453],\n", + " [0.0384798 , 0.03657794, 0.03937889, 0.03078464, 0.02711455,\n", + " 0.03368588, 0.04152446, 0.03633682, 0.03057817, 0.0309922 ],\n", + " [0.03337381, 0.03509298, 0.02798906, 0.02550897, 0.03006162,\n", + " 0.03258644, 0.03997844, 0.03635829, 0.03256153, 0.02695038],\n", + " [0.03146642, 0.0393322 , 0.0302854 , 0.03236746, 0.03662908,\n", + " 0.03440431, 0.03440531, 0.03456365, 0.0369977 , 0.03266244],\n", + " [0.02376912, 0.03025562, 0.0337947 , 0.04311146, 0.03932424,\n", + " 0.03189305, 0.03168823, 0.03069291, 0.0384187 , 0.03463936],\n", + " [0.01961678, 0.02544544, 0.0427541 , 0.06172554, 0.05638264,\n", + " 0.03460142, 0.02543552, 0.0359962 , 0.0536325 , 0.04690408]]), 'biomass': array([[0.08648828, 0.08406252, 0.08114292, 0.06735217, 0.0622897 ,\n", + " 0.04618025, 0.03770504, 0.03109942, 0.02977664, 0.03627473],\n", + " [0.06716742, 0.08020444, 0.08122021, 0.07578609, 0.08046976,\n", + " 0.06769217, 0.05911351, 0.04648703, 0.04537856, 0.05410233],\n", + " [0.05886915, 0.07116079, 0.07459743, 0.08064025, 0.0899053 ,\n", + " 0.08292576, 0.07584538, 0.06468081, 0.06124796, 0.06227267],\n", + " [0.06101448, 0.05892554, 0.06114383, 0.07011687, 0.08741786,\n", + " 0.09137468, 0.08930992, 0.08245139, 0.07822186, 0.07805242],\n", + " [0.05945234, 0.05665024, 0.06265443, 0.0636808 , 0.07514631,\n", + " 0.09163776, 0.09151124, 0.07788431, 0.07085729, 0.07874596],\n", + " [0.07880347, 0.07410157, 0.07274909, 0.06459765, 0.07049697,\n", + " 0.09294317, 0.09288899, 0.07529042, 0.06179003, 0.06690847],\n", + " [0.07771015, 0.07870372, 0.06913948, 0.06903168, 0.07844637,\n", + " 0.0916085 , 0.08525979, 0.07073845, 0.06777825, 0.08144147],\n", + " [0.0617308 , 0.07051667, 0.06659808, 0.07526857, 0.08738862,\n", + " 0.08936367, 0.07684215, 0.068064 , 0.07407289, 0.093465 ],\n", + " [0.04737221, 0.05416142, 0.06318677, 0.08168843, 0.08669527,\n", + " 0.0828274 , 0.07202223, 0.06496834, 0.07799088, 0.09844457],\n", + " [0.053786 , 0.05512666, 0.07388994, 0.09642118, 0.09738754,\n", + " 0.08602656, 0.07353389, 0.07668886, 0.1000673 , 0.11749333]])}, 'time': 6.0}, {'fields': {'glucose': array([[ 6.096105 , 6.05694737, 7.25339189, 9.10096704, 8.93726615,\n", + " 7.47604799, 7.79728971, 8.53484912, 9.28423059, 9.50702355],\n", + " [ 8.45781027, 7.47213177, 7.27415425, 8.44773941, 8.96994765,\n", + " 8.30224475, 8.63962329, 9.36560332, 9.3682788 , 8.28937043],\n", + " [11.32883074, 10.02262188, 8.64129683, 8.4858656 , 8.67388506,\n", + " 8.37664297, 8.24617079, 8.97690557, 9.11593945, 7.81603133],\n", + " [11.73974403, 11.25036734, 10.1169813 , 9.03666201, 8.21555787,\n", + " 7.69000245, 7.64874473, 8.76725981, 9.19494729, 8.50626419],\n", + " [10.33336467, 10.60299583, 10.58776353, 9.71516923, 8.21412494,\n", + " 7.47154499, 7.82911443, 9.15663157, 9.84137332, 9.45871654],\n", + " [ 8.66888285, 8.97983554, 9.1899252 , 8.67497929, 7.57865333,\n", + " 7.08670582, 7.92307126, 9.09592379, 9.70068878, 9.15243361],\n", + " [ 8.22166198, 8.32812427, 7.97102497, 7.52864334, 7.17520917,\n", + " 7.04500906, 8.21169442, 9.33322206, 9.33295858, 7.83240626],\n", + " [ 9.73688728, 9.761989 , 8.77996512, 7.99302914, 7.40387002,\n", + " 7.12976626, 8.03037527, 9.07380033, 9.2249685 , 7.49391533],\n", + " [10.54591947, 10.73505752, 10.20762803, 9.42411306, 8.29588557,\n", + " 7.35411667, 7.77046117, 8.64936155, 9.0646084 , 7.45965361],\n", + " [ 8.6192189 , 9.42158511, 10.34633846, 10.81161626, 9.68276847,\n", + " 7.60795634, 7.14692053, 8.16882395, 8.83852847, 7.47754428]]), 'acetate': array([[0.02239908, 0.02377492, 0.03572337, 0.04166674, 0.03984948,\n", + " 0.02392136, 0.02051304, 0.01779704, 0.01793076, 0.02064406],\n", + " [0.03186844, 0.03300735, 0.0339667 , 0.04306739, 0.05130796,\n", + " 0.03976918, 0.03533646, 0.02938504, 0.02717812, 0.02517796],\n", + " [0.04104033, 0.04418558, 0.04084821, 0.04667481, 0.05503861,\n", + " 0.04869038, 0.04144731, 0.03860449, 0.03694139, 0.03000203],\n", + " [0.04551002, 0.04272509, 0.04073811, 0.04284486, 0.04939096,\n", + " 0.0475143 , 0.04372603, 0.04827171, 0.04818385, 0.04496867],\n", + " [0.04075982, 0.03991723, 0.04439531, 0.04213381, 0.04211305,\n", + " 0.04582322, 0.04743931, 0.04785575, 0.04691813, 0.05044549],\n", + " [0.04565077, 0.04445714, 0.0455101 , 0.03820162, 0.03547754,\n", + " 0.04178681, 0.04903316, 0.04502199, 0.0395011 , 0.03941497],\n", + " [0.04149 , 0.04275643, 0.03628484, 0.03355219, 0.03711535,\n", + " 0.04078699, 0.04740833, 0.04442906, 0.04062603, 0.03600365],\n", + " [0.03899812, 0.04520925, 0.03861865, 0.0403415 , 0.04358919,\n", + " 0.04178844, 0.04227454, 0.04236306, 0.0447852 , 0.04110368],\n", + " [0.03088471, 0.03749009, 0.04271334, 0.05208972, 0.04900773,\n", + " 0.04033953, 0.03851586, 0.03935321, 0.04754742, 0.04470578],\n", + " [0.0262787 , 0.03329944, 0.05123277, 0.0701023 , 0.06495178,\n", + " 0.04344618, 0.03398086, 0.04398188, 0.061164 , 0.05682356]]), 'biomass': array([[0.09115479, 0.08997756, 0.08649157, 0.07433399, 0.06800032,\n", + " 0.05271491, 0.04309241, 0.03581423, 0.03456725, 0.04031687],\n", + " [0.07469058, 0.08492724, 0.08629122, 0.08221583, 0.08439487,\n", + " 0.07280027, 0.06313366, 0.05161642, 0.05001541, 0.05675889],\n", + " [0.06575994, 0.07580066, 0.08004687, 0.08584272, 0.094165 ,\n", + " 0.08861426, 0.08105403, 0.07043309, 0.0666205 , 0.06767424],\n", + " [0.06558951, 0.0650699 , 0.06809078, 0.07681722, 0.09213968,\n", + " 0.09700104, 0.094628 , 0.08709447, 0.08251218, 0.08264996],\n", + " [0.06589344, 0.06386188, 0.06819127, 0.0705628 , 0.08226171,\n", + " 0.09724766, 0.09719529, 0.08474886, 0.07769158, 0.08314035],\n", + " [0.08261557, 0.07893287, 0.07676252, 0.07147858, 0.07872951,\n", + " 0.09780815, 0.09760535, 0.0815784 , 0.06998662, 0.07422279],\n", + " [0.08234714, 0.0826499 , 0.07545828, 0.07564932, 0.08504248,\n", + " 0.09673592, 0.09106467, 0.0776875 , 0.07488238, 0.08637822],\n", + " [0.06759061, 0.07431449, 0.07300329, 0.08153172, 0.09243321,\n", + " 0.09454746, 0.08356736, 0.0750623 , 0.08108772, 0.09825676],\n", + " [0.05388187, 0.0604621 , 0.07043508, 0.08765855, 0.09356382,\n", + " 0.08954647, 0.07888086, 0.07354123, 0.08654159, 0.10540041],\n", + " [0.0577439 , 0.0611029 , 0.07912103, 0.10049146, 0.10275279,\n", + " 0.09235748, 0.08072466, 0.0836548 , 0.1053173 , 0.12293946]])}, 'time': 7.0}, {'fields': {'glucose': array([[ 6.25435024, 6.24924372, 7.24947081, 8.77518871, 8.74554268,\n", + " 7.67540099, 7.88823447, 8.57588641, 9.19996581, 9.33140136],\n", + " [ 8.3445607 , 7.58273233, 7.45742134, 8.37112588, 8.74509624,\n", + " 8.25532257, 8.50454939, 9.13240278, 9.18494428, 8.40723084],\n", + " [10.88816311, 9.80962476, 8.69138174, 8.48682966, 8.52429902,\n", + " 8.24486319, 8.22974866, 8.8618623 , 8.95270152, 7.99410943],\n", + " [11.42771519, 10.93195012, 9.94917523, 8.99091701, 8.20044131,\n", + " 7.69926913, 7.74626965, 8.67558878, 9.05765555, 8.52304759],\n", + " [10.2613159 , 10.40749439, 10.25245614, 9.42229286, 8.14908336,\n", + " 7.48183835, 7.82852676, 8.97094752, 9.58155686, 9.29019038],\n", + " [ 8.74947405, 8.99000567, 9.06506678, 8.54392931, 7.59011607,\n", + " 7.16410492, 7.88736231, 8.97786486, 9.49135751, 9.03842808],\n", + " [ 8.35211881, 8.41273248, 8.09209603, 7.62712487, 7.19618117,\n", + " 7.09957509, 8.0812688 , 9.09846618, 9.13819123, 7.98842651],\n", + " [ 9.5992608 , 9.55271468, 8.78519071, 8.03570126, 7.42472368,\n", + " 7.17843436, 7.95727421, 8.88854992, 8.96226564, 7.60525197],\n", + " [10.24821621, 10.38682586, 9.98559154, 9.2932269 , 8.26793695,\n", + " 7.41194997, 7.7190207 , 8.51971211, 8.7820572 , 7.52447236],\n", + " [ 8.83102215, 9.49543579, 10.19905431, 10.41646008, 9.35891265,\n", + " 7.65607227, 7.279204 , 8.10099282, 8.5648313 , 7.49553473]]), 'acetate': array([[0.02948766, 0.03143768, 0.04268214, 0.04936025, 0.04707864,\n", + " 0.03147137, 0.02627485, 0.02309135, 0.02308422, 0.02559041],\n", + " [0.03982278, 0.04097405, 0.04304759, 0.05168494, 0.05804306,\n", + " 0.04717772, 0.04124193, 0.03547984, 0.03305403, 0.03131052],\n", + " [0.04942317, 0.05165457, 0.04960624, 0.05518276, 0.06272482,\n", + " 0.05676007, 0.0497188 , 0.04648391, 0.04409569, 0.03809273],\n", + " [0.05322275, 0.05116513, 0.04976209, 0.05205362, 0.0577712 ,\n", + " 0.05636244, 0.0533784 , 0.05633895, 0.05598673, 0.0529891 ],\n", + " [0.04972126, 0.04909938, 0.05216068, 0.0504315 , 0.05087537,\n", + " 0.05427183, 0.05643651, 0.05698271, 0.05594125, 0.05817516],\n", + " [0.05357156, 0.05275805, 0.05252902, 0.04629923, 0.04441354,\n", + " 0.05043302, 0.05719931, 0.05420234, 0.04908265, 0.04854694],\n", + " [0.05008097, 0.05091159, 0.04511524, 0.04224381, 0.04503862,\n", + " 0.04933168, 0.05542032, 0.05308965, 0.04948941, 0.04563344],\n", + " [0.04703177, 0.05200583, 0.04749232, 0.04903934, 0.05141627,\n", + " 0.04989116, 0.05061114, 0.05091303, 0.05333842, 0.05036001],\n", + " [0.03869287, 0.04543511, 0.05213638, 0.06154973, 0.05890897,\n", + " 0.04941771, 0.04644479, 0.04861233, 0.05713115, 0.05531649],\n", + " [0.03371998, 0.04182472, 0.06024199, 0.07874568, 0.07388292,\n", + " 0.05289886, 0.04323826, 0.05269069, 0.06930484, 0.067124 ]]), 'biomass': array([[0.09656189, 0.09612522, 0.09242207, 0.08152431, 0.07418298,\n", + " 0.0594438 , 0.04883138, 0.04099893, 0.03964457, 0.044638 ],\n", + " [0.08222846, 0.0903998 , 0.09192856, 0.08876697, 0.08914431,\n", + " 0.07830667, 0.06788861, 0.05703462, 0.0549736 , 0.060188 ],\n", + " [0.07283914, 0.08122266, 0.08595363, 0.09162181, 0.09902603,\n", + " 0.09452404, 0.08666737, 0.07640228, 0.07227751, 0.0731907 ],\n", + " [0.07103289, 0.07159283, 0.0752246 , 0.08377761, 0.09765118,\n", + " 0.10297884, 0.10037014, 0.09242298, 0.08752332, 0.08766759],\n", + " [0.07251138, 0.07110293, 0.07440965, 0.07784661, 0.08965029,\n", + " 0.10337589, 0.10331098, 0.09179575, 0.08474064, 0.08837449],\n", + " [0.08713861, 0.08415919, 0.08175753, 0.07873082, 0.08692645,\n", + " 0.10343941, 0.10305923, 0.08847495, 0.07832163, 0.08171579],\n", + " [0.08735262, 0.08726765, 0.08192857, 0.08271918, 0.09202796,\n", + " 0.10247158, 0.09736246, 0.085044 , 0.08241308, 0.09212384],\n", + " [0.07367986, 0.07906068, 0.07972376, 0.08820881, 0.09828803,\n", + " 0.1004158 , 0.09066124, 0.08268722, 0.0885879 , 0.10386891],\n", + " [0.06058372, 0.06709255, 0.07778809, 0.0941268 , 0.10059986,\n", + " 0.09665128, 0.08639575, 0.08232868, 0.09517211, 0.11270964],\n", + " [0.06244772, 0.06734338, 0.08490513, 0.10530548, 0.10864961,\n", + " 0.09920872, 0.08836025, 0.09117521, 0.11144723, 0.12896174]])}, 'time': 8.0}, {'fields': {'glucose': array([[ 6.38301241, 6.4033188 , 7.2445845 , 8.51075081, 8.57111189,\n", + " 7.79736986, 7.95435722, 8.5801719 , 9.1065915 , 9.18730073],\n", + " [ 8.24043137, 7.65006562, 7.57266769, 8.28407213, 8.55660632,\n", + " 8.19518727, 8.39549894, 8.94448818, 9.03193892, 8.471897 ],\n", + " [10.50827017, 9.61575894, 8.69725162, 8.45968918, 8.39219782,\n", + " 8.13614703, 8.18883354, 8.74043195, 8.81921544, 8.1119414 ],\n", + " [11.12453351, 10.64443238, 9.77783732, 8.91307876, 8.16222478,\n", + " 7.69424101, 7.79231917, 8.5805164 , 8.92279369, 8.51657523],\n", + " [10.1630417 , 10.21359134, 9.96583619, 9.17854741, 8.07577629,\n", + " 7.48235854, 7.8108316 , 8.80370485, 9.34865045, 9.13209788],\n", + " [ 8.80570784, 8.97641091, 8.95109861, 8.42689077, 7.58091849,\n", + " 7.21002225, 7.84247627, 8.83897818, 9.29012921, 8.92717061],\n", + " [ 8.44126651, 8.4645289 , 8.16562124, 7.68668415, 7.21670357,\n", + " 7.13000355, 7.96630085, 8.88648999, 8.9583611 , 8.07555275],\n", + " [ 9.46246983, 9.37990364, 8.75831982, 8.05295664, 7.43790719,\n", + " 7.20740136, 7.87656762, 8.70317822, 8.73967896, 7.6731785 ],\n", + " [10.00355124, 10.10273279, 9.7821405 , 9.15101641, 8.21079973,\n", + " 7.44147428, 7.67464067, 8.37869706, 8.54197581, 7.54889 ],\n", + " [ 8.97434797, 9.51531983, 10.03832276, 10.07427566, 9.08655174,\n", + " 7.67088647, 7.35899232, 8.01959261, 8.33287419, 7.48414915]]), 'acetate': array([[0.03740661, 0.03984125, 0.05046841, 0.05754274, 0.05486131,\n", + " 0.03960475, 0.03280203, 0.02907471, 0.0288616 , 0.03110502],\n", + " [0.04840805, 0.049613 , 0.05253243, 0.06067927, 0.06542774,\n", + " 0.05500342, 0.0478962 , 0.04212894, 0.03950095, 0.03793246],\n", + " [0.05833548, 0.05994101, 0.05895118, 0.06429885, 0.07086049,\n", + " 0.06526495, 0.05839037, 0.05476002, 0.05183756, 0.04662115],\n", + " [0.06174837, 0.06026185, 0.05936314, 0.061757 , 0.06676631,\n", + " 0.06570195, 0.06330838, 0.06505452, 0.06432564, 0.06151911],\n", + " [0.05926821, 0.05878278, 0.06072521, 0.0594232 , 0.06022448,\n", + " 0.06341322, 0.06595837, 0.06659877, 0.06543183, 0.0666302 ],\n", + " [0.0622382 , 0.06157938, 0.06044681, 0.05511022, 0.05392046,\n", + " 0.05964823, 0.06603925, 0.06392832, 0.05928578, 0.05837562],\n", + " [0.0591755 , 0.05963039, 0.05449245, 0.05160074, 0.05379784,\n", + " 0.0583403 , 0.0640538 , 0.06238749, 0.05912721, 0.05587054],\n", + " [0.05562241, 0.0597253 , 0.05694597, 0.05844884, 0.06009963,\n", + " 0.0587044 , 0.05952445, 0.06019853, 0.06267828, 0.06039316],\n", + " [0.04719875, 0.05411276, 0.06208046, 0.07150198, 0.06911585,\n", + " 0.05913468, 0.05538436, 0.05849314, 0.06722249, 0.06643725],\n", + " [0.04195766, 0.05101721, 0.06981057, 0.08780467, 0.08325748,\n", + " 0.06295103, 0.05320125, 0.06212848, 0.07813766, 0.07783085]]), 'biomass': array([[0.10265702, 0.10263802, 0.09891717, 0.08899472, 0.08085497,\n", + " 0.06644377, 0.05497681, 0.04664947, 0.04505254, 0.04930393],\n", + " [0.08993039, 0.09655831, 0.09814124, 0.09559171, 0.09463678,\n", + " 0.08427005, 0.07330669, 0.06281419, 0.06030765, 0.06430627],\n", + " [0.08021859, 0.08736755, 0.09237213, 0.09795549, 0.10452298,\n", + " 0.10075505, 0.09271618, 0.08267529, 0.07826739, 0.07893311],\n", + " [0.07724769, 0.07855332, 0.08265406, 0.09109444, 0.10387079,\n", + " 0.10938144, 0.10658157, 0.09838635, 0.09319836, 0.09316936],\n", + " [0.07941545, 0.07851641, 0.08126298, 0.08556473, 0.09738592,\n", + " 0.11004068, 0.10990571, 0.09914468, 0.09210987, 0.0943645 ],\n", + " [0.09232557, 0.08987317, 0.08760849, 0.08640881, 0.09525974,\n", + " 0.10978779, 0.10924188, 0.09594761, 0.08689075, 0.08951219],\n", + " [0.09279772, 0.09253791, 0.08871213, 0.09024371, 0.09945849,\n", + " 0.1088474 , 0.10420811, 0.09288055, 0.0904175 , 0.09864723],\n", + " [0.0800897 , 0.08463025, 0.08682073, 0.09536126, 0.1048803 ,\n", + " 0.1069696 , 0.09823059, 0.09090483, 0.09661257, 0.11028498],\n", + " [0.06756177, 0.07409862, 0.08536746, 0.10109144, 0.10794863,\n", + " 0.1042137 , 0.09452159, 0.09143973, 0.10403461, 0.12044162],\n", + " [0.06785953, 0.07394155, 0.09123981, 0.11085573, 0.11510767,\n", + " 0.1066044 , 0.09650542, 0.09928134, 0.11839816, 0.13560764]])}, 'time': 9.0}, {'fields': {'glucose': array([[ 6.48448545, 6.52312971, 7.23439414, 8.29032294, 8.41007623,\n", + " 7.86184124, 7.99495259, 8.55825093, 9.0082559 , 9.06288871],\n", + " [ 8.14143526, 7.68258085, 7.63591484, 8.18986016, 8.39160159,\n", + " 8.12622409, 8.30072948, 8.78612554, 8.89863265, 8.49759032],\n", + " [10.17473818, 9.43358541, 8.66789657, 8.40869161, 8.27074196,\n", + " 8.0390494 , 8.13095747, 8.61783339, 8.70179972, 8.18223649],\n", + " [10.83235708, 10.37857261, 9.60419947, 8.81370782, 8.10559087,\n", + " 7.67438933, 7.80010561, 8.47994762, 8.79065318, 8.48908097],\n", + " [10.04461261, 10.02270974, 9.7141123 , 8.96754352, 7.99608282,\n", + " 7.47016276, 7.7771645 , 8.64684002, 9.13570365, 8.98091782],\n", + " [ 8.83608648, 8.9432019 , 8.84229477, 8.31809751, 7.55582545,\n", + " 7.22973604, 7.78669146, 8.68907455, 9.09571835, 8.81347095],\n", + " [ 8.49549699, 8.48824294, 8.20101498, 7.71552971, 7.22897307,\n", + " 7.14079819, 7.85900915, 8.68954639, 8.78757523, 8.11004574],\n", + " [ 9.32947596, 9.22956658, 8.70861153, 8.04637142, 7.43902931,\n", + " 7.21740819, 7.79018585, 8.5206135 , 8.54305117, 7.70333616],\n", + " [ 9.79611975, 9.86311163, 9.59107567, 9.00236255, 8.13466993,\n", + " 7.44608707, 7.62631667, 8.23251618, 8.33102726, 7.54110538],\n", + " [ 9.06200405, 9.49455581, 9.86888247, 9.77160026, 8.84982392,\n", + " 7.65858021, 7.39688495, 7.92613941, 8.12969038, 7.44864435]]), 'acetate': array([[0.0461356 , 0.04896382, 0.05905392, 0.06626193, 0.06323552,\n", + " 0.048306 , 0.04009865, 0.03576854, 0.03528094, 0.03722276],\n", + " [0.05764125, 0.05893322, 0.06246963, 0.0701092 , 0.07348164,\n", + " 0.06333189, 0.05529895, 0.04938515, 0.04655416, 0.04509347],\n", + " [0.06784594, 0.06904598, 0.06890129, 0.07400701, 0.07955021,\n", + " 0.07425121, 0.0675004 , 0.06349268, 0.06017166, 0.0555917 ],\n", + " [0.07110158, 0.07005321, 0.06956912, 0.07199716, 0.07637955,\n", + " 0.07555645, 0.07357942, 0.07439518, 0.07326127, 0.07060077],\n", + " [0.06943445, 0.06901397, 0.07010289, 0.06912986, 0.07018724,\n", + " 0.07322911, 0.07602758, 0.07674176, 0.07544942, 0.07583713],\n", + " [0.07165042, 0.07100614, 0.06926257, 0.06466229, 0.06401981,\n", + " 0.06946163, 0.0755651 , 0.07424044, 0.0701032 , 0.06890273],\n", + " [0.06881858, 0.06897471, 0.0644559 , 0.06164288, 0.0633667 ,\n", + " 0.06790755, 0.07335068, 0.07236018, 0.06952874, 0.06675516],\n", + " [0.0648279 , 0.06835748, 0.06702056, 0.06856739, 0.06961852,\n", + " 0.06823659, 0.0690945 , 0.07021938, 0.07281397, 0.07118274],\n", + " [0.05642466, 0.06354479, 0.07257732, 0.08197413, 0.07971962,\n", + " 0.06950133, 0.06526009, 0.06902344, 0.07787628, 0.07806323],\n", + " [0.05101299, 0.06089401, 0.07997228, 0.09738766, 0.09314522,\n", + " 0.0736105 , 0.06387497, 0.07230477, 0.08770958, 0.08897995]]), 'biomass': array([[0.10941785, 0.10961361, 0.10598097, 0.09681512, 0.08803802,\n", + " 0.07378699, 0.06157467, 0.05277715, 0.05083655, 0.05437068],\n", + " [0.0979168 , 0.10337617, 0.10494763, 0.10280136, 0.10083329,\n", + " 0.09073783, 0.07935365, 0.06901434, 0.06606503, 0.06906711],\n", + " [0.08798879, 0.09420651, 0.09934737, 0.10485288, 0.11067849,\n", + " 0.10739418, 0.09923695, 0.08932464, 0.08464111, 0.08499381],\n", + " [0.08417987, 0.08600359, 0.0904708 , 0.09884353, 0.11076151,\n", + " 0.11627027, 0.1133052 , 0.10496435, 0.09951088, 0.09920606],\n", + " [0.08669503, 0.0862223 , 0.08873259, 0.09375539, 0.10553499,\n", + " 0.1172681 , 0.11702784, 0.10688949, 0.09988322, 0.10106734],\n", + " [0.09816094, 0.09614138, 0.09424512, 0.09456109, 0.10386507,\n", + " 0.11683556, 0.11615182, 0.10399545, 0.09578321, 0.09771186],\n", + " [0.09874337, 0.09846277, 0.09592311, 0.09825017, 0.10738652,\n", + " 0.11589391, 0.11165641, 0.10125565, 0.09894473, 0.10593787],\n", + " [0.08689702, 0.09094927, 0.09435552, 0.10303662, 0.1121783 ,\n", + " 0.11422147, 0.10635439, 0.09971617, 0.10520358, 0.11750032],\n", + " [0.07489223, 0.08152843, 0.09327163, 0.10857569, 0.11572017,\n", + " 0.11229736, 0.10325264, 0.10096428, 0.11325274, 0.12866725],\n", + " [0.07396194, 0.08097423, 0.09814031, 0.11714094, 0.12216396,\n", + " 0.11457835, 0.10521548, 0.10800841, 0.12614264, 0.1429218 ]])}, 'time': 10.0}]}\n" + ] + } + ], + "source": [ + "n_bins = (10, 10)\n", + "\n", + "initial_glucose = np.random.uniform(low=0, high=20, size=n_bins)\n", + "initial_acetate = np.random.uniform(low=0, high=0, size=n_bins)\n", + "initial_biomass = np.random.uniform(low=0, high=0.1, size=n_bins)\n", + "\n", + "dfba_processes_dict = {}\n", + "for i in range(n_bins[0]):\n", + " for j in range(n_bins[1]):\n", + " dfba_processes_dict[f'[{i},{j}]'] = {\n", + " '_type': 'process',\n", + " 'address': 'local:DynamicFBA',\n", + " 'config': dfba_config(),\n", + " 'inputs': {\n", + " 'substrates': {\n", + " 'glucose': ['..', 'fields', 'glucose', i, j],\n", + " 'acetate': ['..', 'fields', 'acetate', i, j],\n", + " 'biomass': ['..', 'fields', 'biomass', i, j],\n", + " }\n", + " },\n", + " 'outputs': {\n", + " 'substrates': {\n", + " 'glucose': ['..', 'fields', 'glucose', i, j],\n", + " 'acetate': ['..', 'fields', 'acetate', i, j],\n", + " 'biomass': ['..', 'fields', 'biomass', i, j]\n", + " }\n", + " }\n", + " }\n", + "\n", + "composite_state = {\n", + " 'fields': {\n", + " '_type': 'map',\n", + " '_value': {\n", + " '_type': 'array',\n", + " '_shape': n_bins,\n", + " '_data': 'positive_float'\n", + " },\n", + " 'glucose': initial_glucose,\n", + " 'acetate': initial_acetate,\n", + " 'biomass': initial_biomass,\n", + " },\n", + " 'spatial_dfba': dfba_processes_dict,\n", + " 'diffusion': {\n", + " '_type': 'process',\n", + " 'address': 'local:DiffusionAdvection',\n", + " 'config': {\n", + " 'n_bins': n_bins,\n", + " 'bounds': (10, 10),\n", + " 'default_diffusion_rate': 1e-1,\n", + " 'default_diffusion_dt': 1e-1,\n", + " 'diffusion_coeffs': {\n", + " 'glucose': 1e-1,\n", + " 'acetate': 1e-1,\n", + " 'biomass': 1e-1,\n", + " },\n", + " 'advection_coeffs': {\n", + " 'glucose': (0, 0),\n", + " 'acetate': (0, 0),\n", + " 'biomass': (0, 0),\n", + " },\n", + " },\n", + " 'inputs': {\n", + " 'fields': ['fields']\n", + " },\n", + " 'outputs': {\n", + " 'fields': ['fields']\n", + " }\n", + " },\n", + " 'emitter': {\n", + " '_type': 'step',\n", + " 'address': 'local:ram-emitter',\n", + " 'config': {\n", + " 'emit': {\n", + " 'fields': 'map',\n", + " 'time': 'float',\n", + " }\n", + " },\n", + " 'inputs': {\n", + " 'fields': ['fields'],\n", + " 'time': ['global_time']\n", + " }\n", + " }\n", + "}\n", + "\n", + "sim = Composite({'state': composite_state}, core=core)\n", + "\n", + "sim.update({}, 10.0)\n", + "\n", + "results = sim.gather_results()\n", + "\n", + "print(results)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python (process-bigraph)", + "language": "python", + "name": "process-bigraph" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/process_bigraph/composite.py b/process_bigraph/composite.py index ad8439a..1df335f 100644 --- a/process_bigraph/composite.py +++ b/process_bigraph/composite.py @@ -10,7 +10,7 @@ from typing import Dict from bigraph_schema import Edge, TypeSystem, get_path, set_path, deep_merge -from bigraph_schema.registry import Registry +from bigraph_schema.registry import Registry, is_schema_key, hierarchy_depth, strip_schema_keys from process_bigraph.process_types import process_types from process_bigraph.protocols import local_lookup, local_lookup_module @@ -231,26 +231,6 @@ def initialize_edge_state(self, schema, path, edge): return state -def hierarchy_depth(hierarchy, path=()): - """ - Create a mapping of every path in the hierarchy to the node living at - that path in the hierarchy. - """ - - base = {} - - for key, inner in hierarchy.items(): - down = tuple(path + (key,)) - if key.startswith('_'): - base[path] = inner - elif isinstance(inner, dict) and 'instance' not in inner: - base.update(hierarchy_depth(inner, down)) - else: - base[down] = inner - - return base - - class SyncUpdate(): def __init__(self, update): self.update = update @@ -400,7 +380,7 @@ def find_instances(state, instance_type='process_bigraph.composite.Process'): if isinstance(inner, dict): if isinstance(inner.get('instance'), process_class): found[key] = inner - elif not key.startswith('_'): + elif not is_schema_key(key): inner_instances = find_instances( inner, instance_type=instance_type) @@ -605,7 +585,6 @@ class Composite(Process): Composite parent class. """ - config_schema = { 'composition': 'schema', 'state': 'tree[any]', @@ -615,7 +594,8 @@ class Composite(Process): 'bridge': { 'inputs': 'wires', 'outputs': 'wires'}, - 'global_time_precision': 'maybe[float]'} + 'global_time_precision': 'maybe[float]', + } def __init__(self, config=None, core=None): @@ -784,6 +764,9 @@ def process_update( Tuple of the deferred update (in absolute terms) and ``store``. """ + + states = strip_schema_keys(states) + update = process['instance'].invoke(states, interval) def defer_project(update, args): @@ -887,7 +870,8 @@ def apply_updates(self, updates): self.interface()['outputs'], self.bridge['outputs'], (), - update) + top_schema=self.composition, + top_state=update) if bridge_update: self.bridge_updates.append(bridge_update) diff --git a/process_bigraph/experiments/comets.py b/process_bigraph/experiments/comets.py new file mode 100644 index 0000000..215a9e4 --- /dev/null +++ b/process_bigraph/experiments/comets.py @@ -0,0 +1,485 @@ +import numpy as np +from process_bigraph import Process, ProcessTypes, Composite +from process_bigraph.experiments.parameter_scan import RunProcess +import matplotlib.pyplot as plt +from scipy.ndimage import convolve +import cobra +from cobra.io import load_model + +core = ProcessTypes() + + +# create new types +def apply_non_negative(schema, current, update, core): + new_value = current + update + return max(0, new_value) + +positive_float = { + '_type': 'positive_float', + '_inherit': 'float', + '_apply': apply_non_negative +} +core.register('positive_float', positive_float) + +bounds_type = { + 'lower': 'maybe[float]', + 'upper': 'maybe[float]' +} +core.register_process('bounds', bounds_type) + + +# TODO -- check the function signature of the apply method and report missing keys upon registration + +class DynamicFBA(Process): + """ + Performs dynamic FBA. + + Parameters: + - model: The metabolic model for the simulation. + - kinetic_params: Kinetic parameters (Km and Vmax) for each substrate. + - biomass_reaction: The identifier for the biomass reaction in the model. + - substrate_update_reactions: A dictionary mapping substrates to their update reactions. + - biomass_identifier: The identifier for biomass in the current state. + + TODO -- check units + """ + + config_schema = { + 'model_file': 'string', + 'kinetic_params': 'map[tuple[float,float]]', + 'biomass_reaction': { + '_type': 'string', + '_default': 'Biomass_Ecoli_core' + }, + 'substrate_update_reactions': 'map[string]', + 'biomass_identifier': 'string', + 'bounds': 'map[bounds]', + } + + def __init__(self, config, core): + super().__init__(config, core) + + if not 'xml' in self.config['model_file']: + # use the textbook model if no model file is provided + self.model = load_model(self.config['model_file']) + else: + self.model = cobra.io.read_sbml_model(self.config['model_file']) + + for reaction_id, bounds in self.config['bounds'].items(): + if bounds['lower'] is not None: + self.model.reactions.get_by_id(reaction_id).lower_bound = bounds['lower'] + if bounds['upper'] is not None: + self.model.reactions.get_by_id(reaction_id).upper_bound = bounds['upper'] + + def inputs(self): + return { + 'substrates': 'map[positive_float]' + } + + def outputs(self): + return { + 'substrates': 'map[positive_float]' + } + + # TODO -- can we just put the inputs/outputs directly in the function? + def update(self, state, interval): + substrates_input = state['substrates'] + + for substrate, reaction_id in self.config['substrate_update_reactions'].items(): + Km, Vmax = self.config['kinetic_params'][substrate] + substrate_concentration = substrates_input[substrate] + uptake_rate = Vmax * substrate_concentration / (Km + substrate_concentration) + self.model.reactions.get_by_id(reaction_id).lower_bound = -uptake_rate + + substrate_update = {} + + solution = self.model.optimize() + if solution.status == 'optimal': + current_biomass = substrates_input[self.config['biomass_identifier']] + biomass_growth_rate = solution.fluxes[self.config['biomass_reaction']] + substrate_update[self.config['biomass_identifier']] = biomass_growth_rate * current_biomass * interval + + for substrate, reaction_id in self.config['substrate_update_reactions'].items(): + flux = solution.fluxes[reaction_id] + substrate_update[substrate] = flux * current_biomass * interval + # TODO -- assert not negative? + else: + # Handle non-optimal solutions if necessary + # print('Non-optimal solution, skipping update') + for substrate, reaction_id in self.config['substrate_update_reactions'].items(): + substrate_update[substrate] = 0 + + return { + 'substrates': substrate_update, + } + +core.register_process('DynamicFBA', DynamicFBA) + + +# Laplacian for 2D diffusion +LAPLACIAN_2D = np.array([[0, 1, 0], + [1, -4, 1], + [0, 1, 0]]) + + +class DiffusionAdvection(Process): + config_schema = { + 'n_bins': 'tuple[integer,integer]', + 'bounds': 'tuple[float,float]', + 'default_diffusion_rate': {'_type': 'float', '_default': 1e-1}, + 'default_diffusion_dt': {'_type': 'float', '_default': 1e-1}, + 'diffusion_coeffs': 'map[float]', + 'advection_coeffs': 'map[tuple[float,float]]', + } + + def __init__(self, config, core): + super().__init__(config, core) + + # get diffusion rates + bins_x = self.config['n_bins'][0] + bins_y = self.config['n_bins'][1] + length_x = self.config['bounds'][0] + length_y = self.config['bounds'][1] + dx = length_x / bins_x + dy = length_y / bins_y + dx2 = dx * dy + + # general diffusion rate + diffusion_rate = self.config['default_diffusion_rate'] + self.diffusion_rate = diffusion_rate / dx2 + + # diffusion rates for each individual molecules + self.molecule_specific_diffusion = { + mol_id: diff_rate / dx2 + for mol_id, diff_rate in self.config['diffusion_coeffs'].items()} + + # get diffusion timestep + diffusion_dt = 0.5 * dx ** 2 * dy ** 2 / (2 * diffusion_rate * (dx ** 2 + dy ** 2)) + self.diffusion_dt = min(diffusion_dt, self.config['default_diffusion_dt']) + + def inputs(self): + return { + 'fields': { + '_type': 'map', + '_value': { + '_type': 'array', + '_shape': self.config['n_bins'], + '_data': 'positive_float' + }, + } + } + + def outputs(self): + return { + 'fields': { + '_type': 'map', + '_value': { + '_type': 'array', + '_shape': self.config['n_bins'], + '_data': 'positive_float' + }, + } + } + + def update(self, state, interval): + fields = state['fields'] + + fields_update = {} + for species, field in fields.items(): + fields_update[species] = self.diffusion_delta( + field, + interval, + diffusion_coeff=self.config['diffusion_coeffs'][species], + advection_coeff=self.config['advection_coeffs'][species] + ) + + return { + 'fields': fields_update + } + + def diffusion_delta(self, state, interval, diffusion_coeff, advection_coeff): + t = 0.0 + dt = min(interval, self.diffusion_dt) + updated_state = state.copy() + + while t < interval: + + # Diffusion + laplacian = convolve( + updated_state, + LAPLACIAN_2D, + mode='reflect', + ) * diffusion_coeff + + # Advection + advective_flux_x = convolve( + updated_state, + np.array([[-1, 0, 1]]), + mode='reflect', + ) * advection_coeff[0] + advective_flux_y = convolve( + updated_state, + np.array([[-1], [0], [1]]), + mode='reflect', + ) * advection_coeff[1] + + # Update the current state + updated_state += (laplacian + advective_flux_x + advective_flux_y) * dt + + # # Ensure non-negativity + # current_states[species] = np.maximum(updated_state, 0) + + # Update time + t += dt + + return updated_state - state + +core.register_process('DiffusionAdvection', DiffusionAdvection) + + +def dfba_config( + model_file='textbook', + kinetic_params={ + 'glucose': (0.5, 1), + 'acetate': (0.5, 2)}, + biomass_reaction='Biomass_Ecoli_core', + substrate_update_reactions={ + 'glucose': 'EX_glc__D_e', + 'acetate': 'EX_ac_e'}, + biomass_identifier='biomass', + bounds={ + 'EX_o2_e': {'lower': -2, 'upper': None}, + 'ATPM': {'lower': 1, 'upper': 1}} +): + return { + 'model_file': model_file, + 'kinetic_params': kinetic_params, + 'biomass_reaction': biomass_reaction, + 'substrate_update_reactions': substrate_update_reactions, + 'biomass_identifier': biomass_identifier, + 'bounds': bounds + } + + +# TODO -- this should be imported, or just part of Process? +def run_process( + address, + config, + core_type, + initial_state, + observables, + timestep=1, + runtime=10 +): + config = { + 'process_address': address, + 'process_config': config, + 'observables': observables, + 'timestep': timestep, + 'runtime': runtime} + + run = RunProcess(config, core_type) + return run.update(initial_state) + + +def run_dfba_spatial(): + n_bins = (2, 2) + + initial_glucose = np.random.uniform(low=0, high=20, size=n_bins) + initial_acetate = np.random.uniform(low=0, high=0, size=n_bins) + initial_biomass = np.random.uniform(low=0, high=0.1, size=n_bins) + + dfba_processes_dict = {} + for i in range(n_bins[0]): + for j in range(n_bins[1]): + dfba_processes_dict[f'[{i},{j}]'] = { + '_type': 'process', + 'address': 'local:DynamicFBA', + 'config': dfba_config(), + 'inputs': { + 'substrates': { + 'glucose': ['..', 'fields', 'glucose', i, j], + 'acetate': ['..', 'fields', 'acetate', i, j], + 'biomass': ['..', 'fields', 'biomass', i, j], + } + }, + 'outputs': { + 'substrates': { + 'glucose': ['..', 'fields', 'glucose', i, j], + 'acetate': ['..', 'fields', 'acetate', i, j], + 'biomass': ['..', 'fields', 'biomass', i, j] + } + } + } + + composite_state = { + 'fields': { + '_type': 'map', + '_value': { + '_type': 'array', + '_shape': n_bins, + '_data': 'positive_float' + }, + 'glucose': initial_glucose, + 'acetate': initial_acetate, + 'biomass': initial_biomass, + }, + 'spatial_dfba': dfba_processes_dict + } + + sim = Composite({'state': composite_state}, core=core) + + + sim.update({}, 10.0) + + +def run_diffusion_process(): + n_bins = (4, 4) + + initial_glucose = np.random.uniform(low=0, high=20, size=n_bins) + initial_acetate = np.random.uniform(low=0, high=0, size=n_bins) + initial_biomass = np.random.uniform(low=0, high=0.1, size=n_bins) + + composite_state = { + 'fields': { + 'glucose': initial_glucose, + 'acetate': initial_acetate, + 'biomass': initial_biomass, + }, + 'diffusion': { + '_type': 'process', + 'address': 'local:DiffusionAdvection', + 'config': { + 'n_bins': n_bins, + 'bounds': (10, 10), + 'default_diffusion_rate': 1e-1, + 'default_diffusion_dt': 1e-1, + 'diffusion_coeffs': { + 'glucose': 1e-1, + 'acetate': 1e-1, + 'biomass': 1e-1, + }, + 'advection_coeffs': { + 'glucose': (0, 0), + 'acetate': (0, 0), + 'biomass': (0, 0), + }, + }, + 'inputs': { + 'fields': ['fields'] + }, + 'outputs': { + 'fields': ['fields'] + } + } + } + + sim = Composite({'state': composite_state}, core=core) + # sim.add_emitter() + + sim.update({}, 10.0) + + data = sim.gather_results() + + print(data) + + +def run_comets(): + n_bins = (10, 10) + + initial_glucose = np.random.uniform(low=0, high=20, size=n_bins) + initial_acetate = np.random.uniform(low=0, high=0, size=n_bins) + initial_biomass = np.random.uniform(low=0, high=0.1, size=n_bins) + + dfba_processes_dict = {} + for i in range(n_bins[0]): + for j in range(n_bins[1]): + dfba_processes_dict[f'[{i},{j}]'] = { + '_type': 'process', + 'address': 'local:DynamicFBA', + 'config': dfba_config(), + 'inputs': { + 'substrates': { + 'glucose': ['..', 'fields', 'glucose', i, j], + 'acetate': ['..', 'fields', 'acetate', i, j], + 'biomass': ['..', 'fields', 'biomass', i, j], + } + }, + 'outputs': { + 'substrates': { + 'glucose': ['..', 'fields', 'glucose', i, j], + 'acetate': ['..', 'fields', 'acetate', i, j], + 'biomass': ['..', 'fields', 'biomass', i, j] + } + } + } + + composite_state = { + 'fields': { + '_type': 'map', + '_value': { + '_type': 'array', + '_shape': n_bins, + '_data': 'positive_float' + }, + 'glucose': initial_glucose, + 'acetate': initial_acetate, + 'biomass': initial_biomass, + }, + 'spatial_dfba': dfba_processes_dict, + 'diffusion': { + '_type': 'process', + 'address': 'local:DiffusionAdvection', + 'config': { + 'n_bins': n_bins, + 'bounds': (10, 10), + 'default_diffusion_rate': 1e-1, + 'default_diffusion_dt': 1e-1, + 'diffusion_coeffs': { + 'glucose': 1e-1, + 'acetate': 1e-1, + 'biomass': 1e-1, + }, + 'advection_coeffs': { + 'glucose': (0, 0), + 'acetate': (0, 0), + 'biomass': (0, 0), + }, + }, + 'inputs': { + 'fields': ['fields'] + }, + 'outputs': { + 'fields': ['fields'] + } + }, + 'emitter': { + '_type': 'step', + 'address': 'local:ram-emitter', + 'config': { + 'emit': { + 'fields': 'map', + 'time': 'float', + } + }, + 'inputs': { + 'fields': ['fields'], + 'time': ['global_time'] + } + } + } + + sim = Composite({'state': composite_state}, core=core) + + sim.update({}, 10.0) + + results = sim.gather_results() + + print(results) + + + +if __name__ == '__main__': + # run_dfba_spatial() + # run_diffusion_process() + run_comets() diff --git a/process_bigraph/experiments/parameter_scan.py b/process_bigraph/experiments/parameter_scan.py index dfcf4ee..f95eddf 100644 --- a/process_bigraph/experiments/parameter_scan.py +++ b/process_bigraph/experiments/parameter_scan.py @@ -185,7 +185,7 @@ def __init__(self, config, core): **self.inputs_config), 'outputs': {}}}} - self.composite = Composite(composite_config) + self.composite = Composite(composite_config, core=core) def inputs(self):