예제 #1
0
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
예제 #2
0
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
예제 #3
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()
예제 #4
0
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")
예제 #5
0
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
예제 #6
0
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
예제 #7
0
    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
예제 #8
0
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
예제 #9
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
예제 #10
0
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)
예제 #12
0
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
예제 #13
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
예제 #14
0
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)
예제 #15
0
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)
예제 #17
0
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
예제 #18
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
예제 #19
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")
예제 #20
0
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
예제 #21
0
def test_load_project():

    with FakeProjectContext() as ctx:
        project = GSMProject(ctx.path)
        assert project.project_path == ctx.path
예제 #22
0
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()
예제 #23
0
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
예제 #24
0
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")
예제 #25
0
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
예제 #26
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")
예제 #27
0
def test_no_model_to_add():
    with FakeProjectContext() as ctx:
        with pytest.raises(IOError):
            project = GSMProject(ctx.path)
            project.add_model('/does/not/exist')