def test_design_removals(): with FakeProjectContext() as ctx: # Design with removal of reactions, metabolites, genes project = GSMProject(ctx.path) mdl = project.load_model() rx = mdl.reactions.get_by_id('TPI') rx.remove_from_model() gx = mdl.genes.get_by_id("b3916") gx.name = 'ffoods' mx = mdl.metabolites.get_by_id('h2o_c') mx.remove_from_model() des = project.save_design(mdl, 'test', 'test', description='test', overwrite=True) des._genes.append( dict(id='ffooo', name='', functional=True, notes=None, annotation={})) des._removed_metabolites.append('ttttesssst') tp = des.load() assert rx.id not in tp.reactions assert mx.id not in tp.metabolites
def test_json_tests(): """ Test the execution of json tests""" with FakeProjectContext() as fp: # Create a fake json file with tests in it jtest = dict( test_1=dict(models=[], conditions=[], designs=[], reaction_fluxes=dict( BIOMASS_Ec_iAF1260_core_59p81M=[0.72, 0.74]), required_reactions=["DHQS"], description='TEST JSON TEST')) project = GSMProject(fp.path) tpath = os.path.join(project.tests_dir, 'test_x.json') # write to project path with open(tpath, "w+") as ff: json.dump(jtest, ff) jtest = dict( test_1=dict(conditions=[], designs=[], reaction_fluxes=dict( BIOMASS_Ec_iAF1260_core_59p81M=[0.72, 0.74]), required_reactions=["DHQS"], description='TEST JSON TEST')) project = GSMProject(fp.path) tpath = os.path.join(project.tests_dir, 'test_invalid.json') # write to project path with open(tpath, "w+") as ff: json.dump(jtest, ff) tpath = os.path.join(project.tests_dir, 'test_load_error.json') with open(tpath, 'w+') as tt: tt.write('not json\n') # run test functions tester = project.project_tester() tester.collect_tests() assert len(tester.json_tests) == 1 tester.run_all() assert len(tester.load_errors) == 1 assert len(tester.invalid_tests) == 1 runner = CliRunner() result = runner.invoke(gsmodutils.cli.test, ['--project_path', fp.path, '--verbose']) assert result.exit_code == 0 result = runner.invoke(gsmodutils.cli.test, [ '--project_path', fp.path, '--verbose', '--test_id', 'test_x.json' ]) assert result.exit_code == 0
def test_save_design(): with FakeProjectContext() as ctx: ctx.add_fake_conditions() ctx.add_fake_designs() project = GSMProject(ctx.path) design = project.get_design("mevalonate_cbb") mdl = GSModutilsModel(project, design=design) mdl.save_model() # Can't save py designs that have been modified with pytest.raises(NotImplementedError): design = project.get_design("fake_testpy") mdl = GSModutilsModel(project, design=design) mdl.save_model()
def test_project_update(): with FakeProjectContext() as ctx: project = GSMProject(ctx.path) assert len(project.models) project.update() with pytest.raises(ProjectNotFound): project._project_path = 'NOT_REAL_PATH' project.update() # Test non existent designs with pytest.raises(DesignNotFoundError): project.get_design("fooooo")
def test_create_project(): runner = CliRunner() with CleanUpDir() as ctx: name = 'Test model' description = 'test desc' author = 'test author' email = '*****@*****.**' inpt = '{}\n{}\n{}\n{}\n'.format(name, description, author, email) result = runner.invoke(gsmodutils.cli.init, [ctx.path, _CORE_MODEL_PATH], input=inpt) assert result.exit_code == 0 # shouldn't raise an exception project = GSMProject(ctx.path) assert project.config.name == name assert project.config.description == description assert project.config.author == author assert project.config.author_email == email assert 'e_coli_core.json' in project.config.models # attempting rerun will raise exception result = runner.invoke(gsmodutils.cli.init, [ctx.path, _CORE_MODEL_PATH], input=inpt) assert result.exit_code == -1
def _load_project(project_path): project = None try: project = GSMProject(project_path) except ProjectNotFound: click.echo('Error project not found in path'.format(project_path)) exit(-1) return project
def __enter__(self): """ Create a temporary gsmodutils project folder """ add_models = [self.model] if self.second_model is not None: add_models += [self.second_model] self.project = GSMProject.create_project(add_models, 'TEST PROJECT ONLY', 'test', '*****@*****.**', self.path) return self
def test_import_conditions(): with FakeProjectContext() as ctx: runner = CliRunner() project = GSMProject(ctx.path) model = project.load_model() model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 save_path = os.path.join(ctx.path, 'tp.json') cobra.io.save_json_model(model, save_path) cid = 'xylose_growth' result = runner.invoke(gsmodutils.cli.iconditions, [save_path, cid, '--project_path', ctx.path]) assert result.exit_code == 0 # Check we can actually load these conditions mdl = project.load_conditions(cid) assert mdl.reactions.EX_xyl__D_e.lower_bound == -8.0 assert mdl.reactions.EX_glc__D_e.lower_bound == 0.0
def test_addmodel(): with FakeProjectContext() as ctx: runner = CliRunner() result = runner.invoke(gsmodutils.cli.addmodel, [_CORE_MODEL_PATH, '--project_path', ctx.path]) assert result.exit_code == 0 project = GSMProject(ctx.path) assert "e_coli_core.json" in project.config.models # Should fail when model already exists result = runner.invoke(gsmodutils.cli.addmodel, [_CORE_MODEL_PATH, '--project_path', ctx.path]) assert result.exit_code == -1
def test_copy(): with FakeProjectContext() as ctx: project = GSMProject(ctx.path) assert project.project_path == ctx.path model = GSModutilsModel(project) copied = model.copy() assert model is not copied for met in copied.metabolites: assert met is not model.metabolites.get_by_id(met.id) assert met.model is not model for gene in copied.genes: assert gene is not model.genes.get_by_id(gene.id) assert gene.model is not model
def test_create_project(): """ Create a test project with an example e coli model """ # When writing tests use a different folder for multiprocess! with FakeProjectContext() as ctx: # Make sure all files exist assert os.path.exists(ctx.path) assert os.path.exists(os.path.join(ctx.path, default_project_file)) assert os.path.exists( os.path.join(ctx.path, default_model_conditionsfp)) # check project loads GSMProject(ctx.path)
def test_docker(): with FakeProjectContext() as ctx: # Add some conditions and a design with a parent project = GSMProject(ctx.path) model = project.load_model() model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 project.save_conditions(model, 'xylose_growth') nr = model.reactions.EX_glc__D_e.copy() model.remove_reactions(["EX_glc__D_e"]) project.save_design(model, 'tt1', 'tt1') model.add_reactions([nr]) project.save_design(model, 'tt2', 'tt2', parent='tt1') runner = CliRunner() result = runner.invoke(gsmodutils.cli.docker, ['--project_path', ctx.path]) assert result.exit_code == 0 result = runner.invoke(gsmodutils.cli.docker, ['--project_path', ctx.path, '--overwrite']) assert result.exit_code == 0
def test_load_scrumpy(): with FakeProjectContext() as ctx: project = GSMProject(ctx.path) assert project.project_path == ctx.path model = GSModutilsModel(project) scrumpy_string = """ External(PROTON_i, "WATER") NADH_DH_ubi: "NADH" + "UBIQUINONE-8" + 4 PROTON_i -> "UBIQUINOL-8" + 3 PROTON_p + "NAD" ~ NADH_DH_meno: "NADH" + "Menaquinones" + 4 PROTON_i -> "Menaquinols" + 3 PROTON_p + "NAD" ~ Cytochrome_c_oxidase: 1/2 "OXYGEN-MOLECULE" + "UBIQUINOL-8" + 2 PROTON_i -> "UBIQUINONE-8" + "WATER" + 2 PROTON_p ~ ATPSynth: "ADP" + "Pi" + 4 PROTON_p -> "ATP" + "WATER" + 3 PROTON_i ~ ATPase: "ATP" -> "ADP" + "Pi" + x_ATPWork ~ """ model.add_scrumpy_reactions(scrumpy_string) assert "NADH_DH_ubi" in model.reactions assert "NADH_DH_meno" in model.reactions assert "Cytochrome_c_oxidase" in model.reactions assert "ATPSynth" in model.reactions assert "ATPase" in model.reactions
def test_load_model(): """ Most of this is for code coverage :return: """ with FakeProjectContext() as ctx: ctx.add_fake_conditions() ctx.add_fake_designs() project = GSMProject(ctx.path) assert project.project_path == ctx.path model = GSModutilsModel(project) assert isinstance(model, cobra.Model) model.load_conditions("xyl_src") model.diff() model.diff(model) with pytest.raises(TypeError): model.diff("should break") # Test loading non design fails with pytest.raises(TypeError): GSModutilsModel(project, design={}) with pytest.raises(TypeError): GSModutilsModel({}) with pytest.raises(IOError): GSModutilsModel(project, mpath="/this/is/a/fake/path") model.save_model() cpy = model.to_cobra_model() assert not isinstance(cpy, GSModutilsModel)
def test_old_conditions(): """ Test to see if old conditions (without setting objective function) breaks :return: """ with FakeProjectContext() as ctx: project = GSMProject(ctx.path) model = project.model model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 project.save_conditions(model, 'xylose_growth', carbon_source="EX_xyl__D_e") with open(os.path.join(ctx.path, "model_conditions.json")) as cond_path: ddict = json.load(cond_path) del ddict["growth_conditions"]["xylose_growth"]["objective_reactions"] with open(os.path.join(ctx.path, "model_conditions.json"), "w") as cond_path: json.dump(ddict, cond_path) too_model = project.load_conditions('xylose_growth', model=model, copy=True) model.reactions.EX_xyl__D_e.lower_bound = 0.00 assert model.reactions.EX_xyl__D_e.lower_bound != too_model.reactions.EX_xyl__D_e.lower_bound # Test bad objective handling ddict["growth_conditions"]["xylose_growth"]["objective_reactions"] = [ "NOT_REAL" ] with open(os.path.join(ctx.path, "model_conditions.json"), "w") as cond_path: json.dump(ddict, cond_path) too_model = project.load_conditions('xylose_growth', model=model, copy=True) assert too_model.reactions.BIOMASS_Ec_iAF1260_core_59p81M.objective_coefficient
def project_creator(path, add_models): GSMProject.create_project(add_models, 'TEST PROJECT ONLY', 'test', '*****@*****.**', path)
def test_export(fmt, excode): with FakeProjectContext() as ctx: runner = CliRunner() opt = '{}/testmdl.{}'.format(ctx.path, fmt) with CleanUpFile(opt): result = runner.invoke(gsmodutils.cli.export, [fmt, opt, '--project_path', ctx.path]) assert result.exit_code == excode if excode == 0: # Should create the file as well as returning saying it has! assert os.path.exists(opt) # Model should load again without exceptions load_model(opt) # Should not allow overwriting/removing without flag result = runner.invoke(gsmodutils.cli.export, [fmt, opt, '--project_path', ctx.path]) assert result.exit_code == -1 assert os.path.exists(opt) os.remove(opt) # Test export of designs and conditions project = GSMProject(ctx.path) model = project.load_model() model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 project.save_conditions(model, 'xylose_growth') model.remove_reactions(["EX_glc__D_e"]) project.save_design(model, 'tt1', 'tt1') result = runner.invoke( gsmodutils.cli.export, [fmt, opt, '--project_path', ctx.path, '--design', 'tt1']) assert result.exit_code == 0 assert os.path.exists(opt) # test that design works correctly # more covered by tests for StrainDesign class, this just checks it is actually exporting a design l_model = load_model(opt) assert "EX_glc__D_e" not in l_model.reactions os.remove(opt) assert not os.path.exists(opt) # The same applies for exporting conditions result = runner.invoke(gsmodutils.cli.export, [ fmt, opt, '--project_path', ctx.path, '--conditions', 'xylose_growth' ]) assert result.exit_code == 0 assert os.path.exists(opt) l_model = load_model(opt) assert l_model.reactions.EX_xyl__D_e.lower_bound == -8.00 assert l_model.reactions.EX_glc__D_e.lower_bound == 0.0
def test_diff(): with FakeProjectContext() as ctx: runner = CliRunner() project = GSMProject(ctx.path) mdl = project.load_model() rubisco = cobra.Reaction(id="RBPC", lower_bound=0, upper_bound=1000.0, name="Ribulose-bisphosphate carboxylase") mdl.add_reactions([rubisco]) rb15bp = cobra.Metabolite(id='rb15bp_c', name='D-Ribulose 1,5-bisphosphate', formula='C5H8O11P2', charge=0) mdl.add_metabolites(rb15bp) stoich = { "3pg_c": 2.0, "rb15bp_c": -1.0, "co2_c": -1.0, "h2o_c": -1.0, "h_c": 2.0 } rubisco.add_metabolites(stoich) # Remove a metabolite and reaction mdl.metabolites.h2o_c.remove_from_model() mdl.reactions.TRE6PH.remove_from_model() mdl.reactions.EX_glc__D_e.lower_bound = -1000 save_path = os.path.join(ctx.path, 'tp.json') cobra.io.save_json_model(mdl, save_path) output_path = os.path.join(ctx.path, 'differ.json') result = runner.invoke(gsmodutils.cli.diff, [ save_path, '--project_path', ctx.path, '--output', output_path, '--names', '--base_model', 'iAF1260.json' ]) assert result.exit_code == 0 assert os.path.exists(output_path) with open(output_path) as dff_file: diff = json.load(dff_file) dmdl = project.load_diff(diff) assert 'RBPC' in dmdl.reactions assert 'rb15bp_c' in dmdl.metabolites # add a design from a diff did = 'test' name = 'ftt' description = 'tt' opts = [ output_path, did, '--project_path', ctx.path, '--from_diff', '--name', name, '--description', description, ] result = runner.invoke(gsmodutils.cli.dimport, opts) assert result.exit_code == 0 assert did in project.list_designs result = runner.invoke(gsmodutils.cli.diff, [ save_path, '--project_path', ctx.path, '--output', output_path, '--names', '--base_model', 'iAF1260.json', '--parent', did ]) assert result.exit_code == 0
def test_load_conditions(): with FakeProjectContext() as ctx: project = GSMProject(ctx.path) model = project.model # Growth on xylose instead of glucose model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 model.reactions.EX_h_e.objective_coefficient = 1.0 project.save_conditions(model, 'xylose_growth', carbon_source="EX_xyl__D_e") # The model should be reloaded so it isn't the same reference del model new_model = project.load_conditions('xylose_growth') assert new_model.reactions.EX_xyl__D_e.lower_bound == -8.00 assert new_model.reactions.EX_xyl__D_e.upper_bound == -8.00 assert new_model.reactions.EX_glc__D_e.lower_bound == 0.0 # Test model objective assert new_model.reactions.EX_h_e.objective_coefficient == 1.0 assert new_model.reactions.BIOMASS_Ec_iAF1260_core_59p81M.objective_coefficient == 1.0 del new_model model = project.model # test using a copy of the model too_model = project.load_conditions('xylose_growth', model=model, copy=True) model.reactions.EX_xyl__D_e.lower_bound = 0.00 assert model.reactions.EX_xyl__D_e.lower_bound != too_model.reactions.EX_xyl__D_e.lower_bound # Model growth when it shouldn't with pytest.raises(AssertionError): project.save_conditions(too_model, 'xylose_growth2', carbon_source="EX_xyl__D_e", observe_growth=False) # Bad "apply_to" model with pytest.raises(KeyError): project.save_conditions(too_model, 'xylose_growth3', carbon_source="EX_xyl__D_e", apply_to=["FOO"]) # Bad growth target with pytest.raises(KeyError): project.save_conditions(too_model, 'xylose_growth3', carbon_source="EX_foo")
def test_import_designs(): with FakeProjectContext() as ctx: runner = CliRunner() name = 'test m' description = 'test desc' project = GSMProject(ctx.path) model = project.load_model() model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.remove_reactions(["EX_glc__D_e"]) save_path = os.path.join(ctx.path, 'tp.json') cobra.io.save_json_model(model, save_path) did = 'tdes' opts = [ save_path, did, '--project_path', ctx.path, '--name', name, '--description', description, ] result = runner.invoke(gsmodutils.cli.dimport, opts) assert result.exit_code == 0 assert did in project.designs mdl = project.load_design(did) assert mdl.reactions.EX_xyl__D_e.lower_bound == -8.00 assert "EX_glc__D_e" not in mdl.reactions des = project.get_design(did) assert des.name == name assert des.description == description # Now test inheritence cdid = 'tdes_child' rb15bp = cobra.Metabolite(id='rb15bp_c', name='D-Ribulose 1,5-bisphosphate', formula='C5H8O11P2', charge=0) mdl.add_metabolites(rb15bp) rubisco = cobra.Reaction(id="RBPC", lower_bound=0, upper_bound=1000.0, name="Ribulose-bisphosphate carboxylase") mdl.add_reactions([rubisco]) stoich = { "3pg_c": 2.0, "rb15bp_c": -1.0, "co2_c": -1.0, "h2o_c": -1.0, "h_c": 2.0 } rubisco.add_metabolites(stoich) cobra.io.save_json_model(mdl, save_path) opts = [save_path, cdid, '--project_path', ctx.path, '--parent', did] name = 'test m' description = 'test desc' result = runner.invoke(gsmodutils.cli.dimport, opts, input='{}\n{}\n'.format(name, description)) assert result.exit_code == 0 tmdl = project.load_design(cdid) cdes = project.get_design(cdid) # Test parent loads assert cdes.parent.id == did assert tmdl.reactions.EX_xyl__D_e.lower_bound == -8.00 assert "EX_glc__D_e" not in tmdl.reactions # Test child stuff assert "RBPC" in tmdl.reactions assert cdes.name == name assert cdes.description == description desc_n = "overwrite valid test" name_n = "overwrite" # Test overwrite - valid opts = [ save_path, cdid, '--project_path', ctx.path, '--parent', did, '--description', desc_n, '--name', name_n, '--overwrite' ] result = runner.invoke(gsmodutils.cli.dimport, opts) assert result.exit_code == 0 odes = project.get_design(cdid) assert odes.name == name_n assert odes.description == desc_n # Test non-existent parent opts = [ save_path, 'should_fail', '--project_path', ctx.path, '--parent', 'notarealparentanyway' ] result = runner.invoke(gsmodutils.cli.dimport, opts) assert result.exit_code == -3 assert 'should_fail' not in project.list_designs # Test overwrite existing fail and pass opts = [save_path, cdid, '--project_path', ctx.path, '--parent', did] # Test overwrite existing fail and pass result = runner.invoke(gsmodutils.cli.dimport, opts) assert result.exit_code == -2
def test_load_project(): with FakeProjectContext() as ctx: project = GSMProject(ctx.path) assert project.project_path == ctx.path
def test_py_tests(): """ This is a test of python test code within a python test. These tests are important because the exec code is nasty to debug... """ code_str = """ # Look our tests are python 2 compatible! # p.s. if you're reading this you're such a nerd from __future__ import print_function from gsmodutils.test.utils import ModelTestSelector @ModelTestSelector(models=["not_there"], conditions=["xyl_src", "bad", "not_there"], designs=["not_there"]) def test_func(model, project, log): log.assertion(True, "Works", "Does not work", "Test") # For code coverage @ModelTestSelector() def test_func_cove(model, project, log): log.assertion(True, "Works", "Does not work", "Test") def test_model(model, project, log): solution = model.solver.optimize() print('This is the end') log.warning(True, "this is a warning") log.assertion(True, "Model grows", "Model does not grow") log.assertion(False, "Model grows", "Model does not grow") def test_exception(model, project, log): raise Exception('This is exceptional') """ syntax_err = """ def test_model(model, project, log): print('This is the end {}'.format(solution) """ with FakeProjectContext() as fp: project = GSMProject(fp.path) fp.add_fake_conditions() mdl = fp.project.model load_medium(mdl, dict()) fp.project.save_conditions(mdl, "bad", apply_to=fp.project.config.default_model, observe_growth=False) test_codep = 'test_code.py' tfp = os.path.join(project.tests_dir, test_codep) with open(tfp, 'w+') as testf: testf.write(code_str) tfp = os.path.join(project.tests_dir, 'test_syn_err.py') with open(tfp, 'w+') as testf: testf.write(syntax_err) tester = project.project_tester() tester.run_all() assert len(tester.syntax_errors) == 1 log = tester.run_by_id('test_code.py::test_model') assert log.std_out == "This is the end\n" # Test record should capture the standard output runner = CliRunner() lpath = os.path.join(fp.path, 'lp.json') result = runner.invoke( gsmodutils.cli.test, ['--project_path', fp.path, '--verbose', '--log_path', lpath]) assert result.exit_code == 0 result = runner.invoke( gsmodutils.cli.test, ['--project_path', fp.path, '--verbose', '--test_id', test_codep]) assert result.exit_code == 0 result = runner.invoke(gsmodutils.cli.test, [ '--project_path', fp.path, '--verbose', '--test_id', '{}::test_func'.format(test_codep) ]) assert result.exit_code == 0 result = runner.invoke(gsmodutils.cli.test, [ '--project_path', fp.path, '--verbose', '--test_id', 'test_syn_err.py' ]) assert result.exit_code == -1 project.run_tests()
def test_design_parent(): """ Design class should throw errors for cyclical parent designs, but accept valid hierarchy""" with FakeProjectContext() as ctx: project = GSMProject(ctx.path) # Create a design model = project.load_model() # Phosphoribulokinase reaction stoich = dict( atp_c=-1.0, ru5p__D_c=-1.0, adp_c=1.0, h_c=1.0, rb15bp_c=1.0, ) rb15bp = cobra.Metabolite(id='rb15bp_c', name='D-Ribulose 1,5-bisphosphate', formula='C5H8O11P2', charge=0) model.add_metabolites(rb15bp) pruk = cobra.Reaction(id="PRUK", name="Phosphoribulokinase reaction", lower_bound=-1000, upper_bound=1000) model.add_reactions([pruk]) pruk.add_metabolites(stoich) # Rubisco reaction (Ribulose-bisphosphate carboxylase) stoich = { "3pg_c": 2.0, "rb15bp_c": -1.0, "co2_c": -1.0, "h2o_c": -1.0, "h_c": 2.0 } rubisco = cobra.Reaction(id="RBPC", lower_bound=0, upper_bound=1000.0, name="Ribulose-bisphosphate carboxylase") model.add_reactions([rubisco]) rubisco.add_metabolites(stoich) model.genes.get_by_id("b3916").knock_out() model.genes.get_by_id("b1723").knock_out() model.genes.get_by_id("b1852").knock_out() model.reactions.EX_glc__D_e.lower_bound = -10.0 model.reactions.EX_nh4_e.lower_bound = -1000.0 design = project.save_design( model, 'cbb_cycle', 'calvin cycle', description='Reactions necissary for the calvin cycle in ecoli', overwrite=True) # Test html string # Test string representation str(design) design._repr_html_() # test jsonschema is valid design.validate_dict(design.to_dict()) # Create a child of this design model = project.load_design('cbb_cycle') reaction = cobra.Reaction(id="HMGCOASi", name="Hydroxymethylglutaryl CoA synthase") aacoa = cobra.Metabolite(id="aacoa_c", charge=-4, formula="C25H36N7O18P3S", name="Acetoacetyl-CoA") hmgcoa = cobra.Metabolite(id="hmgcoa_c", charge=-5, formula="C27H40N7O20P3S", name="Hydroxymethylglutaryl CoA") model.add_metabolites([aacoa, hmgcoa]) stoich = dict( aacoa_c=-1.0, accoa_c=-1.0, coa_c=1.0, h_c=1.0, h2o_c=-1.0, hmgcoa_c=1.0, ) model.add_reactions([reaction]) reaction.add_metabolites(stoich) reaction.lower_bound = -1000.0 reaction.upper_bound = 1000.0 mev__R = cobra.Metabolite(id="mev__R_c", name="R Mevalonate", charge=-1, formula="C6H11O4") model.add_metabolites([mev__R]) reaction = cobra.Reaction(id="HMGCOAR", name="Hydroxymethylglutaryl CoA reductase") reaction.lower_bound = -1000.0 reaction.upper_bound = 1000.0 stoich = dict(coa_c=-1.0, h_c=2.0, nadp_c=-2.0, nadph_c=2.0, hmgcoa_c=1.0, mev__R_c=-1.0) model.add_reactions([reaction]) reaction.add_metabolites(stoich) model.add_boundary(mev__R, type='sink') # add somewhere for mevalonate to go design = project.save_design( model, 'mevalonate_cbb', 'mevalonate production', parent='cbb_cycle', description='Reactions for the production of mevalonate', overwrite=True) des = project.get_design('mevalonate_cbb') inf = des.info pmodel = des.as_pathway_model() # TODO Test reactions are correct (counts should be correct) des.reactions_dataframe() des.genes_dataframe() des.to_dict() des.metabolites_dataframe() des.removed_genes # Check copying models works tmodel = cobra.Model() tmodel.id = 'test' des.add_to_model(tmodel, copy=True) # Requires a cobra model with pytest.raises(TypeError): des.add_to_model(model=None) # try to overwrite with pytest.raises(IOError): path = os.path.join(project._project_path, project.config.design_dir, '{}.json'.format(des.id)) des.to_json(path, overwrite=False) # Try to save a design with a bad parent with pytest.raises(DesignError): des.id = 'fuuuu' project.save_design( model, 'mevalonate_cbbd', 'mevalonate production', parent=des, description='Reactions for the production of mevalonate') _ = project.list_models _ = project.list_conditions
def test_parantage(): """ Tests for child and parent designs. Take a breath, this is some pretty confusing logic. """ py_design = """ from gsmodutils.utils import design_annotation @design_annotation(parent="mevalonate_cbb") def gsmdesign_thanos(model, project): reaction = model.reactions.get_by_id("ATPM") reaction.bounds = (-999, 999) return model @design_annotation(parent="t1_thanos") def gsmdesign_child_of_thanos(model, project): reaction = model.reactions.get_by_id("ATPM") reaction.lower_bound = 0 return model @design_annotation(parent="thanos") def gsmdesign_invalid_parent_id(model, project): reaction = model.reactions.get_by_id("ATPM") reaction.lower_bound = 0 return model """ with FakeProjectContext() as ctx: project = GSMProject(ctx.path) # Create existing json designs ctx.add_fake_designs() ndpath = os.path.join(project.design_path, 'design_t1.py') # Write the design with open(ndpath, 'w+') as desf: desf.write(py_design) d1 = project.get_design("t1_thanos") assert d1.id == "t1_thanos" assert d1.parent.id == "mevalonate_cbb" m1 = d1.load() assert m1.reactions.get_by_id("RBPC").lower_bound == 0 design = project.get_design("t1_child_of_thanos") assert design.parent.id == "t1_thanos" assert design.parent.parent.id == "mevalonate_cbb" mdl = design.load() # t1_child_of_thanos reaction = mdl.reactions.get_by_id("ATPM") assert reaction.lower_bound == 0 mdl2 = design.parent.load() # should be t1_thanos assert mdl2.design.id == "t1_thanos" assert mdl2.design.parent.id == "mevalonate_cbb" reaction = mdl2.reactions.get_by_id("ATPM") assert reaction.lower_bound == -999 mdl2.reactions.EX_xyl__D_e.lower_bound = -8.00 mdl2.save_as_design("json_child_of_thanos", "jsonchild", "json_child_of_thanos") design2 = project.get_design("json_child_of_thanos") assert design2.parent.id == "t1_thanos" assert design2.id == design2.load().design.id assert design2.parent.parent.parent.id == "cbb_cycle" mdl3 = design2.load() reaction = mdl3.reactions.get_by_id("ATPM") assert reaction.lower_bound == -999 assert mdl3.reactions.EX_xyl__D_e.lower_bound == -8.00 # shows that the very top level json design is still working assert mdl3.reactions.get_by_id("RBPC").lower_bound == 0 # This design shouldn't load as the parent id ref is wrong with pytest.raises(DesignError): project.get_design("t1_invalid_parent_id")
def test_create_design(): """ Create a design that adds and removes reactions """ with FakeProjectContext() as ctx: project = GSMProject(ctx.path) model = project.model # Growth on xylose instead of glucose model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 project.save_conditions(model, 'xylose_growth') model.reactions.ATPM.lower_bound = 8.0 # Modified metabolite (all the water turned to hydrogen peroxide!?) model.metabolites.h2o_c.formula = 'H202' # Remove a reaction model.reactions.UDPGD.remove_from_model() # Add a reaction with a hetrologous metabolite metabolite = cobra.Metabolite() metabolite.id = 'test_c' metabolite.name = 'test_metabolite' metabolite.charge = 0 metabolite.formula = '' metabolite.notes = {} metabolite.annotation = {} metabolite.compartment = 'c' model.add_metabolites([metabolite]) reaction = cobra.Reaction() reaction.id = 'test_reaction' reaction.name = 'test' reaction.lower_bound = -1000.0 reaction.upper_bound = 1000.0 model.add_reactions([reaction]) reaction.add_metabolites({ 'h2o_c': -1, 'glx_c': -1, 'test_c': 1, 'o2_c': 1 }) model.add_boundary(metabolite, type='demand') # Add transporter for hetrologous metabolite project.save_design(model, 'test_design', 'test design 01', 'This is a test', conditions='xylose_growth') # Can't save a design twice with pytest.raises(IOError): project.save_design(model, 'test_design', 'test design 01', 'This is a test', conditions='xylose_growth') # Invalid base model with pytest.raises(KeyError): project.save_design(model, 'test_design22', 'test design 0221', 'This is a test', base_model='NONE') del model # assert design has been saved assert 'test_design' in project.list_designs assert os.path.exists( os.path.join(ctx.path, 'designs', 'test_design.json')) # Test loading the design into the default model nmodel = project.load_design('test_design') nmodel.reactions.get_by_id('test_reaction') nmodel.metabolites.get_by_id('test_c') # assert that the reaction is removed with pytest.raises(KeyError): nmodel.reactions.get_by_id('UDPGD') # assert that the metabolite is changed assert nmodel.metabolites.h2o_c.formula == 'H202' # assert that the reaction bounds have been modified assert nmodel.reactions.ATPM.lower_bound == 8.0 # check conditions are loaded assert nmodel.reactions.EX_xyl__D_e.lower_bound == -8.00 assert nmodel.reactions.EX_glc__D_e.lower_bound == 0.0
def test_py_design(): """ Tests a working py_design """ py_design = """ from gsmodutils.utils import design_annotation @design_annotation(name="tester") def gsmdesign_tester(model, project): '''This is the description''' reaction = model.reactions.get_by_id("ATPM") reaction.bounds = (-999, 999) return model @design_annotation() def gsmdesign_no_return(model, project): pass @design_annotation() def gsmdesign_bad_prototype(model): return model @design_annotation(conditions="xylose_growth", description="overridden description") def gsmdesign_uses_conditions(model, project): '''orginal description''' return model @design_annotation(base_model="e_coli_core.json") def gsmdesign_uses_base_model(model, project): return model @design_annotation(base_model="e_coli_core") def gsmdesign_bad_base_model(model, project): return model """ broken_file = """ THIS IS CLEARLY BROKEN PYTHON SYNTAX """ with FakeProjectContext(use_second_model=True) as ctx: project = GSMProject(ctx.path) ndpath = os.path.join(project.design_path, 'design_t1.py') # Write the design with open(ndpath, 'w+') as desf: desf.write(py_design) # The file is broken but but the project should still load ndpath = os.path.join(project.design_path, 'design_broken.py') with open(ndpath, 'w+') as desb: desb.write(broken_file) # Should load without error design = project.get_design("t1_tester") assert design.is_pydesign assert design.name == "tester" assert design.parent is None assert design.description == "This is the description" mdl = design.load() # Check that the code has executed reaction = mdl.reactions.get_by_id("ATPM") assert reaction.lower_bound == -999 assert reaction.upper_bound == 999 model = project.model # Growth on xylose instead of glucose model.reactions.EX_xyl__D_e.lower_bound = -8.00 model.reactions.EX_glc__D_e.lower_bound = 0.0 project.save_conditions(model, 'xylose_growth', carbon_source="EX_xyl__D_e") design = project.get_design("t1_uses_conditions") assert design.description == "overridden description" assert design.conditions == "xylose_growth" mdl = design.load() assert mdl.reactions.EX_glc__D_e.lower_bound == 0 assert mdl.reactions.EX_xyl__D_e.lower_bound == -8.00 with pytest.raises(DesignError): project.get_design("t1_no_return") with pytest.raises(DesignError): project.get_design("t1_bad_prototype") design = project.get_design("t1_uses_base_model") assert design.base_model == "e_coli_core.json" assert len(design.load().reactions) == 95 # Make sure the base model is loaded with pytest.raises(DesignError): project.get_design("t1_bad_base_model")
def test_no_model_to_add(): with FakeProjectContext() as ctx: with pytest.raises(IOError): project = GSMProject(ctx.path) project.add_model('/does/not/exist')