def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.results_dir = tempfile.mkdtemp(dir=self.tmp_dir) self.models = ['static', 'one_reaction_linear', 'one_rxn_exponential', 'one_exchange_rxn_compt_growth', 'stop_conditions'] de_simulation_config = SimulationConfig(time_max=20, output_dir=tempfile.mkdtemp(dir=self.tmp_dir)) self.wc_sim_config = WCSimulationConfig(de_simulation_config, checkpoint_period=1)
def test_init(self): self.assertTrue(isinstance(self.nrm_submodel.options, dict)) # test NrmSubmodel() with default options=None wc_sim_config = WCSimulationConfig(SimulationConfig(time_max=10)) _, dynamic_model = MultialgorithmSimulation(self.model, wc_sim_config).build_simulation() nrm_submodel = dynamic_model.dynamic_submodels['nrm_submodel'] self.assertEquals(nrm_submodel.options, None)
def make_sim_w_nrm_submodel(self, model, auto_initialize): wc_lang.transform.PrepForWcSimTransform().run(model) de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) nrm_options = dict(auto_initialize=auto_initialize) options = {'NrmSubmodel': dict(options=nrm_options)} multialgorithm_simulation = MultialgorithmSimulation(model, wc_sim_config, options) return multialgorithm_simulation.build_simulation()
def setUp(self): self.model_file = os.path.join(os.path.dirname(__file__), 'fixtures', 'test_dynamic_expressions.xlsx') self.model = Reader().run(self.model_file)[Model][0] de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) multialgorithm_simulation = MultialgorithmSimulation( self.model, wc_sim_config) _, self.dynamic_model = multialgorithm_simulation.build_simulation()
def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.results_dir = tempfile.mkdtemp(dir=self.tmp_dir) self.args = dict(results_dir=tempfile.mkdtemp(dir=self.tmp_dir), checkpoint_period=1) de_simulation_config = SimulationConfig( time_max=10, output_dir=tempfile.mkdtemp(dir=self.tmp_dir)) self.wc_sim_config = WCSimulationConfig(de_simulation_config, checkpoint_period=1)
def make_dynamic_model(self, model_filename): # read and initialize a model self.model = TestDynamicModel.models[model_filename] de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) multialgorithm_simulation = MultialgorithmSimulation( self.model, wc_sim_config) multialgorithm_simulation.initialize_components() self.dynamic_model = DynamicModel( self.model, multialgorithm_simulation.local_species_population, multialgorithm_simulation.temp_dynamic_compartments)
def setUp(self): # read and initialize a model self.model = Reader().run(self.MODEL_FILENAME, ignore_extra_models=True)[Model][0] for conc in self.model.distribution_init_concentrations: conc.std = 0. PrepForWcSimTransform().run(self.model) de_simulation_config = SimulationConfig(time_max=10) self.wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1) self.multialgorithm_simulation = MultialgorithmSimulation(self.model, self.wc_sim_config) self.test_dir = tempfile.mkdtemp() self.results_dir = tempfile.mkdtemp(dir=self.test_dir)
def setUp(self): self.tempdir = tempfile.mkdtemp() self.time_max = 5 self.de_simulation_config = SimulationConfig(time_max=self.time_max) self.wc_sim_config = WCSimulationConfig(self.de_simulation_config) self.wc_simulation_metadata = WCSimulationMetadata(self.wc_sim_config) # fixtures to test obtaining git metadata self.test_repo_name = 'test_wc_sim_metadata' self.github_repo = GitHubRepoForTests(self.test_repo_name) self.repo_dir = tempfile.mkdtemp(dir=self.tempdir) self.github_repo.make_test_repo(self.repo_dir)
def test_initialize_infrastructure(self): self.multialgorithm_simulation.initialize_components() self.multialgorithm_simulation.initialize_infrastructure() self.assertTrue(isinstance(self.multialgorithm_simulation.dynamic_model, DynamicModel)) de_simulation_config = SimulationConfig(time_max=10, output_dir=self.results_dir) wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1, checkpoint_period=10) multialg_sim = MultialgorithmSimulation(self.model, wc_sim_config) multialg_sim.initialize_components() multialg_sim.initialize_infrastructure() self.assertEqual(multialg_sim.checkpointing_sim_obj.checkpoint_dir, self.results_dir) self.assertTrue(multialg_sim.checkpointing_sim_obj.access_state_object is not None) self.assertTrue(isinstance(multialg_sim.checkpointing_sim_obj, MultialgorithmicCheckpointingSimObj)) self.assertTrue(isinstance(multialg_sim.dynamic_model, DynamicModel))
def make_dynamic_submodel_params(model, lang_submodel): de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) multialgorithm_simulation = MultialgorithmSimulation(model, wc_sim_config) multialgorithm_simulation.initialize_components() multialgorithm_simulation.dynamic_model = \ DynamicModel(multialgorithm_simulation.model, multialgorithm_simulation.local_species_population, multialgorithm_simulation.temp_dynamic_compartments) return (lang_submodel.id, multialgorithm_simulation.dynamic_model, lang_submodel.reactions, lang_submodel.get_children(kind='submodel', __type=Species), multialgorithm_simulation.get_dynamic_compartments(lang_submodel), multialgorithm_simulation.local_species_population)
def make_ode_submodel(self, model, ode_time_step=1.0, submodel_name='submodel_1'): """ Make a MultialgorithmSimulation from a wc lang model """ # assume a single submodel # todo: test concurrent OdeSubmodels, perhaps self.ode_time_step = ode_time_step de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config, ode_time_step=ode_time_step) multialgorithm_simulation = MultialgorithmSimulation( model, wc_sim_config) simulation_engine, dynamic_model = multialgorithm_simulation.build_simulation( ) simulation_engine.initialize() submodel_1 = dynamic_model.dynamic_submodels[submodel_name] return submodel_1
def make_ssa_submodel(self, model, default_center_of_mass=None): PrepForWcSimTransform().run(model) de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) multialgorithm_simulation = MultialgorithmSimulation( model, wc_sim_config) multialgorithm_simulation.build_simulation() # todo: don't call SsaSubmodel(); return dynamic_model.dynamic_submodels['submodel name here'] will work; see test_nrm.py wc_lang_ssa_submodel = model.submodels[0] ssa_submodel = SsaSubmodel( model.id, multialgorithm_simulation.dynamic_model, list(wc_lang_ssa_submodel.reactions), wc_lang_ssa_submodel.get_children(kind='submodel', __type=Species), multialgorithm_simulation.get_dynamic_compartments( wc_lang_ssa_submodel), multialgorithm_simulation.local_species_population, default_center_of_mass=default_center_of_mass) return ssa_submodel
def test_dynamic_model(self): self.make_dynamic_model(self.MODEL_FILENAME) self.assertEqual(len(self.dynamic_model.cellular_dyn_compartments), 1) self.assertEqual(self.dynamic_model.cellular_dyn_compartments[0].id, 'c') self.assertEqual(self.dynamic_model.get_num_submodels(), 2) model = TestDynamicModel.models[self.MODEL_FILENAME] for compartment in self.model.get_compartments(): compartment.biological_type = onto['WC:extracellular_compartment'] de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) multialgorithm_simulation = MultialgorithmSimulation( model, wc_sim_config) multialgorithm_simulation.initialize_components() with self.assertRaisesRegex( MultialgorithmError, 'must have at least 1 cellular compartment'): DynamicModel(model, multialgorithm_simulation.local_species_population, multialgorithm_simulation.temp_dynamic_compartments)
def test_build_simulation(self): de_simulation_config = SimulationConfig(time_max=10, output_dir=self.results_dir) wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1, checkpoint_period=10) multialgorithm_simulation = MultialgorithmSimulation(self.model, wc_sim_config) simulation_engine, _ = multialgorithm_simulation.build_simulation() # 3 objects: 2 submodels, and the checkpointing obj: expected_sim_objs = set(['CHECKPOINTING_SIM_OBJ', 'submodel_1', 'submodel_2']) self.assertEqual(expected_sim_objs, set(list(simulation_engine.simulation_objects))) self.assertEqual(type(multialgorithm_simulation.checkpointing_sim_obj), MultialgorithmicCheckpointingSimObj) self.assertEqual(multialgorithm_simulation.dynamic_model.get_num_submodels(), 2) # check that submodels receive options dfba_options = dict(dfba='fast but inaccurate') ssa_options = dict(ssa='accurate but slow') options = {'DfbaSubmodel': dict(options=dfba_options), 'SsaSubmodel': dict(options=ssa_options) } multialgorithm_simulation = MultialgorithmSimulation(self.model, wc_sim_config, options) multialgorithm_simulation.build_simulation() dfba_submodel = multialgorithm_simulation.dynamic_model.dynamic_submodels['submodel_1'] ssa_submodel = multialgorithm_simulation.dynamic_model.dynamic_submodels['submodel_2'] self.assertEqual(dfba_submodel.options, dfba_options) self.assertEqual(ssa_submodel.options, ssa_options) # test skipped submodel submodels_to_skip = ['submodel_2'] self.wc_sim_config.submodels_to_skip = submodels_to_skip ma_sim = MultialgorithmSimulation(self.model, self.wc_sim_config) _, dynamic_model = ma_sim.build_simulation() expected_dynamic_submodels = set([sm.id for sm in self.model.get_submodels()]) - ma_sim.skipped_submodels() self.assertEqual(expected_dynamic_submodels, set(dynamic_model.dynamic_submodels)) submodel_1 = self.model.submodels.get(id='submodel_1')[0] # WC:modeling_framework is not an instance of a modeling framework submodel_1.framework = onto['WC:modeling_framework'] ma_sim = MultialgorithmSimulation(self.model, self.wc_sim_config) with self.assertRaisesRegex(MultialgorithmError, 'Unsupported lang_submodel framework'): ma_sim.build_simulation()
def test_calc_reaction_rates(self): # set standard deviation of initial conc. to 0 self.setUp(std_init_concentrations=0.) de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1) multialgorithm_simulation = MultialgorithmSimulation(self.model, wc_sim_config) _, dynamic_model = multialgorithm_simulation.build_simulation() # rate law for reaction_4-forward: k_cat_4_for * max(species_4[c], p_4) k_cat_4_for = 1 p_4 = 2 species_4_c_pop = \ multialgorithm_simulation.local_species_population.read_one(0, 'species_4[c]') expected_rate_reaction_4_forward = k_cat_4_for * max(species_4_c_pop, p_4) expected_rates = { 'reaction_2': 0.0, 'reaction_4': expected_rate_reaction_4_forward } for dynamic_submodel in multialgorithm_simulation.dynamic_model.dynamic_submodels.values(): rates = dynamic_submodel.calc_reaction_rates() for index, rxn in enumerate(dynamic_submodel.reactions): if rxn.id in expected_rates: self.assertAlmostEqual(list(rates)[index], expected_rates[rxn.id])
class Simulation(object): """ Simulate a multialgorithm model Attributes: model_path (:obj:`str`): path to a file describing a `wc_lang` model model (:obj:`Model`): a `wc_lang` model description dynamic_model (:obj:`DynamicModel`): the simulation's :obj:`DynamicModel` de_sim_config (:obj:`SimulationConfig`): a DE-Sim simulation configuration author_metadata (:obj:`AuthorMetadata`): metadata about the author of a whole-cell simulation run wc_sim_config (:obj:`WCSimulationConfig`): a WC-Sim simulation configuration simulation_engine (:obj:`SimulationEngine`): the simulation engine """ def __init__(self, model): """ Args: model (:obj:`str` or `Model`): either a path to file(s) describing a `wc_lang` model, or a `Model` instance Raises: :obj:`MultialgorithmError`: if `model` is invalid """ if isinstance(model, Model): self.model_path = None self.model = model elif isinstance(model, str): # read model self.model_path = os.path.abspath(os.path.expanduser(model)) self.model = Reader().run(self.model_path)[Model][0] else: raise MultialgorithmError( "model must be a `wc_lang Model` or a pathname for a model, " "but its type is {}".format(type(model))) def _prepare(self): """ Prepare and validate the model, and create simulation metadata """ # prepare & check the model PrepForWcSimTransform().run(self.model) errors = Validator().run(self.model) if errors: raise MultialgorithmError( indent_forest(['The model is invalid:', [errors]])) def run(self, time_max, results_dir=None, progress_bar=True, checkpoint_period=None, seed=None, ode_time_step=None, dfba_time_step=None, profile=False, submodels_to_skip=None, verbose=True, options=None): """ Run one simulation Args: time_max (:obj:`float`): the maximum time of a simulation; a stop condition may end it earlier (sec) results_dir (:obj:`str`, optional): path to a directory in which results are stored progress_bar (:obj:`bool`, optional): whether to show the progress of a simulation in in a real-time bar on a terminal checkpoint_period (:obj:`float`, optional): the period between simulation state checkpoints (sec) ode_time_step (:obj:`float`, optional): time step length of ODE submodel (sec) dfba_time_step (:obj:`float`, optional): time step length of dFBA submodel (sec) profile (:obj:`bool`, optional): whether to output a profile of the simulation's performance created by a Python profiler seed (:obj:`object`, optional): a seed for the simulation's `numpy.random.RandomState`; if provided, `seed` will reseed the simulator's PRNG submodels_to_skip (:obj:`list` of :obj:`str`, optional): submodels that should not be run, identified by their ids verbose (:obj:`bool`, optional): whether to print success output options (:obj:`dict`, optional): options for submodels, passed to `MultialgorithmSimulation` Returns: :obj:`tuple` of (`int`, `str`): number of simulation events, pathname of directory containing the results, or :obj:`tuple` of (`int`, `None`): number of simulation events, `None` if `results_dir is None`, or :obj:`tuple` of (`pstats.Stats`, `None`): profile stats, `None` if `profile is True` Raises: :obj:`MultialgorithmError`: if the simulation raises an exception """ self._prepare() # create simulation configurations # create and validate DE sim configuration self.de_sim_config = SimulationConfig(time_max, output_dir=results_dir, progress=progress_bar, profile=profile) self.de_sim_config.validate() # create and validate WC configuration self.wc_sim_config = WCSimulationConfig( de_simulation_config=self.de_sim_config, random_seed=seed, ode_time_step=ode_time_step, dfba_time_step=dfba_time_step, checkpoint_period=checkpoint_period, submodels_to_skip=submodels_to_skip, verbose=verbose) self.wc_sim_config.validate() # create author metadata for DE sim try: username = getpass.getuser() except KeyError: # pragma: no cover username = '******' self.author_metadata = AuthorMetadata( name='Unknown name', email='Unknown email', username=username, organization='Unknown organization') # create WC sim metadata wc_simulation_metadata = WCSimulationMetadata(self.wc_sim_config) if self.model_path is not None: wc_simulation_metadata.set_wc_model_repo(self.model_path) if seed is not None: RandomStateManager.initialize(seed=seed) # create a multi-algorithmic simulator multialgorithm_simulation = MultialgorithmSimulation( self.model, self.wc_sim_config, options) self.simulation_engine, self.dynamic_model = multialgorithm_simulation.build_simulation( ) self.simulation_engine.initialize() # set stop_condition after the dynamic model is created self.de_sim_config.stop_condition = self.dynamic_model.get_stop_condition( ) # run simulation try: # provide DE config and author metadata to DE sim simulate_rv = self.simulation_engine.simulate( sim_config=self.de_sim_config, author_metadata=self.author_metadata) # add WC sim metadata to the output after the simulation, which requires an empty output dir # TODO: have simulation_engine.simulate() allow certain files in self.de_sim_config.output_dir, and move # this code above if self.de_sim_config.output_dir is not None: WCSimulationMetadata.write_dataclass( wc_simulation_metadata, self.de_sim_config.output_dir) if profile: stats = simulate_rv return stats, None else: num_events = simulate_rv except SimulatorError as e: # pragma: no cover raise MultialgorithmError( f'Simulation terminated with simulator error:\n{e}') except BaseException as e: # pragma: no cover raise MultialgorithmError( f'Simulation terminated with error:\n{e}') if verbose: print(f'Simulated {num_events} events') if results_dir: # summarize results in an HDF5 file in results_dir RunResults(results_dir) if verbose: print(f"Saved checkpoints and run results in '{results_dir}'") return (num_events, results_dir) else: return (num_events, None) def get_simulation_engine(self): """ Provide the simulation's simulation engine Returns: :obj:`SimulationEngine`: the simulation's simulation engine """ if hasattr(self, 'simulation_engine'): return self.simulation_engine return None def provide_event_counts(self): """ Provide the last simulation's categorized event counts Returns: :obj:`str`: the last simulation's categorized event counts, in a tab-separated table """ if self.get_simulation_engine(): return self.get_simulation_engine().provide_event_counts() return 'execute run() to obtain event counts' def run_batch(self, results_dir, checkpoint_period): # pragma: no cover # not implemented """ Run all simulations specified by the simulation configuration Args: results_dir (:obj:`str`): path to a directory in which results should be stored checkpoint_period (:obj:`float`): the period between simulation state checkpoints (sec) Returns: :obj:`tuple` of (`int`, `str`): number of simulation events, pathname of directory containing the results """ # todo: implement; iterate over sim configs for simulation in self.sim_config.iterator(): # setup simulation changes pass
def setUp(self): self.results_dir = tempfile.mkdtemp() de_simulation_config = SimulationConfig(time_max=10, output_dir=self.results_dir) self.wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1, checkpoint_period=10) self.out_dir = tempfile.mkdtemp()
def test_deterministic_simulation_algorithm_submodel_statics(self): self.transform_model_for_dsa_simulation(self.model) prepare_model(self.model) de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1) multialgorithm_simulation = MultialgorithmSimulation(self.model, wc_sim_config) simulation_engine, _ = multialgorithm_simulation.build_simulation() simulation_engine.initialize() dsa_submodel_name = 'submodel_2' dsa_submodel = multialgorithm_simulation.dynamic_model.dynamic_submodels[dsa_submodel_name] self.assertTrue(isinstance(dsa_submodel, DsaSubmodel)) # test init: is reaction_table correct? self.assertEqual(len(dsa_submodel.reaction_table), len(dsa_submodel.reactions)) for rxn_id, rxn_index in dsa_submodel.reaction_table.items(): # map reaction id to index self.assertEqual(dsa_submodel.reactions[rxn_index].id, rxn_id) # test send_initial_events(), schedule_next_reaction_execution() & schedule_ExecuteDsaReaction() # all of dsa_submodel's reactions should be scheduled to execute events = simulation_engine.event_queue.render(sim_obj=dsa_submodel, as_list=True) reaction_indices = set() send_time_idx, _, sender_idx, receiver_idx, event_type_idx, reaction_idx = list(range(6)) for event_record in events[1:]: self.assertEqual(event_record[send_time_idx], (0.0,)) self.assertEqual(event_record[sender_idx], dsa_submodel_name) self.assertEqual(event_record[receiver_idx], dsa_submodel_name) self.assertEqual(event_record[event_type_idx], ExecuteDsaReaction.__name__) reaction_indices.add(event_record[reaction_idx]) self.assertEqual(reaction_indices, set([str(i) for i in range(len(dsa_submodel.reactions))])) # test handle_ExecuteDsaReaction_msg(): execute next reaction # reaction_3_forward has the highest reaction rate events = simulation_engine.event_queue.next_events() self.assertEqual(len(events), 1) event = events[0] self.assertEqual(dsa_submodel.reactions[event.message.reaction_index].id, 'reaction_3_forward') # reaction_3_forward: [c]: species_2 + (2) species_4 ==> species_5 # check population changes species = ['species_2[c]', 'species_4[c]', 'species_5[c]'] pops_before = {} populations = multialgorithm_simulation.local_species_population for species_id in species: pops_before[species_id] = populations.read_one(event.event_time, species_id) expected_pop_changes = dict(zip(species, [-1, -2, +1])) # set time of dsa_submodel to time of the event dsa_submodel.time = event.event_time dsa_submodel.handle_ExecuteDsaReaction_msg(event) for s_id, expected_pop_change in expected_pop_changes.items(): self.assertEqual(pops_before[s_id] + expected_pop_changes[s_id], populations.read_one(event.event_time, s_id)) # zero populations and test exception for species_id in species: pop = populations.read_one(event.event_time, species_id) populations.adjust_discretely(event.event_time, {species_id: -pop}) with self.assertRaises(DynamicMultialgorithmError): dsa_submodel.handle_ExecuteDsaReaction_msg(event) # test DsaSubmodel options expected = dict(a=1) options = dict(DsaSubmodel=dict(optiona=expected)) options = {'DsaSubmodel': {'options': expected } } de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config, dfba_time_step=1) multialgorithm_simulation = MultialgorithmSimulation(self.model, wc_sim_config, options) multialgorithm_simulation.build_simulation() dsa_submodel = multialgorithm_simulation.dynamic_model.dynamic_submodels['submodel_2'] self.assertEqual(dsa_submodel.options, expected)
def run(self, time_max, results_dir=None, progress_bar=True, checkpoint_period=None, seed=None, ode_time_step=None, dfba_time_step=None, profile=False, submodels_to_skip=None, verbose=True, options=None): """ Run one simulation Args: time_max (:obj:`float`): the maximum time of a simulation; a stop condition may end it earlier (sec) results_dir (:obj:`str`, optional): path to a directory in which results are stored progress_bar (:obj:`bool`, optional): whether to show the progress of a simulation in in a real-time bar on a terminal checkpoint_period (:obj:`float`, optional): the period between simulation state checkpoints (sec) ode_time_step (:obj:`float`, optional): time step length of ODE submodel (sec) dfba_time_step (:obj:`float`, optional): time step length of dFBA submodel (sec) profile (:obj:`bool`, optional): whether to output a profile of the simulation's performance created by a Python profiler seed (:obj:`object`, optional): a seed for the simulation's `numpy.random.RandomState`; if provided, `seed` will reseed the simulator's PRNG submodels_to_skip (:obj:`list` of :obj:`str`, optional): submodels that should not be run, identified by their ids verbose (:obj:`bool`, optional): whether to print success output options (:obj:`dict`, optional): options for submodels, passed to `MultialgorithmSimulation` Returns: :obj:`tuple` of (`int`, `str`): number of simulation events, pathname of directory containing the results, or :obj:`tuple` of (`int`, `None`): number of simulation events, `None` if `results_dir is None`, or :obj:`tuple` of (`pstats.Stats`, `None`): profile stats, `None` if `profile is True` Raises: :obj:`MultialgorithmError`: if the simulation raises an exception """ self._prepare() # create simulation configurations # create and validate DE sim configuration self.de_sim_config = SimulationConfig(time_max, output_dir=results_dir, progress=progress_bar, profile=profile) self.de_sim_config.validate() # create and validate WC configuration self.wc_sim_config = WCSimulationConfig( de_simulation_config=self.de_sim_config, random_seed=seed, ode_time_step=ode_time_step, dfba_time_step=dfba_time_step, checkpoint_period=checkpoint_period, submodels_to_skip=submodels_to_skip, verbose=verbose) self.wc_sim_config.validate() # create author metadata for DE sim try: username = getpass.getuser() except KeyError: # pragma: no cover username = '******' self.author_metadata = AuthorMetadata( name='Unknown name', email='Unknown email', username=username, organization='Unknown organization') # create WC sim metadata wc_simulation_metadata = WCSimulationMetadata(self.wc_sim_config) if self.model_path is not None: wc_simulation_metadata.set_wc_model_repo(self.model_path) if seed is not None: RandomStateManager.initialize(seed=seed) # create a multi-algorithmic simulator multialgorithm_simulation = MultialgorithmSimulation( self.model, self.wc_sim_config, options) self.simulation_engine, self.dynamic_model = multialgorithm_simulation.build_simulation( ) self.simulation_engine.initialize() # set stop_condition after the dynamic model is created self.de_sim_config.stop_condition = self.dynamic_model.get_stop_condition( ) # run simulation try: # provide DE config and author metadata to DE sim simulate_rv = self.simulation_engine.simulate( sim_config=self.de_sim_config, author_metadata=self.author_metadata) # add WC sim metadata to the output after the simulation, which requires an empty output dir # TODO: have simulation_engine.simulate() allow certain files in self.de_sim_config.output_dir, and move # this code above if self.de_sim_config.output_dir is not None: WCSimulationMetadata.write_dataclass( wc_simulation_metadata, self.de_sim_config.output_dir) if profile: stats = simulate_rv return stats, None else: num_events = simulate_rv except SimulatorError as e: # pragma: no cover raise MultialgorithmError( f'Simulation terminated with simulator error:\n{e}') except BaseException as e: # pragma: no cover raise MultialgorithmError( f'Simulation terminated with error:\n{e}') if verbose: print(f'Simulated {num_events} events') if results_dir: # summarize results in an HDF5 file in results_dir RunResults(results_dir) if verbose: print(f"Saved checkpoints and run results in '{results_dir}'") return (num_events, results_dir) else: return (num_events, None)
def test_dynamic_components(self): # test agregate properties like mass and volume against independent calculations of their values # calculations made in the model's spreadsheet # read model while ignoring missing models model = read_model_for_test(self.MODEL_FILENAME) # create dynamic model de_simulation_config = SimulationConfig(time_max=10) wc_sim_config = WCSimulationConfig(de_simulation_config) multialgorithm_simulation = MultialgorithmSimulation( model, wc_sim_config) multialgorithm_simulation.initialize_components() dynamic_model = DynamicModel( model, multialgorithm_simulation.local_species_population, multialgorithm_simulation.temp_dynamic_compartments) # a Model to store expected initial values class ExpectedInitialValue(obj_tables.Model): component = obj_tables.StringAttribute() attribute = obj_tables.StringAttribute() expected_initial_value = obj_tables.FloatAttribute() comment = obj_tables.StringAttribute() class Meta(obj_tables.Model.Meta): attribute_order = ('component', 'attribute', 'expected_initial_value', 'comment') # get calculations of expected initial values from the workbook expected_initial_values = \ obj_tables.io.Reader().run(self.MODEL_FILENAME, models=[ExpectedInitialValue], ignore_extra_models=True)[ExpectedInitialValue] for cellular_compartment in dynamic_model.cellular_dyn_compartments: compartment = dynamic_model.dynamic_compartments[ cellular_compartment.id] actual_values = { 'mass': compartment.mass(), 'volume': compartment.volume(), 'accounted mass': compartment.accounted_mass(), 'accounted volume': compartment.accounted_volume() } for expected_initial_value in expected_initial_values: if expected_initial_value.component == cellular_compartment.id: expected_value = expected_initial_value.expected_initial_value actual_value = actual_values[ expected_initial_value.attribute] numpy.testing.assert_approx_equal(actual_value, expected_value) # cell mass, cell volume, etc. actual_values = { 'cell mass': dynamic_model.cell_mass(), 'cell volume': dynamic_model.cell_volume(), 'cell accounted mass': dynamic_model.cell_accounted_mass(), 'cell accounted volume': dynamic_model.cell_accounted_volume() } for expected_initial_value in expected_initial_values: if expected_initial_value.component == 'whole_cell': expected_value = expected_initial_value.expected_initial_value actual_value = actual_values[ f"cell {expected_initial_value.attribute}"] numpy.testing.assert_approx_equal(actual_value, expected_value) # test dynamic_model.get_aggregate_state() aggregate_state = dynamic_model.get_aggregate_state() for eiv_record in expected_initial_values: expected_value = eiv_record.expected_initial_value if eiv_record.component == 'whole_cell': actual_value = aggregate_state[f"cell {eiv_record.attribute}"] numpy.testing.assert_approx_equal(actual_value, expected_value) else: actual_value = aggregate_state['compartments'][ eiv_record.component][eiv_record.attribute] numpy.testing.assert_approx_equal(actual_value, expected_value)