class TestInitialDynamicComponentsComprehensively(unittest.TestCase): 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 test(self): # test all DynamicComponents that implement eval() ### Test DynamicExpressions ### # each one is tested using each of the objects it uses in some instance in self.model_file # DynamicFunction for id, dynamic_function in self.dynamic_model.dynamic_functions.items( ): expected_value = float(self.model.get_functions(id=id)[0].comments) numpy.testing.assert_approx_equal(dynamic_function.eval(0), expected_value) # test eval_dynamic_functions() for func_id, func_val in self.dynamic_model.eval_dynamic_functions( 0).items(): expected_value = float( self.model.get_functions(id=func_id)[0].comments) numpy.testing.assert_approx_equal(func_val, expected_value) a_func_id = list(self.dynamic_model.dynamic_functions)[0] for func_id, func_val in \ self.dynamic_model.eval_dynamic_functions(0, functions_to_eval=[a_func_id]).items(): expected_value = float( self.model.get_functions(id=func_id)[0].comments) numpy.testing.assert_approx_equal(func_val, expected_value) # DynamicStopCondition for id, dynamic_stop_condition in self.dynamic_model.dynamic_stop_conditions.items( ): expected_val_in_comment = self.model.get_stop_conditions( id=id)[0].comments if expected_val_in_comment == 'True': expected_value = True elif expected_val_in_comment == 'False': expected_value = False self.assertEqual(expected_value, dynamic_stop_condition.eval(0)) # DynamicObservable for id, dynamic_observable in self.dynamic_model.dynamic_observables.items( ): expected_value = float( self.model.get_observables(id=id)[0].comments) numpy.testing.assert_approx_equal(dynamic_observable.eval(0), expected_value) # test eval_dynamic_observables() for obs_id, obs_val in self.dynamic_model.eval_dynamic_observables( 0).items(): expected_value = float( self.model.get_observables(id=obs_id)[0].comments) numpy.testing.assert_approx_equal(obs_val, expected_value) an_obs_id = list(self.dynamic_model.dynamic_observables)[0] for obs_id, obs_val in \ self.dynamic_model.eval_dynamic_observables(0, observables_to_eval=[an_obs_id]).items(): expected_value = float( self.model.get_observables(id=obs_id)[0].comments) numpy.testing.assert_approx_equal(obs_val, expected_value) # DynamicRateLaw for id, dynamic_rate_law in self.dynamic_model.dynamic_rate_laws.items( ): expected_value = float(self.model.get_rate_laws(id=id)[0].comments) numpy.testing.assert_approx_equal(dynamic_rate_law.eval(0), expected_value) ### Test DynamicComponents ### # DynamicCompartment for id, dynamic_compartment in self.dynamic_model.dynamic_compartments.items( ): expected_value = float( self.model.get_compartments(id=id)[0].comments) numpy.testing.assert_approx_equal(dynamic_compartment.eval(0), expected_value) # DynamicParameter for id, dynamic_parameter in self.dynamic_model.dynamic_parameters.items( ): expected_value = float( self.model.get_parameters(id=id)[0].comments) numpy.testing.assert_approx_equal(dynamic_parameter.eval(0), expected_value) # DynamicSpecies for id, dynamic_species in self.dynamic_model.dynamic_species.items(): expected_value = float(self.model.get_species(id=id)[0].comments) numpy.testing.assert_approx_equal(dynamic_species.eval(0), expected_value) # FIX FOR DE-SIM CHANGES: need to make a few dynamic models to test all branches of get_stop_condition() # a dynamic model with no stop concitions # a dynamic model with stop condidtions that all evaluate false # a dynamic model with at least one stop condidtions that evaluates true def test_get_stop_condition(self): all_stop_conditions = self.dynamic_model.get_stop_condition() self.assertTrue(callable(all_stop_conditions)) self.assertTrue(all_stop_conditions(0))
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))
class TestModelUtilities(unittest.TestCase): def get_submodel(self, model, id_val): return model.submodels.get_one(id=id_val) MODEL_FILENAME = os.path.join(os.path.dirname(__file__), 'fixtures', 'test_model.xlsx') def setUp(self): # read a model self.model = Reader().run(self.MODEL_FILENAME, ignore_extra_models=True)[wc_lang.Model][0] def test_find_private_species(self): # since set() operations are being used, this test does not ensure that the methods being # tested are deterministic and repeatable; repeatability should be tested by running the # code under different circumstances and ensuring identical output private_species = ModelUtilities.find_private_species(self.model) submodel_1_exp_species_ids = [ 'species_1[c]', 'species_1[e]', 'species_2[e]' ] mod1_expected_species = wc_lang.Species.get(submodel_1_exp_species_ids, self.model.get_species()) self.assertEqual( set(private_species[self.get_submodel(self.model, 'submodel_1')]), set(mod1_expected_species)) submodel_2_exp_species_ids = [ 'species_5[c]', 'species_4[c]', 'species_6[c]' ] mod2_expected_species = wc_lang.Species.get(submodel_2_exp_species_ids, self.model.get_species()) self.assertEqual( set(private_species[self.get_submodel(self.model, 'submodel_2')]), set(mod2_expected_species)) private_species = ModelUtilities.find_private_species(self.model, return_ids=True) self.assertEqual(set(private_species['submodel_1']), set(submodel_1_exp_species_ids)) self.assertEqual(set(private_species['submodel_2']), set(submodel_2_exp_species_ids)) def test_find_shared_species(self): self.assertEqual( set(ModelUtilities.find_shared_species(self.model)), set( wc_lang.Species.get( ['species_2[c]', 'species_3[c]', 'H2O[e]', 'H2O[c]'], self.model.get_species()))) self.assertEqual( set(ModelUtilities.find_shared_species(self.model, return_ids=True)), set(['species_2[c]', 'species_3[c]', 'H2O[e]', 'H2O[c]'])) def test_sample_copy_num_from_concentration(self): model = wc_lang.Model() submodel = model.submodels.create( id='submodel', framework=onto['WC:stochastic_simulation_algorithm']) compartment_c = model.compartments.create( id='c', init_volume=wc_lang.InitVolume(mean=1.)) structure = wc_lang.ChemicalStructure(molecular_weight=10.) species_types = {} cus_species_types = {} for cu in wc_lang.DistributionInitConcentration.units.choices: id = str(cu).replace(' ', '_') species_types[id] = model.species_types.create(id=id, structure=structure) cus_species_types[id] = cu for other in ['no_units', 'no_concentration', 'no_std']: species_types[other] = model.species_types.create( id=other, structure=structure) species = {} for key, species_type in species_types.items(): species[key] = wc_lang.Species(species_type=species_type, compartment=compartment_c) species[key].id = species[key].gen_id() conc_value = 2_000. std_value = 0. for key, sp in species.items(): if key in cus_species_types: wc_lang.DistributionInitConcentration( species=sp, mean=conc_value, std=std_value, units=cus_species_types[key]) elif key == 'no_units': wc_lang.DistributionInitConcentration(species=sp, mean=conc_value, std=std_value) elif key == 'no_std': wc_lang.DistributionInitConcentration( species=sp, mean=conc_value, std=float('NaN'), units=cus_species_types['molecule']) elif key == 'no_concentration': continue conc_to_molecules = ModelUtilities.sample_copy_num_from_concentration random_state = numpy.random.RandomState() copy_number = conc_to_molecules( species['molecule'], species['molecule'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, conc_value) copy_number = conc_to_molecules( species['molar'], species['molar'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, conc_value * Avogadro) copy_number = conc_to_molecules( species['no_units'], species['no_units'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, conc_value * Avogadro) copy_number = conc_to_molecules( species['millimolar'], species['millimolar'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, 10**-3 * conc_value * Avogadro) copy_number = conc_to_molecules( species['micromolar'], species['micromolar'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, 10**-6 * conc_value * Avogadro) copy_number = conc_to_molecules( species['nanomolar'], species['nanomolar'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, 10**-9 * conc_value * Avogadro) copy_number = conc_to_molecules( species['picomolar'], species['picomolar'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, 10**-12 * conc_value * Avogadro) copy_number = conc_to_molecules( species['femtomolar'], species['femtomolar'].compartment.init_volume.mean, random_state) self.assertAlmostEqual(copy_number, 10**-15 * conc_value * Avogadro, delta=1) copy_number = conc_to_molecules( species['attomolar'], species['attomolar'].compartment.init_volume.mean, random_state) self.assertAlmostEqual(copy_number, 10**-18 * conc_value * Avogadro, delta=1) copy_number = conc_to_molecules( species['no_concentration'], species['no_concentration'].compartment.init_volume.mean, random_state) self.assertEqual(copy_number, 0) conc = species['no_std'].distribution_init_concentration copy_number = conc_to_molecules( species['no_std'], species['no_std'].compartment.init_volume.mean, random_state) self.assertNotEqual(copy_number, conc_value) with self.assertRaises(KeyError): conc_to_molecules( species['mol dm^-2'], species['no_concentration'].compartment.init_volume.mean, random_state) species_tmp = wc_lang.Species(species_type=species_type, compartment=compartment_c) species_tmp.id = species_tmp.gen_id() wc_lang.DistributionInitConcentration( species=species_tmp, mean=conc_value, std=std_value, units='not type(unit_registry.Unit)') with self.assertRaisesRegex(ValueError, 'Unsupported unit type'): conc_to_molecules(species_tmp, species_tmp.compartment.init_volume.mean, random_state) species_tmp2 = wc_lang.Species(species_type=species_type, compartment=compartment_c) species_tmp2.id = species_tmp2.gen_id() wc_lang.DistributionInitConcentration( species=species_tmp2, mean=conc_value, std=std_value, units=wc_lang.InitVolume.units.choices[0]) with self.assertRaisesRegex(ValueError, 'Unsupported unit'): conc_to_molecules(species_tmp2, species_tmp2.compartment.init_volume.mean, random_state) def test_get_species_types(self): self.assertEqual(ModelUtilities.get_species_types([]), []) species_type_ids = [ species_type.id for species_type in self.model.get_species_types() ] species_ids = [ species.serialize() for species in self.model.get_species() ] self.assertEqual(sorted(ModelUtilities.get_species_types(species_ids)), sorted(species_type_ids)) def test_get_species_types(self): self.assertEqual( ModelUtilities.parse_species_id('species_type_id[compartment_id]'), ('species_type_id', 'compartment_id')) with self.assertRaisesRegex(ValueError, 'Species id format should be'): ModelUtilities.parse_species_id('compartment_id]') with self.assertRaisesRegex(ValueError, 'Species id format should be'): ModelUtilities.parse_species_id('[compartment_id]') with self.assertRaisesRegex(ValueError, 'Species id format should be'): ModelUtilities.parse_species_id('species_type_id[]') with self.assertRaisesRegex(ValueError, 'Species id format should be'): ModelUtilities.parse_species_id( 'species_type_id[compartment_id]extra')