def test_one_reaction_constant_species_pop(self): # test statics init_volume = 1E-16 init_density = 1000 molecular_weight = 100. default_species_copy_number = 10_000 init_accounted_mass = molecular_weight * default_species_copy_number / Avogadro init_accounted_density = init_accounted_mass / init_volume expected_initial_values_compt_1 = dict(init_volume=init_volume, init_accounted_mass=init_accounted_mass, init_mass= init_volume * init_density, init_density=init_density, init_accounted_density=init_accounted_density, accounted_fraction = init_accounted_density / init_density) expected_initial_values = {'compt_1': expected_initial_values_compt_1} model = MakeModel.make_test_model('1 species, 1 reaction', init_vols=[expected_initial_values_compt_1['init_volume']], init_vol_stds=[0], density=init_density, molecular_weight=molecular_weight, default_species_copy_number=default_species_copy_number, default_species_std=0) multialgorithm_simulation = MultialgorithmSimulation(model, self.wc_sim_config) _, dynamic_model = multialgorithm_simulation.build_simulation() check_simul_results(self, dynamic_model, None, expected_initial_values=expected_initial_values)
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 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 make_model_and_simulation(self, model_type, num_submodels, species_copy_numbers=None, species_stds=None, init_vols=None, submodel_framework='WC:stochastic_simulation_algorithm'): # make simple model if init_vols is not None: if not isinstance(init_vols, list): init_vols = [init_vols]*num_submodels model = MakeModel.make_test_model(model_type, num_submodels=num_submodels, species_copy_numbers=species_copy_numbers, species_stds=species_stds, init_vols=init_vols, submodel_framework=submodel_framework) multialgorithm_simulation = MultialgorithmSimulation(model, self.wc_sim_config) simulation_engine, _ = multialgorithm_simulation.build_simulation() return (model, multialgorithm_simulation, simulation_engine)
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_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_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])
def test_prepare_skipped_submodels(self): multialgorithm_simulation = MultialgorithmSimulation(self.model, self.wc_sim_config) self.assertEqual(multialgorithm_simulation.skipped_submodels(), set()) submodels_to_skip = ['submodel_1'] self.wc_sim_config.submodels_to_skip = submodels_to_skip multialgorithm_simulation = MultialgorithmSimulation(self.model, self.wc_sim_config) self.assertEqual(multialgorithm_simulation.skipped_submodels(), set(submodels_to_skip)) submodels_to_skip = ['no_such_submodel'] self.wc_sim_config.submodels_to_skip = submodels_to_skip with self.assertRaisesRegex(MultialgorithmError, "'submodels_to_skip' contains submodels that aren't in the model:"): MultialgorithmSimulation(self.model, self.wc_sim_config)
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 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_check_simul_results(self): init_volume = 1E-16 init_density = 1000 molecular_weight = 100. default_species_copy_number = 10_000 init_accounted_mass = molecular_weight * default_species_copy_number / Avogadro init_accounted_density = init_accounted_mass / init_volume expected_initial_values_compt_1 = dict( init_volume=init_volume, init_accounted_mass=init_accounted_mass, init_mass=init_volume * init_density, init_density=init_density, init_accounted_density=init_accounted_density, accounted_fraction=init_accounted_density / init_density) expected_initial_values = {'compt_1': expected_initial_values_compt_1} model = MakeModel.make_test_model( '1 species, 1 reaction', init_vols=[expected_initial_values_compt_1['init_volume']], init_vol_stds=[0], density=init_density, molecular_weight=molecular_weight, default_species_copy_number=default_species_copy_number, default_species_std=0, submodel_framework='WC:deterministic_simulation_algorithm') multialgorithm_simulation = MultialgorithmSimulation( model, self.wc_sim_config) _, dynamic_model = multialgorithm_simulation.build_simulation() check_simul_results(self, dynamic_model, None, expected_initial_values=expected_initial_values) # test dynamics simulation = Simulation(model) _, results_dir = simulation.run(time_max=2, **self.args) nan = float('NaN') check_simul_results(self, dynamic_model, results_dir, expected_initial_values=expected_initial_values, expected_species_trajectories=\ {'spec_type_0[compt_1]':[10000., 9999., 9998.]}) check_simul_results(self, dynamic_model, results_dir, expected_initial_values=expected_initial_values, expected_species_trajectories=\ {'spec_type_0[compt_1]':[nan, nan, nan]}) with self.assertRaises(AssertionError): check_simul_results(self, dynamic_model, results_dir, expected_initial_values=expected_initial_values, expected_species_trajectories=\ {'spec_type_0[compt_1]':[10000., 10000., 9998.]}) with self.assertRaises(AssertionError): check_simul_results(self, dynamic_model, results_dir, expected_initial_values=expected_initial_values, expected_species_trajectories=\ {'spec_type_0[compt_1]':[10000., 10000.]}) check_simul_results(self, dynamic_model, results_dir, expected_initial_values=expected_initial_values, expected_species_trajectories=\ {'spec_type_0[compt_1]':[10000., 9999., 9998.]}, rel_tol=1E-5) check_simul_results(self, dynamic_model, results_dir, expected_property_trajectories={ 'compt_1': { 'mass': [1.000e-13, 9.999e-14, 9.998e-14] } }) check_simul_results(self, dynamic_model, results_dir, expected_property_trajectories={ 'compt_1': { 'mass': [nan, nan, nan] } }) with self.assertRaises(AssertionError): check_simul_results(self, dynamic_model, results_dir, expected_property_trajectories={ 'compt_1': { 'mass': [1.000e-13, 1.000e-13, 9.999e-14] } }, rel_tol=0) plots_dir = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', 'tests', 'results')) os.makedirs(plots_dir, exist_ok=True) plot_expected_vs_simulated(dynamic_model, 'ordinary_differential_equations', results_dir, trajectory_times=[0, 1, 2], plots_dir=plots_dir, expected_species_trajectories=\ {'spec_type_0[compt_1]':[10000., 10000., 9998.]}, expected_property_trajectories=\ {'compt_1': {'mass':[1.000e-13, 1.000e-13, 9.999e-14]}}) plot_expected_vs_simulated(dynamic_model, 'ordinary_differential_equations', results_dir, trajectory_times=[0, 1, 2], plots_dir=plots_dir, expected_property_trajectories=\ {'compt_1': {'mass':[1.000e-13, 1.000e-13, 9.999e-14]}}) plot_expected_vs_simulated(dynamic_model, 'ordinary_differential_equations', results_dir, trajectory_times=[0, 1, 2], plots_dir=plots_dir, expected_species_trajectories=\ {'spec_type_0[compt_1]':[10000., 10000., 9998.]}) plot_expected_vs_simulated(dynamic_model, 'ordinary_differential_equations', results_dir, trajectory_times=[0, 1, 2], plots_dir=plots_dir, expected_species_trajectories=\ {'spec_type_0[compt_1]':[nan, nan, nan]}, expected_property_trajectories=\ {'compt_1': {'mass':[nan, nan, nan]}})
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)
class TestMultialgorithmSimulationStatically(unittest.TestCase): MODEL_FILENAME = os.path.join(os.path.dirname(__file__), 'fixtures', 'test_model.xlsx') 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 tearDown(self): shutil.rmtree(self.test_dir) def test_init(self): self.model.submodels = [] with self.assertRaises(MultialgorithmError): MultialgorithmSimulation(self.model, self.wc_sim_config) def test_prepare_skipped_submodels(self): multialgorithm_simulation = MultialgorithmSimulation(self.model, self.wc_sim_config) self.assertEqual(multialgorithm_simulation.skipped_submodels(), set()) submodels_to_skip = ['submodel_1'] self.wc_sim_config.submodels_to_skip = submodels_to_skip multialgorithm_simulation = MultialgorithmSimulation(self.model, self.wc_sim_config) self.assertEqual(multialgorithm_simulation.skipped_submodels(), set(submodels_to_skip)) submodels_to_skip = ['no_such_submodel'] self.wc_sim_config.submodels_to_skip = submodels_to_skip with self.assertRaisesRegex(MultialgorithmError, "'submodels_to_skip' contains submodels that aren't in the model:"): MultialgorithmSimulation(self.model, self.wc_sim_config) def test_molecular_weights_for_species(self): multi_alg_sim = self.multialgorithm_simulation expected = { 'species_6[c]': float('nan'), 'H2O[c]': 18.0152 } actual = multi_alg_sim.molecular_weights_for_species(set(expected.keys())) self.assertEqual(actual['H2O[c]'], expected['H2O[c]']) self.assertTrue(np.isnan(actual['species_6[c]'])) # add a species_type without a structure species_type_wo_structure = self.model.species_types.create( id='st_wo_structure', name='st_wo_structure') cellular_compartment = self.model.compartments.get(**{'id': 'c'})[0] species_wo_structure = self.model.species.create( species_type=species_type_wo_structure, compartment=cellular_compartment) species_wo_structure.id = species_wo_structure.gen_id() actual = multi_alg_sim.molecular_weights_for_species([species_wo_structure.id]) self.assertTrue(np.isnan(actual[species_wo_structure.id])) # test obtain weights for all species actual = multi_alg_sim.molecular_weights_for_species() self.assertEqual(actual['H2O[c]'], expected['H2O[c]']) self.assertTrue(np.isnan(actual['species_6[c]'])) self.assertEqual(len(actual), len(self.model.get_species())) def test_create_dynamic_compartments(self): self.multialgorithm_simulation.create_dynamic_compartments() self.assertEqual(set(['c', 'e']), set(self.multialgorithm_simulation.temp_dynamic_compartments)) for id, dynamic_compartment in self.multialgorithm_simulation.temp_dynamic_compartments.items(): self.assertEqual(id, dynamic_compartment.id) self.assertTrue(0 < dynamic_compartment.init_density) def test_prepare_dynamic_compartments(self): self.multialgorithm_simulation.create_dynamic_compartments() self.multialgorithm_simulation.init_species_pop_from_distribution() self.multialgorithm_simulation.local_species_population = \ self.multialgorithm_simulation.make_local_species_population(retain_history=False) self.multialgorithm_simulation.prepare_dynamic_compartments() for dynamic_compartment in self.multialgorithm_simulation.temp_dynamic_compartments.values(): self.assertTrue(dynamic_compartment._initialized()) self.assertTrue(0 < dynamic_compartment.accounted_mass()) self.assertTrue(0 < dynamic_compartment.mass()) def test_init_species_pop_from_distribution(self): self.multialgorithm_simulation.create_dynamic_compartments() self.multialgorithm_simulation.init_species_pop_from_distribution() species_wo_init_conc = ['species_1[c]', 'species_3[c]'] for species_id in species_wo_init_conc: self.assertEqual(self.multialgorithm_simulation.init_populations[species_id], 0) for concentration in self.model.get_distribution_init_concentrations(): self.assertTrue(0 <= self.multialgorithm_simulation.init_populations[concentration.species.id]) # todo: statistically evaluate sampled population # ensure that over multiple runs of init_species_pop_from_distribution(): # mean(species population) ~= mean(volume) * mean(concentration) def test_make_local_species_population(self): self.multialgorithm_simulation.create_dynamic_compartments() self.multialgorithm_simulation.init_species_pop_from_distribution() local_species_population = self.multialgorithm_simulation.make_local_species_population() self.assertEqual(local_species_population._molecular_weights, self.multialgorithm_simulation.molecular_weights_for_species()) # test the initial population slopes # continuous adjustments are only allowed on species used by continuous submodels used_by_continuous_submodels = \ ['species_1[e]', 'species_2[e]', 'species_1[c]', 'species_2[c]', 'species_3[c]'] adjustments = {species_id: 0. for species_id in used_by_continuous_submodels} self.assertEqual(local_species_population.adjust_continuously(1, adjustments), None) not_in_a_reaction = ['H2O[e]', 'H2O[c]'] used_by_discrete_submodels = ['species_4[c]', 'species_5[c]', 'species_6[c]'] adjustments = {species_id: 0. for species_id in used_by_discrete_submodels + not_in_a_reaction} with self.assertRaises(DynamicSpeciesPopulationError): local_species_population.adjust_continuously(2, adjustments) def test_set_simultaneous_execution_priorities(self): expected_order_of_sim_obj_classes = [SsaSubmodel, NrmSubmodel, DsaSubmodel, DfbaSubmodel, OdeSubmodel, MultialgorithmicCheckpointingSimObj] self.multialgorithm_simulation.set_simultaneous_execution_priorities() # ensure that expected_order_of_sim_obj_classes are arranged in decreasing priority for i in range(len(expected_order_of_sim_obj_classes) - 1): simulation_object_class = expected_order_of_sim_obj_classes[i] next_simulation_object_class = expected_order_of_sim_obj_classes[i+1] self.assertLess(simulation_object_class.metadata.class_priority, next_simulation_object_class.metadata.class_priority) def test_initialize_components(self): self.multialgorithm_simulation.initialize_components() self.assertTrue(isinstance(self.multialgorithm_simulation.local_species_population, LocalSpeciesPopulation)) for dynamic_compartment in self.multialgorithm_simulation.temp_dynamic_compartments.values(): self.assertTrue(isinstance(dynamic_compartment.species_population, LocalSpeciesPopulation)) 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 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_get_dynamic_compartments(self): expected_compartments = dict( submodel_1=['c', 'e'], submodel_2=['c'] ) self.multialgorithm_simulation.build_simulation() for submodel_id in ['submodel_1', 'submodel_2']: submodel = self.model.submodels.get_one(id=submodel_id) submodel_dynamic_compartments = self.multialgorithm_simulation.get_dynamic_compartments(submodel) self.assertEqual(set(submodel_dynamic_compartments.keys()), set(expected_compartments[submodel_id])) def test_str(self): self.multialgorithm_simulation.create_dynamic_compartments() self.multialgorithm_simulation.init_species_pop_from_distribution() self.multialgorithm_simulation.local_species_population = \ self.multialgorithm_simulation.make_local_species_population(retain_history=False) self.assertIn('species_1[e]', str(self.multialgorithm_simulation)) self.assertIn('model:', str(self.multialgorithm_simulation))
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)
def test_init(self): self.model.submodels = [] with self.assertRaises(MultialgorithmError): MultialgorithmSimulation(self.model, self.wc_sim_config)
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)