def test_normalize(self): filename_xls_1 = path.join(self.tempdir, 'model-1.xlsx') filename_xls_2 = path.join(self.tempdir, 'model-2.xlsx') model = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.0') Writer().run(filename_xls_1, model, data_repo_metadata=False) # with same destination with __main__.App(argv=['normalize', filename_xls_1]) as app: app.run() model2 = Reader().run(filename_xls_1)[Model][0] self.assertTrue(model2.is_equal(model)) # with different destination with __main__.App( argv=['normalize', filename_xls_1, '--dest', filename_xls_2 ]) as app: app.run() model2 = Reader().run(filename_xls_2)[Model][0] self.assertTrue(model2.is_equal(model))
def test_convert_sloppy(self): filename_xls1 = os.path.join(self.tempdir, 'model1.xlsx') filename_xls2 = os.path.join(self.tempdir, 'model2.xlsx') filename_csv = os.path.join(self.tempdir, 'model-*.csv') Writer().run(filename_xls1, self.model, data_repo_metadata=False) wb = read_workbook(filename_xls1) row = wb['!!Model'].pop(3) wb['!!Model'].insert(4, row) write_workbook(filename_xls1, wb) with self.assertRaisesRegex(ValueError, "The rows of worksheet '!!Model' must be defined in this order"): convert(filename_xls1, filename_csv) env = EnvironmentVarGuard() env.set('CONFIG__DOT__wc_lang__DOT__io__DOT__strict', '0') with env: convert(filename_xls1, filename_csv) self.assertTrue(os.path.isfile(os.path.join(self.tempdir, 'model-Model.csv'))) self.assertTrue(os.path.isfile(os.path.join(self.tempdir, 'model-Taxon.csv'))) model = Reader().run(filename_csv)[Model][0] self.assertTrue(model.is_equal(self.model)) convert(filename_csv, filename_xls2) model = Reader().run(filename_xls2)[Model][0] self.assertTrue(model.is_equal(self.model))
def test_read_write(self): fixture_filename = os.path.join(os.path.dirname(__file__), 'fixtures', 'example-model.xlsx') model = Reader().run(fixture_filename)[Model][0] self.assertEqual(model.validate(), None) # compare excel files Writer().run(self.filename, model, data_repo_metadata=False) original = read_workbook(fixture_filename) copy = read_workbook(self.filename) remove_ws_metadata(original) remove_ws_metadata(copy) original.pop('!!' + obj_tables.core.TOC_SHEET_NAME) copy.pop('!!' + obj_tables.core.TOC_SHEET_NAME) # note that models must be sorted by id for this assertion to hold for sheet in original.keys(): for i_row, (copy_row, original_row) in enumerate(zip(copy[sheet], original[sheet])): self.assertEqual(copy_row, original_row, msg='Rows {} of {} sheets are not equal'.format(i_row, sheet)) self.assertEqual(copy[sheet], original[sheet], msg='{} sheets are not equal'.format(sheet)) self.assertEqual(copy, original) # compare models model2 = Reader().run(self.filename)[Model][0] self.assertTrue(model2.is_equal(model)) self.assertTrue(model.difference(model2) == '')
def test_convert(self): filename_xls1 = os.path.join(self.tempdir, 'model1.xlsx') filename_xls2 = os.path.join(self.tempdir, 'model2.xlsx') filename_csv = os.path.join(self.tempdir, 'model-*.csv') Writer().run(filename_xls1, self.model, data_repo_metadata=False) convert(filename_xls1, filename_csv) self.assertTrue(os.path.isfile(os.path.join(self.tempdir, 'model-Model.csv'))) self.assertTrue(os.path.isfile(os.path.join(self.tempdir, 'model-Taxon.csv'))) model = Reader().run(filename_csv)[Model][0] self.assertTrue(model.is_equal(self.model)) convert(filename_csv, filename_xls2) model = Reader().run(filename_xls2)[Model][0] self.assertTrue(model.is_equal(self.model))
def setUp(self): self.model = model = Model(id='test', version='0.1') c = model.compartments.create(id='comp') c.init_density = model.parameters.create(id='density_compartment_1', value=1100, units=unit_registry.parse_units('g l^-1')) t0 = model.species_types.create(id='s0', type=onto['WC:metabolite']) t1 = model.species_types.create(id='s1', type=onto['WC:metabolite']) t2 = model.species_types.create(id='s2', type=onto['WC:metabolite']) s0 = model.species.create(id='s0[comp]', species_type=t0, compartment=c) s1 = model.species.create(id='s1[comp]', species_type=t1, compartment=c) s2 = model.species.create(id='s2[comp]', species_type=t2, compartment=c) self.submodel = submodel = model.submodels.create(id='submodel', framework=onto['WC:stochastic_simulation_algorithm']) self.r0 = r0 = model.reactions.create(id='r0', reversible=True, submodel=submodel) r0.participants.create(species=s0, coefficient=-2) r0.participants.create(species=s1, coefficient=3) r0_f = r0.rate_laws.create(id='r0-forward', direction=RateLawDirection.forward, model=model) a = model.parameters.create(id='a', value=1., units=unit_registry.parse_units('s^-1')) r0_f.expression, error = RateLawExpression.deserialize('a', {Parameter: {'a': a}}) assert error is None, str(error) r0_b = r0.rate_laws.create(id='r0-backward', direction=RateLawDirection.backward, model=model) b = model.parameters.create(id='b', value=1., units=unit_registry.parse_units('s^-1')) r0_b.expression, error = RateLawExpression.deserialize('b', {Parameter: {'b': b}}) assert error is None, str(error) r0.references.create(id='ref_0', model=model) r0.identifiers.create(namespace='x', id='y') self.r1 = r1 = model.reactions.create(id='r1', reversible=False, submodel=submodel) r1.participants.create(species=s1, coefficient=-3) r1.participants.create(species=s2, coefficient=4) r1_f = r1.rate_laws.create(id='r1-forward', direction=RateLawDirection.forward, model=model) c = model.parameters.create(id='c', value=1., units=unit_registry.parse_units('s^-1')) r1_f.expression, error = RateLawExpression.deserialize('c', {Parameter: {'c': c}}) assert error is None, str(error) r1.references.create(id='ref_1', model=model) r1.identifiers.create(namespace='xx', id='yy') self.tempdir = tempfile.mkdtemp() # check model's integrity by writing and reading with validate=True filename = os.path.join(self.tempdir, 'model_for_tranformation.xlsx') Writer().run(filename, model, data_repo_metadata=False) # turn off validate_element_charge_balance validation so that simple species and reactions validate with EnvironUtils.temp_config_env([(['wc_lang', 'validation', 'validate_element_charge_balance'], 'False')]): model_read = Reader().run(filename, validate=True)[Model][0] self.assertTrue(model_read.is_equal(model))
def test_write_read(self): filename = os.path.join(self.tempdir, 'model.xlsx') Writer().run(filename, self.model, data_repo_metadata=False) model = Reader().run(filename)[Model][0] self.assertEqual(model.validate(), None) self.assertTrue(model.is_equal(self.model)) self.assertEqual(self.model.difference(model), '')
def test(self): test_model = Model(id='model', version='0.0.1', wc_lang_version='0.0.1') submodel = test_model.submodels.create(id='submodel') filename_yaml = os.path.join(self.tempdir, 'model.yaml') Writer().run(filename_yaml, test_model) model = Reader().run(filename_yaml)[Model][0] self.assertEqual(model.validate(), None) self.assertTrue(model.is_equal(test_model)) self.assertEqual(test_model.difference(model), '')
def test_export_import(self): filename = path.join(path.dirname(__file__), 'fixtures', 'sbml-io.xlsx') filename_transformed = path.join(path.dirname(__file__), 'fixtures', 'sbml-io-transformed.xlsx') sbml_dir = self.tempdir filename_2 = path.join(self.tempdir, 'export.xlsx') with __main__.App(argv=['export', filename, sbml_dir]) as app: app.run() with __main__.App(argv=['import', sbml_dir, filename_2]) as app: app.run() model = Reader().run(filename_transformed)[Model][0] model_2 = Reader().run(filename_2)[Model][0] self.assertTrue(model_2.is_equal(model))
def test_write_read_sloppy(self): filename = os.path.join(self.tempdir, 'model.xlsx') Writer().run(filename, self.model, data_repo_metadata=False) wb = read_workbook(filename) row = wb['!!Model'].pop(3) wb['!!Model'].insert(4, row) write_workbook(filename, wb) with self.assertRaisesRegex(ValueError, "The rows of worksheet '!!Model' must be defined in this order"): Reader().run(filename) env = EnvironmentVarGuard() env.set('CONFIG__DOT__wc_lang__DOT__io__DOT__strict', '0') with env: model = Reader().run(filename)[Model][0] self.assertEqual(model.validate(), None) self.assertTrue(model.is_equal(self.model)) self.assertEqual(self.model.difference(model), '')
def do_test_dfba_obj_expr(self, obj_expression, reversible_rxns, expected_obj_expr, dfba_obj_reaction_id='unused'): model, submodel, dfba_rxn = self.prep_dfba_obj_test(obj_expression, reversible_rxns, expected_obj_expr, dfba_obj_reaction_id=dfba_obj_reaction_id) SplitReversibleReactionsTransform().run(model) self.assertEqual(len(model.dfba_objs), 1) self.assertEqual(model.dfba_objs[0], submodel.dfba_obj) # make DfbaObjectiveExpression & DfbaObjective from expected_obj_expr, and compare all_reactions = {Reaction: {rxn.id: rxn for rxn in model.reactions}, DfbaObjReaction: {dfba_obj_reaction_id: dfba_rxn}} expected_dfba_obj_expr, error = DfbaObjectiveExpression.deserialize(expected_obj_expr, all_reactions) self.assertEqual(error, None) transformed_dfba_obj = submodel.dfba_obj submodel.dfba_obj = None dfba_obj = DfbaObjective(id='dfba-obj-submodel', submodel=submodel, expression=expected_dfba_obj_expr) self.assertEqual(dfba_obj.validate(), None) # the list of ObjTablesTokens captures the semantics of a parsed expression self.assertEqual(dfba_obj.expression._parsed_expression._obj_tables_tokens, transformed_dfba_obj.expression._parsed_expression._obj_tables_tokens) # test io model, _, _ = self.prep_dfba_obj_test(obj_expression, reversible_rxns, expected_obj_expr, dfba_obj_reaction_id=dfba_obj_reaction_id) SplitReversibleReactionsTransform().run(model) filename = os.path.join(self.tempdir, 'split_rxn_model.xlsx') Writer().run(filename, model, data_repo_metadata=False) # turn off validate_element_charge_balance validation so that simple species and reactions validate with EnvironUtils.temp_config_env([(['wc_lang', 'validation', 'validate_element_charge_balance'], 'False')]): model_read = Reader().run(filename, validate=True)[Model][0] self.assertTrue(model_read.is_equal(model))
def test_cut_submodels(self): timestamp = datetime.datetime(2018, 1, 1, 12, 0, 0) model = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.1', created=timestamp, updated=timestamp) model.submodels.create(id='submodel_1') model.submodels.create(id='submodel_2') model.references.create(id='ref_0') model.references.create(id='ref_1', submodels=model.submodels[0:1]) model.references.create(id='ref_2', submodels=model.submodels[1:2]) model.references.create(id='ref_3', submodels=model.submodels[0:2]) in_path = path.join(self.tempdir, 'in.xlsx') Writer().run(in_path, model, data_repo_metadata=False) out_path = path.join(self.tempdir, 'out') with __main__.App(argv=['cut-submodels', in_path, out_path]) as app: app.run() model_0 = Reader().run(path.join(out_path, 'core.xlsx'))[Model][0] model_1 = Reader().run(path.join(out_path, 'submodel_1.xlsx'))[Model][0] model_2 = Reader().run(path.join(out_path, 'submodel_2.xlsx'))[Model][0] exp_model_0 = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.1', created=timestamp, updated=timestamp) exp_model_0.references.create(id='ref_0') self.assertTrue(model_0.is_equal(exp_model_0)) exp_model_1 = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.1', created=timestamp, updated=timestamp) exp_model_1.submodels.create(id='submodel_1') exp_model_1.references.create(id='ref_1', submodels=exp_model_1.submodels) exp_model_1.references.create(id='ref_3', submodels=exp_model_1.submodels) self.assertTrue(model_1.is_equal(exp_model_1)) exp_model_2 = Model(id='model', name='test model', version='0.0.1a', wc_lang_version='0.0.1', created=timestamp, updated=timestamp) exp_model_2.submodels.create(id='submodel_2') exp_model_2.references.create(id='ref_2', submodels=exp_model_2.submodels) exp_model_2.references.create(id='ref_3', submodels=exp_model_2.submodels) self.assertTrue(model_2.is_equal(exp_model_2))
def test_make_test_model(self): ''' Simple SSA model tests: no reactions: simulation terminates immediately 1 species: one reaction consume species, at constant rate: consume all reactant, in time given by rate 2 species: one reaction: convert all reactant into product, in time given by rate a pair of symmetrical reactions with constant rates: maintain steady state, on average a pair of symmetrical reactions rates given by reactant population: maintain steady state, on average a pair of symmetrical reactions rates given by product population: exhaust on species, with equal chance for each species ** ring of futile reactions with balanced rates: maintain steady state, on average ''' # test get_model_type_params expected_params_list = [(0, 0, False, RateLawType.constant), (1, 1, False, RateLawType.constant), (2, 1, False, RateLawType.constant), (2, 1, True, RateLawType.constant), (2, 1, True, RateLawType.reactant_pop), (2, 1, True, RateLawType.product_pop)] for model_type, expected_params in zip(self.model_types, expected_params_list): params = MakeModel.get_model_type_params(model_type) self.assertEqual(params, expected_params) # test make_test_model for model_type in self.model_types: for num_submodels in [1, 10]: model = MakeModel.make_test_model( model_type, num_submodels=num_submodels, transform_prep_and_check=False) self.assertEqual(model.validate(), None) # test round-tripping file = model_type.replace(' ', '_').replace(',', '') file = "{}_{}_submodels.xlsx".format(file, num_submodels) filename = os.path.join(self.test_dir, file) Writer().run(filename, model, data_repo_metadata=False) round_trip_model = Reader().run(filename)[Model][0] self.assertEqual(round_trip_model.validate(), None) self.assertTrue(round_trip_model.is_equal(model, tol=1e-8)) self.assertEqual(model.difference(round_trip_model, tol=1e-8), '') # unittest one of the models made # TODO (ARTHUR): test with multiple submodels # TODO (ARTHUR): test observables # TODO (ARTHUR): test functions model = MakeModel.make_test_model(self.model_types[4]) self.assertEqual(model.id, 'test_model') comp = model.compartments[0] self.assertEqual(comp.id, 'compt_1') species_type_ids = set([st.id for st in model.species_types]) self.assertEqual(species_type_ids, set(['spec_type_0', 'spec_type_1'])) species_ids = set([s.id for s in comp.species]) self.assertEqual(species_ids, set(['spec_type_0[compt_1]', 'spec_type_1[compt_1]'])) submodel = model.submodels[0] # reaction was split by SplitReversibleReactionsTransform ratelaw_elements = set() for r in submodel.reactions: self.assertFalse(r.reversible) rl = r.rate_laws[0] ratelaw_elements.add((rl.direction, rl.expression.expression)) expected_rate_laws = set([ # direction, expression.expression (RateLawDirection.forward, 'k_cat_1_1_for * spec_type_0[compt_1] / Avogadro / volume_compt_1' ), # forward (RateLawDirection.forward, 'k_cat_1_1_bck * spec_type_1[compt_1] / Avogadro / volume_compt_1' ), # backward, but reversed ]) self.assertEqual(ratelaw_elements, expected_rate_laws) participant_elements = set() for r in submodel.reactions: r_list = [] for part in r.participants: r_list.append((part.species.id, part.coefficient)) participant_elements.add(tuple(sorted(r_list))) expected_participants = set([ # id, coefficient tuple( sorted((('spec_type_0[compt_1]', -1), ('spec_type_1[compt_1]', 1)))), # forward tuple( sorted((('spec_type_1[compt_1]', -1), ('spec_type_0[compt_1]', 1)))), # reversed ]) self.assertEqual(participant_elements, expected_participants) # test exceptions with self.assertRaises(ValueError): MakeModel.make_test_model('3 reactions') with self.assertRaises(ValueError): MakeModel.make_test_model(self.model_types[0], num_submodels=0)
def test_successful_roundtrip(self): """ Args: species_coefficient_creation_method (:obj:`str`): name of method to use to get or create an instance of :obj:`wc_lang.SpeciesCoefficient` """ model = Model(id='test_model', version='0.0.0') comp = model.compartments.create(id='compartment_1') comp.init_density = model.parameters.create( id='density_compartment_1', value=1100, units=unit_registry.parse_units('g l^-1')) species_type_1 = model.species_types.create( id='species_type_1', structure=ChemicalStructure( empirical_formula=EmpiricalFormula('CHO'), charge=1)) species_type_2 = model.species_types.create( id='species_type_2', structure=ChemicalStructure( empirical_formula=EmpiricalFormula('C3H3O3'), charge=3)) species_1 = comp.species.create(species_type=species_type_1, model=model) species_2 = comp.species.create(species_type=species_type_2, model=model) species_1.id = species_1.gen_id() species_2.id = species_2.gen_id() submdl = model.submodels.create(id='submodel_1') # create a DistributionInitConcentration so that Species are provided to ExpressionAttribute.deserialize() species_1.distribution_init_concentration = DistributionInitConcentration( model=model, mean=1, units=unit_registry.parse_units('M')) species_1.distribution_init_concentration.id = species_1.distribution_init_concentration.gen_id( ) objects = {Species: {}} objects[Species][species_1.id] = species_1 observable_1 = Expression.make_obj(model, Observable, 'observable_1', species_1.id, objects) objects = {Observable: {'observable_1': observable_1}} observable_2 = Expression.make_obj(model, Observable, 'observable_2', 'obs_1', objects) param_1 = model.parameters.create( id='param_1', value=1., units=unit_registry.parse_units('dimensionless')) param_2 = model.parameters.create( id='param_2', value=1., units=unit_registry.parse_units('s^-1')) objects = { Parameter: { 'param_1': param_1, 'param_2': param_2, }, } func_1 = Expression.make_obj(model, Function, 'func_1', 'param_1', objects) func_1.units = unit_registry.parse_units('dimensionless') rxn_species_coeffs = [ species_1.species_coefficients.get_or_create(coefficient=-3.), species_2.species_coefficients.get_or_create(coefficient=1.), ] rxn = submdl.reactions.create(id='reaction_1', model=model) rxn.participants.extend(rxn_species_coeffs) rl = rxn.rate_laws.create(direction=RateLawDirection.forward, units=unit_registry.parse_units('s^-1'), model=model) rl.id = rl.gen_id() rl.expression, error = RateLawExpression.deserialize( 'param_2', objects) self.assertEqual(error, None) errors = obj_tables.Validator().run(model, get_related=True) self.assertEqual(errors, None, str(errors)) filename = os.path.join(self.tmp_dir, 'model.xlsx') Writer().run(filename, model, data_repo_metadata=False) model_2 = Reader().run(filename)[Model][0] self.assertEqual(model.difference(model_2), '') self.assertTrue(model_2.is_equal(model)) self.assertTrue(model.is_equal(model_2))