def test_write_sbml_file(self):

        import libsbml
        from biocrnpyler import ChemicalReactionNetwork
        from biocrnpyler import Species
        from biocrnpyler import Reaction

        s1 = Species(name='test_species1')
        s2 = Species(name='test_species2')

        species_list = [s1, s2]

        rx1 = Reaction(inputs=[s1], outputs=[s2], k=0.1)
        rxn_list = [rx1]

        crn = ChemicalReactionNetwork(species=species_list, reactions=rxn_list)
        document, _ = crn.generate_sbml_model()
        sbml_string = libsbml.writeSBMLToString(document)

        file_name = 'test_sbml.xml'
        with patch("builtins.open", new=mock_open()) as _file:
            crn.write_sbml_file(file_name)

            _file.assert_called_once_with(file_name, 'w')
            _file().write.assert_called_once_with(sbml_string)
Esempio n. 2
0
    def test_species_protection(self):
        #tests that Species cannot be changed once they are in a CRN
        S = Species("S")
        S2 = Species("S2")
        CRN = ChemicalReactionNetwork([S], [])

        #Internal species copied correctly to return
        assert S in CRN.species

        #assert species are copied
        assert not S is CRN._species[0]

        #Returned list does not effect internal species
        CRN.species[0] = S2
        assert S2 not in CRN.species

        #add species effects internal species list
        CRN.add_species(S2)
        assert S2 in CRN.species
        #assert correct copying
        assert S2 is not CRN._species[1]

        with self.assertRaisesRegex(
                AttributeError,
                "The species in a CRN cannot be removed or modified*"):
            CRN.species = []

        #Test bypassing species protection
        CRN = ChemicalReactionNetwork([], [])
        CRN.add_species([S], copy_species=False)
        assert S is CRN._species[0]
def test_bioscrape_import_simulate_via_sbml():
    from biocrnpyler import ChemicalReactionNetwork, Species
    try:
        import numpy as np

        X = Species("X")
        CRN = ChemicalReactionNetwork(species=[X], reactions=[])
        with pytest.warns(None) as record:
            sim_result, bioscrape_model = CRN.simulate_with_bioscrape_via_sbml(
                timepoints=np.linspace(0, 10, 100),
                initial_condition_dict={str(X): 1},
                return_model=True)

        #In the case bioscrape is not imported
        if sim_result is None and bioscrape_model is None:
            # only one warning was triggered
            assert len(record) == 1
            # check the warning message
            assert str(record[0].message
                       ) == "bioscrape was not found, please install bioscrape"

        #In the case bioscrape is imported
        else:
            assert str(X) in sim_result
            assert bioscrape_model is not None
    except ModuleNotFoundError:
        print('test skipped')
def test_initial_condition_in_crn():
    S = Species("S")
    S2 = Species("S2")
    S3 = Species("S3")

    CRN = ChemicalReactionNetwork(species=[S, S2, S3], reactions=[])

    #No Initial Concentration Dict
    assert S not in CRN.initial_concentration_dict

    #test setter
    CRN.initial_concentration_dict = {S: 10, S2: 10}
    assert S in CRN.initial_concentration_dict
    assert CRN.initial_concentration_dict[S] == 10

    #Test setter overwriting
    CRN.initial_concentration_dict = {S: 11, S3: 10}
    assert S2 in CRN.initial_concentration_dict
    assert CRN.initial_concentration_dict[S] == 11
    assert CRN.initial_concentration_dict[S2] == 10
    assert CRN.initial_concentration_dict[S3] == 10

    #Test setter reset
    CRN.initial_concentration_dict = None
    assert S not in CRN.initial_concentration_dict
    assert S2 not in CRN.initial_concentration_dict
    assert S3 not in CRN.initial_concentration_dict
    def test_initial_condition_vector(self):
        from biocrnpyler import ChemicalReactionNetwork
        from biocrnpyler import Species
        from biocrnpyler import Reaction

        s1 = Species(name='test_species1')
        s2 = Species(name='test_species2')

        species_list = [s1, s2]

        rx1 = Reaction(inputs=[s1], outputs=[s2], k=0.1)
        rxn_list = [rx1]

        crn = ChemicalReactionNetwork(species=species_list, reactions=rxn_list)

        s3 = Species(name='test_species3')

        init_cond = {s1: 5, s3: 10}

        x0 = crn.initial_condition_vector(init_cond_dict=init_cond)

        not_in_the_list = False
        for key, value in init_cond.items():
            if value not in x0 and key == s3:
                not_in_the_list = True
        self.assertTrue(not_in_the_list)
Esempio n. 6
0
    def setUp(self) -> None:
        """this method gets executed before every test"""
        self.s1 = Species(name='test_species1')
        self.s2 = Species(name='test_species2')
        self.s3 = Species(name='test_species3')
        self.s4 = Species(name='test_species4')

        self.species_list = [self.s1, self.s2]
        # creating a valid reaction two species
        self.rx1 = Reaction(inputs=[self.s1], outputs=[self.s2], k=0.1)
        self.rxn_list = [self.rx1]

        self.crn = ChemicalReactionNetwork(species=self.species_list, reactions=self.rxn_list)
Esempio n. 7
0
def test_libroadrunner_import():
    from biocrnpyler import ChemicalReactionNetwork
    CRN = ChemicalReactionNetwork(species=[], reactions=[])
    try:
        import roadrunner
    except ModuleNotFoundError:
        # libroadrunner is not installed, let's check if it triggers a warning inside simulate_with_roadrunner()
        with pytest.warns(UserWarning, match='libroadrunner was not found, please install libroadrunner'):
            CRN.simulate_with_roadrunner(timepoints=list(range(0,10)))
    else:
        # no exception was triggered, we can simulate the CRN with roadrunner
        sim_results = CRN.simulate_with_roadrunner(timepoints=list(range(0,10)))
        assert sim_results is not None
Esempio n. 8
0
    def test_compile_crn(self):
        from biocrnpyler import ChemicalReactionNetwork
        from biocrnpyler import Species
        from biocrnpyler import Reaction
        from biocrnpyler import Mixture

        a = Species(name='a')
        b = Species(name='b')

        species_list = [a, b]

        def mock_update_reactions():
            rxn = Reaction(inputs=[a], outputs=[b], k=0.1)
            return [rxn]

        rxn = Reaction(inputs=[a], outputs=[b], k=0.1)

        CRN = ChemicalReactionNetwork(species_list, [rxn])

        mixture = Mixture(species=species_list)
        mixture.update_reactions = mock_update_reactions

        crn_from_mixture = mixture.compile_crn()
        self.assertEqual(CRN.species, crn_from_mixture.species)
        self.assertEqual(CRN.reactions, crn_from_mixture.reactions)
Esempio n. 9
0
    def test_compile_crn(self):
        a = Species(name='a')
        b = Species(name='b')

        species_list = [a, b]

        rxn = Reaction.from_massaction(inputs=[a], outputs=[b], k_forward=0.1)

        CRN = ChemicalReactionNetwork(species_list, [rxn])

        # create a component
        component = Component("comp")

        # creating a mock update function to decouple the update process from the rest of the code
        def mock_update_reactions():
            rxn = Reaction.from_massaction(inputs=[a], outputs=[b], k_forward=0.1)
            return [rxn]

        def mock_update_species():
            return [a, b]

        component.update_species = mock_update_species
        component.update_reactions = mock_update_reactions

        mixture = Mixture(components=[component])

        crn_from_mixture = mixture.compile_crn()
        # test that the mixture has the same species as the manually build CRN object
        self.assertEqual(set(CRN.species), set(crn_from_mixture.species))
        # test that the mixture has the same reactions as the manually build CRN object
        self.assertEqual(CRN.reactions, crn_from_mixture.reactions)
Esempio n. 10
0
    def test_write_sbml_file(self):
        s1, s2 = Species("S1"), Species("S2")
        rx1 = Reaction.from_massaction(inputs=[s1],
                                       outputs=[s2],
                                       k_forward=0.1)
        crn = ChemicalReactionNetwork(species=[s1, s2], reactions=[rx1])

        model_id = 'test_model'
        document, _ = crn.generate_sbml_model(model_id=model_id)
        sbml_string = libsbml.writeSBMLToString(document)

        file_name = 'test_sbml.xml'
        with patch("builtins.open", new=mock_open()) as _file:
            crn.write_sbml_file(file_name, model_id=model_id)

            _file.assert_called_once_with(file_name, 'w')
            _file().write.assert_called_once_with(sbml_string)
    def test_get_all_species_containing(self):
        from biocrnpyler import ChemicalReactionNetwork
        from biocrnpyler import Species
        from biocrnpyler import Reaction

        s1 = Species(name='test_species1')
        s2 = Species(name='test_species2')

        species_list = [s1, s2]

        rx1 = Reaction(inputs=[s1], outputs=[s2], k=0.1)
        rxn_list = [rx1]

        crn = ChemicalReactionNetwork(species=species_list, reactions=rxn_list)

        s3 = Species(name='test_species3')

        with self.assertRaises(ValueError):
            crn.get_all_species_containing(species=species_list)

        rtn_species_list = crn.get_all_species_containing(species=s3)
        self.assertEqual(rtn_species_list, [])

        rtn_species_list = crn.get_all_species_containing(species=s1)
        self.assertEqual(rtn_species_list, [s1])

        rtn_species_list = crn.get_all_species_containing(
            species=s1, return_as_strings=True)
        self.assertEqual(rtn_species_list, [repr(s1)])
    def test_generate_sbml_model(self):
        from biocrnpyler import ChemicalReactionNetwork
        from biocrnpyler import Species
        from biocrnpyler import Reaction

        s1 = Species(name='test_species1')
        s2 = Species(name='test_species2')

        species_list = [s1, s2]

        rx1 = Reaction(inputs=[s1], outputs=[s2], k=0.1)
        rxn_list = [rx1]

        crn = ChemicalReactionNetwork(species=species_list, reactions=rxn_list)

        document, model = crn.generate_sbml_model()

        self.assertEqual(len(model.getListOfSpecies()), len(crn.species))
        self.assertEqual(len(model.getListOfReactions()), len(crn.reactions))
Esempio n. 13
0
def test_bioscrape_import_simulate():
    from biocrnpyler import ChemicalReactionNetwork, Species
    try:
        import numpy as np

        X = Species("X")
        CRN = ChemicalReactionNetwork(species=[X],reactions=[])
        with pytest.warns(None) as record:
            sim_result = CRN.simulate_with_bioscrape(timepoints=np.linspace(0, 10, 100), initial_condition_dict = {str(X):1})


        #In the case bioscrape is not imported
        if sim_result is None:
            # check the warning message
            assert "simulate_with_bioscrape is depricated and will cease working in a future release." in str(record[0].message)
        #In the case bioscrape is imported
        else:
            assert str(X) in sim_result
    except ModuleNotFoundError:
        print('test skipped')
def test_libroadrunner_import():
    from biocrnpyler import ChemicalReactionNetwork
    try:
        import numpy as np

        CRN = ChemicalReactionNetwork(species=[], reactions=[])
        with pytest.warns(None) as record:
            sim_results = CRN.runsim_roadrunner(timepoints=np.linspace(
                0, 10, 100),
                                                filename=None)

        assert sim_results is None

        # only one warning was triggered
        assert len(record) == 1
        # check the warning message
        assert str(
            record[0].message
        ) == "libroadrunner was not found, please install libroadrunner"
    except ModuleNotFoundError:
        print('test skipped')
Esempio n. 15
0
    def test_generate_sbml_model(self):

        # generate an sbml model
        document, model = self.crn.generate_sbml_model()
        # all species from the CRN are accounted for
        self.assertEqual(len(model.getListOfSpecies()), len(self.crn.species))
        # all reactions from the CRN are accounted for
        self.assertEqual(len(model.getListOfReactions()), len(self.crn.reactions))

        # test a reversible reaction
        rx1 = Reaction(inputs=[self.s1], outputs=[self.s2], k=0.1, k_rev=0.1)
        rxn_list = [rx1]
        crn = ChemicalReactionNetwork(species=self.species_list, reactions=rxn_list)

        # generate an sbml model
        document, model = crn.generate_sbml_model()
        # all species from the CRN are accounted for
        self.assertEqual(len(model.getListOfSpecies()), len(crn.species))
        # all reactions from the CRN are accounted for
        # the sbml represents a reverisble reaction with to separate reactions
        self.assertEqual(len(model.getListOfReactions()), 2*len(crn.reactions))
    def test_check_crn_validity(self):
        from biocrnpyler import ChemicalReactionNetwork
        from biocrnpyler import Species
        from biocrnpyler import Reaction

        s1 = Species(name='test_species1')
        s2 = Species(name='test_species2')
        species_list = [s1, s2]

        rx1 = Reaction(inputs=[s1], outputs=[s2], k=0.1)
        rxn_list = [rx1]

        checked_species, checked_reactions = ChemicalReactionNetwork.check_crn_validity(
            reactions=rxn_list, species=species_list)

        self.assertEqual(species_list, checked_species)

        self.assertEqual(rxn_list, checked_reactions)

        species_list_with_none = species_list.copy()
        species_list_with_none.append(None)
        with self.assertRaises(ValueError):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list, species=species_list_with_none)

        rxn_list_with_none = rxn_list.copy()
        rxn_list_with_none.append(None)
        with self.assertRaises(ValueError):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list_with_none, species=species_list)

        s3 = Species(name='test_species3')
        s4 = Species(name='test_species4')

        rxn2 = Reaction(inputs=[s1], outputs=[s3], k=0.1)
        with self.assertWarns(Warning):
            ChemicalReactionNetwork.check_crn_validity(reactions=[rxn2],
                                                       species=species_list,
                                                       warnings=True)

        rxn3 = Reaction(inputs=[s4], outputs=[s2], k=0.1)
        with self.assertWarns(Warning):
            ChemicalReactionNetwork.check_crn_validity(reactions=[rxn3],
                                                       species=species_list,
                                                       warnings=True)
Esempio n. 17
0
    def test_replace_in_a_chemical_reaction_network(self):
        c1 = Complex([self.s1, self.s_old])
        c2 = Complex([self.s1, c1])
        species = [self.s1, self.s_old, c1, c2]
        r1 = Reaction.from_massaction([self.s1, self.s_old], [c1], k_forward=1)
        crn = ChemicalReactionNetwork(species=species, reactions=[r1])
        new_crn = crn.replace_species(self.s_old, self.s_new)

        self.assertTrue(self.s1 in new_crn.species)
        self.assertFalse(self.s_old in new_crn.species)

        self.assertTrue(self.s_new in new_crn.species)
        self.assertFalse(c1 in new_crn.species)
        self.assertFalse(c2 in new_crn.species)
        c1_new = Complex([self.s1, self.s_new])
        c2_new = Complex([self.s1, c1_new])
        self.assertTrue(c1_new in new_crn.species)
        self.assertTrue(c2_new in new_crn.species)
        r1_new = Reaction.from_massaction([self.s1, self.s_new], [c1_new],
                                          k_forward=1)
        self.assertFalse(r1 in new_crn.reactions)
        self.assertTrue(r1_new in new_crn.reactions)
Esempio n. 18
0
    def test_compile_crn_directives(self):
        a = Species(name='a')
        b = Species(name='b')

        species_list = [a, b]

        rxn = Reaction.from_massaction(inputs=[a], outputs=[b], k_forward=0.1)

        CRN = ChemicalReactionNetwork(species_list, [rxn])

        # create a component
        component = Component("comp")

        # creating a mock update function to decouple the update process from the rest of the code
        def mock_update_reactions():
            rxn = Reaction.from_massaction(inputs=[a], outputs=[b], k_forward=0.1)
            return [rxn]

        def mock_update_species():
            return [a, b]

        component.update_species = mock_update_species
        component.update_reactions = mock_update_reactions

        mixture = Mixture(components=[component])

        #All the directives used below should not change the CRN. 
        #They just remove some checks and safegaurds, but compilation should work the same in this simple case.
        #directives are best used in specific cases to compile very large models where speed is essential

        crn_from_mixture1 = mixture.compile_crn(copy_objects = False)
        # test that the mixture has the same species as the manually build CRN object
        self.assertEqual(set(CRN.species), set(crn_from_mixture1.species))
        # test that the mixture has the same reactions as the manually build CRN object
        self.assertEqual(CRN.reactions, crn_from_mixture1.reactions)


        crn_from_mixture2 = mixture.compile_crn(add_reaction_species = False)
        # test that the mixture has the same species as the manually build CRN object
        self.assertEqual(set(CRN.species), set(crn_from_mixture2.species))
        # test that the mixture has the same reactions as the manually build CRN object
        self.assertEqual(CRN.reactions, crn_from_mixture2.reactions)

        crn_from_mixture3 = mixture.compile_crn(initial_concentrations_at_end = True)
        # test that the mixture has the same species as the manually build CRN object
        self.assertEqual(set(CRN.species), set(crn_from_mixture3.species))
        # test that the mixture has the same reactions as the manually build CRN object
        self.assertEqual(CRN.reactions, crn_from_mixture3.reactions)
Esempio n. 19
0
    def test_compile_crn(self):
        a = Species(name='a')
        b = Species(name='b')

        species_list = [a, b]

        # creating a mock update function to decouple the update process from the rest of the code
        def mock_update_reactions():
            rxn = Reaction(inputs=[a], outputs=[b], k=0.1)
            return [rxn]

        rxn = Reaction(inputs=[a], outputs=[b], k=0.1)

        CRN = ChemicalReactionNetwork(species_list, [rxn])

        mixture = Mixture(species=species_list)
        mixture.update_reactions = mock_update_reactions

        crn_from_mixture = mixture.compile_crn()
        # test that the mixture has the same species as the manually build CRN object
        self.assertEqual(CRN.species, crn_from_mixture.species)
        # test that the mixture has the same reactions as the manually build CRN object
        self.assertEqual(CRN.reactions, crn_from_mixture.reactions)
Esempio n. 20
0
    def test_check_crn_validity(self):

        checked_species, checked_reactions = ChemicalReactionNetwork.check_crn_validity(
            reactions=self.rxn_list, species=self.species_list)
        # test that the returned species list is the same as the species list supplied
        self.assertEqual(self.species_list, checked_species)
        # test that the returned reaction list is the same as the reaction list supplied
        self.assertEqual(self.rxn_list, checked_reactions)

        species_list_with_none = self.species_list.copy()
        # injecting a None to the species list
        species_list_with_none.append(None)
        # test whether a non-species object is detected and Value error has been raised
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"'
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"
        with self.assertRaisesRegexp(
                ValueError, "A non-species object was used as a species!"):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=self.rxn_list, species=species_list_with_none)

        rxn_list_with_none = self.rxn_list.copy()
        # injecting a None to the reaction list
        rxn_list_with_none.append(None)
        # test whether a non-reaction object is detected and Value Error has been raised
        with self.assertRaisesRegexp(
                ValueError, 'A non-reaction object was used as a reaction!'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list_with_none, species=self.species_list)

        rxn2 = Reaction(inputs=[self.s1], outputs=[self.s3], k=0.1)
        # test warning raised if a species (in the reaction outputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning,
                f'contains a species {self.s3.name} which is not in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn2], species=self.species_list, warnings=True)

        rxn3 = Reaction(inputs=[self.s4], outputs=[self.s2], k=0.1)
        # test warning raised if a species (in the reaction inputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning,
                f'contains a species {self.s4.name} which is not in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn3], species=self.species_list, warnings=True)

        # test duplicate reactions
        rxn_list = [self.rx1, self.rx1]
        with self.assertWarnsRegex(Warning,
                                   'may be duplicated in CRN definitions'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list, species=self.species_list, warnings=True)
Esempio n. 21
0
class TestChemicalReactionNetwork(TestCase):
    def setUp(self) -> None:
        """this method gets executed before every test"""
        self.s1 = Species(name='test_species1')
        self.s2 = Species(name='test_species2')
        self.s3 = Species(name='test_species3')
        self.s4 = Species(name='test_species4')

        self.species_list = [self.s1, self.s2]
        # creating a valid reaction two species
        self.rx1 = Reaction(inputs=[self.s1], outputs=[self.s2], k=0.1)
        self.rxn_list = [self.rx1]

        self.crn = ChemicalReactionNetwork(species=self.species_list,
                                           reactions=self.rxn_list)

    def test_check_crn_validity(self):

        checked_species, checked_reactions = ChemicalReactionNetwork.check_crn_validity(
            reactions=self.rxn_list, species=self.species_list)
        # test that the returned species list is the same as the species list supplied
        self.assertEqual(self.species_list, checked_species)
        # test that the returned reaction list is the same as the reaction list supplied
        self.assertEqual(self.rxn_list, checked_reactions)

        species_list_with_none = self.species_list.copy()
        # injecting a None to the species list
        species_list_with_none.append(None)
        # test whether a non-species object is detected and Value error has been raised
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"'
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"
        with self.assertRaisesRegexp(
                ValueError, "A non-species object was used as a species!"):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=self.rxn_list, species=species_list_with_none)

        rxn_list_with_none = self.rxn_list.copy()
        # injecting a None to the reaction list
        rxn_list_with_none.append(None)
        # test whether a non-reaction object is detected and Value Error has been raised
        with self.assertRaisesRegexp(
                ValueError, 'A non-reaction object was used as a reaction!'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list_with_none, species=self.species_list)

        rxn2 = Reaction(inputs=[self.s1], outputs=[self.s3], k=0.1)
        # test warning raised if a species (in the reaction outputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning,
                f'contains a species {self.s3.name} which is not in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn2], species=self.species_list, warnings=True)

        rxn3 = Reaction(inputs=[self.s4], outputs=[self.s2], k=0.1)
        # test warning raised if a species (in the reaction inputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning,
                f'contains a species {self.s4.name} which is not in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn3], species=self.species_list, warnings=True)

        # test duplicate reactions
        rxn_list = [self.rx1, self.rx1]
        with self.assertWarnsRegex(Warning,
                                   'may be duplicated in CRN definitions'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list, species=self.species_list, warnings=True)

    def test_species_index(self):
        # TODO add test if we actually use this function
        pass

    def test_initial_condition_vector(self):

        # no initial value is supplied for s2
        init_cond = {self.s1: 5, self.s3: 10}

        x0 = self.crn.initial_condition_vector(init_cond_dict=init_cond)

        # test that value for s3 is not in the initial value list because s3 is not part of any reaction
        not_in_the_list = False
        for key, value in init_cond.items():
            if value not in x0 and key == self.s3:
                not_in_the_list = True
        self.assertTrue(not_in_the_list)

    def test_get_all_species_containing(self):

        # test that the species arument must be Species object
        with self.assertRaisesRegexp(
                ValueError,
                'species argument must be an instance of Species!'):
            self.crn.get_all_species_containing(species=self.species_list)

        # s3 is not part of the CRN
        rtn_species_list = self.crn.get_all_species_containing(species=self.s3)
        # test that empty list is returned
        self.assertEqual(rtn_species_list, [])

        # test that s1 is returned only once
        rtn_species_list = self.crn.get_all_species_containing(species=self.s1)
        self.assertEqual(rtn_species_list, [self.s1])

        # test that s1 is returned only once as a string
        rtn_species_list = self.crn.get_all_species_containing(
            species=self.s1, return_as_strings=True)
        self.assertEqual(rtn_species_list, [repr(self.s1)])

    def test_generate_sbml_model(self):

        # generate an sbml model
        document, model = self.crn.generate_sbml_model()
        # all species from the CRN are accounted for
        self.assertEqual(len(model.getListOfSpecies()), len(self.crn.species))
        # all reactions from the CRN are accounted for
        self.assertEqual(len(model.getListOfReactions()),
                         len(self.crn.reactions))

        # test a reversible reaction
        rx1 = Reaction(inputs=[self.s1], outputs=[self.s2], k=0.1, k_rev=0.1)
        rxn_list = [rx1]
        crn = ChemicalReactionNetwork(species=self.species_list,
                                      reactions=rxn_list)

        # generate an sbml model
        document, model = crn.generate_sbml_model()
        # all species from the CRN are accounted for
        self.assertEqual(len(model.getListOfSpecies()), len(crn.species))
        # all reactions from the CRN are accounted for
        # the sbml represents a reverisble reaction with to separate reactions
        self.assertEqual(len(model.getListOfReactions()),
                         2 * len(crn.reactions))

    def test_write_sbml_file(self):

        document, _ = self.crn.generate_sbml_model()
        sbml_string = libsbml.writeSBMLToString(document)

        file_name = 'test_sbml.xml'
        with patch("builtins.open", new=mock_open()) as _file:
            self.crn.write_sbml_file(file_name)

            _file.assert_called_once_with(file_name, 'w')
            _file().write.assert_called_once_with(sbml_string)
Esempio n. 22
0
class TestChemicalReactionNetwork(TestCase):
    def setUp(self) -> None:
        """this method gets executed before every test"""
        self.s1 = Species(name='test_species1')
        self.s2 = Species(name='test_species2')
        self.s3 = Species(name='test_species3')
        self.s4 = Species(name='test_species4')

        self.s_old = Species("s_old")
        self.s_new = Species("s_new")

        self.species_list = [self.s1, self.s2]
        # creating a valid reaction two species
        self.rx1 = Reaction.from_massaction(inputs=[self.s1],
                                            outputs=[self.s2],
                                            k_forward=0.1)
        self.rxn_list = [self.rx1]

        self.crn = ChemicalReactionNetwork(species=self.species_list,
                                           reactions=self.rxn_list)

    def test_check_crn_validity(self):

        checked_reactions, checked_species = ChemicalReactionNetwork.check_crn_validity(
            reactions=self.rxn_list, species=self.species_list)
        # test that the returned species list is the same as the species list supplied
        self.assertEqual(self.species_list, checked_species)
        # test that the returned reaction list is the same as the reaction list supplied
        self.assertEqual(self.rxn_list, checked_reactions)

        species_list_with_none = self.species_list.copy()
        # injecting a None to the species list
        species_list_with_none.append(None)
        # test whether a non-species object is detected and Value error has been raised
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"'
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"
        with self.assertRaisesRegex(
                ValueError, "A non-species object was used as a species!"):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=self.rxn_list, species=species_list_with_none)

        rxn_list_with_none = self.rxn_list.copy()
        # injecting a None to the reaction list
        rxn_list_with_none.append(None)
        # test whether a non-reaction object is detected and Value Error has been raised
        with self.assertRaisesRegex(
                ValueError, 'A non-reaction object was used as a reaction!'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list_with_none, species=self.species_list)

        rxn2 = Reaction.from_massaction(inputs=[self.s1],
                                        outputs=[self.s3],
                                        k_forward=0.1)
        # test warning raised if a species (in the reaction outputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning, f'are not part of any reactions in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn2],
                species=self.species_list,
                show_warnings=True)

        rxn3 = Reaction.from_massaction(inputs=[self.s4],
                                        outputs=[self.s2],
                                        k_forward=0.1)
        # test warning raised if a species (in the reaction inputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning, f'are not part of any reactions in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn3],
                species=self.species_list,
                show_warnings=True)

        # test warning if reaction has unlisted species
        rxn4 = Reaction.from_massaction(inputs=[self.s4, self.s3],
                                        outputs=[self.s2],
                                        k_forward=0.1)
        with self.assertWarnsRegex(
                Warning,
                f'are not listed in the Species list, but part of the reactions'
        ):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn4],
                species=[self.s4, self.s2],
                show_warnings=True)

        # test duplicate reactions are both added
        rxn_list = [self.rx1, self.rx1]

        CRN = ChemicalReactionNetwork(species=[self.s1, self.s2],
                                      reactions=rxn_list)
        self.assertTrue(CRN.reactions.count(self.rx1) == 2)

        with self.assertWarnsRegex(Warning,
                                   'may be duplicated in CRN definitions'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list,
                species=self.species_list,
                show_warnings=True)

        # test warning suppression
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list,
                species=self.species_list,
                show_warnings=False)

        assert not w

    def test_species_protection(self):
        #tests that Species cannot be changed once they are in a CRN
        S = Species("S")
        S2 = Species("S2")
        CRN = ChemicalReactionNetwork([S], [])

        #Internal species copied correctly to return
        assert S in CRN.species

        #assert species are copied
        assert not S is CRN._species[0]

        #Returned list does not effect internal species
        CRN.species[0] = S2
        assert S2 not in CRN.species

        #add species effects internal species list
        CRN.add_species(S2)
        assert S2 in CRN.species
        #assert correct copying
        assert S2 is not CRN._species[1]

        with self.assertRaisesRegex(
                AttributeError,
                "The species in a CRN cannot be removed or modified*"):
            CRN.species = []

        #Test bypassing species protection
        CRN = ChemicalReactionNetwork([], [])
        CRN.add_species([S], copy_species=False)
        assert S is CRN._species[0]

    def test_reaction_protection(self):
        #tests that Reactions cannot be changed once they are in a CRN
        S = Species("S")
        S2 = Species("S2")
        R = Reaction.from_massaction([S], [S2], k_forward=1.0)
        R2 = Reaction.from_massaction([S2], [S], k_forward=1.0)
        CRN = ChemicalReactionNetwork([S, S2], [R])

        #Internal reactions copied correctly to return
        assert R in CRN.reactions
        assert not R is CRN._reactions[0]

        #Returned list does not effect internal reactions
        CRN.reactions[0] = R2
        assert R2 not in CRN.reactions

        #add reactions effects internal reaction list
        CRN.add_reactions(R2)
        assert R2 in CRN.reactions
        assert not R2 is CRN._reactions[1]

        with self.assertRaisesRegex(
                AttributeError,
                "The reactions in a CRN cannot be removed or modified*"):
            CRN.reactions = []

        #test bypassing reaction protection
        CRN = ChemicalReactionNetwork([], [])
        CRN.add_reactions([R], copy_reactions=False)
        assert R is CRN._reactions[0]
        assert S in CRN.species

        #test bypassing reaction protection
        CRN = ChemicalReactionNetwork([], [])
        CRN.add_reactions([R], add_species=False)
        assert not S in CRN.species

    def test_initial_condition_vector(self):

        # no initial value is supplied for s2
        init_cond = {self.s1: 5, self.s3: 10}

        x0 = self.crn.initial_condition_vector(init_cond_dict=init_cond)

        # test that value for s3 is not in the initial value list because s3 is not part of any reaction
        not_in_the_list = False
        for key, value in init_cond.items():
            if value not in x0 and key == self.s3:
                not_in_the_list = True
        self.assertTrue(not_in_the_list)

    def test_get_all_species_containing(self):

        # test that the species arument must be Species object
        with self.assertRaisesRegex(
                ValueError,
                'species argument must be an instance of Species!'):
            self.crn.get_all_species_containing(species=self.species_list)

        # s3 is not part of the CRN
        rtn_species_list = self.crn.get_all_species_containing(species=self.s3)
        # test that empty list is returned
        self.assertEqual(rtn_species_list, [])

        # test that s1 is returned only once
        rtn_species_list = self.crn.get_all_species_containing(species=self.s1)
        self.assertEqual(rtn_species_list, [self.s1])

        # test that s1 is returned only once as a string
        rtn_species_list = self.crn.get_all_species_containing(
            species=self.s1, return_as_strings=True)
        self.assertEqual(rtn_species_list, [repr(self.s1)])

    def test_replace_species_in_Species(self):

        #Test replace species in a Species
        self.assertTrue(
            self.s1.replace_species(self.s2, self.s_new) == self.s1)
        self.assertTrue(
            self.s_old.replace_species(self.s_old, self.s_new) == self.s_new)

    def test_replace_Species_in_ComplexSpecies(self):
        c1 = Complex([self.s1, self.s_old])
        c2 = Complex([self.s1, c1])
        self.assertTrue(c1.replace_species(self.s2, self.s_new) == c1)
        self.assertTrue(
            c1.replace_species(self.s_old, self.s_new) == Complex(
                [self.s1, self.s_new]))
        self.assertTrue(c2 == Complex([self.s1, c1]))
        self.assertTrue(
            c2.replace_species(self.s_new, self.s_old) == Complex(
                [self.s1, Complex([self.s1, self.s_old])]))

    def test_replace_Species_in_OrderedComplexSpecies(self):
        oc1 = Complex([self.s1, self.s_old], ordered=True)
        self.assertTrue(
            oc1.replace_species(self.s_old, self.s_new) == Complex(
                [self.s1, self.s_new], ordered=True))

    def test_replace_species_in_Reaction(self):
        c1 = Complex([self.s1, self.s_old])
        c2 = Complex([self.s1, self.s_new])
        r1 = Reaction.from_massaction([self.s1, self.s_old], [c1], k_forward=1)
        self.assertTrue(
            r1.replace_species(self.s_old, self.s_new) ==
            Reaction.from_massaction([self.s1, self.s_new], [c2], k_forward=1))

    def test_replace_species_with_a_non_massaction_reaction(self):
        c1 = Complex([self.s1, self.s_old])

        prop_hill_old = ProportionalHillPositive(k=1.,
                                                 s1=self.s1,
                                                 K=10,
                                                 d=self.s_old,
                                                 n=2)
        r1 = Reaction([self.s1, self.s_old], [c1],
                      propensity_type=prop_hill_old)
        prop_hill_new = ProportionalHillPositive(k=1.,
                                                 s1=self.s1,
                                                 K=10,
                                                 d=self.s_new,
                                                 n=2)
        r1_new = Reaction([self.s1, self.s_new],
                          [c1.replace_species(self.s_old, self.s_new)],
                          propensity_type=prop_hill_new)
        self.assertTrue(r1.replace_species(self.s_old, self.s_new) == r1_new)

    def test_replace_in_a_chemical_reaction_network(self):
        c1 = Complex([self.s1, self.s_old])
        c2 = Complex([self.s1, c1])
        species = [self.s1, self.s_old, c1, c2]
        r1 = Reaction.from_massaction([self.s1, self.s_old], [c1], k_forward=1)
        crn = ChemicalReactionNetwork(species=species, reactions=[r1])
        new_crn = crn.replace_species(self.s_old, self.s_new)

        self.assertTrue(self.s1 in new_crn.species)
        self.assertFalse(self.s_old in new_crn.species)

        self.assertTrue(self.s_new in new_crn.species)
        self.assertFalse(c1 in new_crn.species)
        self.assertFalse(c2 in new_crn.species)
        c1_new = Complex([self.s1, self.s_new])
        c2_new = Complex([self.s1, c1_new])
        self.assertTrue(c1_new in new_crn.species)
        self.assertTrue(c2_new in new_crn.species)
        r1_new = Reaction.from_massaction([self.s1, self.s_new], [c1_new],
                                          k_forward=1)
        self.assertFalse(r1 in new_crn.reactions)
        self.assertTrue(r1_new in new_crn.reactions)

    def test_write_sbml_file(self):
        s1, s2 = Species("S1"), Species("S2")
        rx1 = Reaction.from_massaction(inputs=[s1],
                                       outputs=[s2],
                                       k_forward=0.1)
        crn = ChemicalReactionNetwork(species=[s1, s2], reactions=[rx1])

        model_id = 'test_model'
        document, _ = crn.generate_sbml_model(model_id=model_id)
        sbml_string = libsbml.writeSBMLToString(document)

        file_name = 'test_sbml.xml'
        with patch("builtins.open", new=mock_open()) as _file:
            crn.write_sbml_file(file_name, model_id=model_id)

            _file.assert_called_once_with(file_name, 'w')
            _file().write.assert_called_once_with(sbml_string)
Esempio n. 23
0
    def test_reaction_protection(self):
        #tests that Reactions cannot be changed once they are in a CRN
        S = Species("S")
        S2 = Species("S2")
        R = Reaction.from_massaction([S], [S2], k_forward=1.0)
        R2 = Reaction.from_massaction([S2], [S], k_forward=1.0)
        CRN = ChemicalReactionNetwork([S, S2], [R])

        #Internal reactions copied correctly to return
        assert R in CRN.reactions
        assert not R is CRN._reactions[0]

        #Returned list does not effect internal reactions
        CRN.reactions[0] = R2
        assert R2 not in CRN.reactions

        #add reactions effects internal reaction list
        CRN.add_reactions(R2)
        assert R2 in CRN.reactions
        assert not R2 is CRN._reactions[1]

        with self.assertRaisesRegex(
                AttributeError,
                "The reactions in a CRN cannot be removed or modified*"):
            CRN.reactions = []

        #test bypassing reaction protection
        CRN = ChemicalReactionNetwork([], [])
        CRN.add_reactions([R], copy_reactions=False)
        assert R is CRN._reactions[0]
        assert S in CRN.species

        #test bypassing reaction protection
        CRN = ChemicalReactionNetwork([], [])
        CRN.add_reactions([R], add_species=False)
        assert not S in CRN.species
Esempio n. 24
0
    def test_check_crn_validity(self):

        checked_reactions, checked_species = ChemicalReactionNetwork.check_crn_validity(
            reactions=self.rxn_list, species=self.species_list)
        # test that the returned species list is the same as the species list supplied
        self.assertEqual(self.species_list, checked_species)
        # test that the returned reaction list is the same as the reaction list supplied
        self.assertEqual(self.rxn_list, checked_reactions)

        species_list_with_none = self.species_list.copy()
        # injecting a None to the species list
        species_list_with_none.append(None)
        # test whether a non-species object is detected and Value error has been raised
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"'
        #                                         A non-species object was used as a species: [test_species1, test_species2, None]!"
        with self.assertRaisesRegex(
                ValueError, "A non-species object was used as a species!"):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=self.rxn_list, species=species_list_with_none)

        rxn_list_with_none = self.rxn_list.copy()
        # injecting a None to the reaction list
        rxn_list_with_none.append(None)
        # test whether a non-reaction object is detected and Value Error has been raised
        with self.assertRaisesRegex(
                ValueError, 'A non-reaction object was used as a reaction!'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list_with_none, species=self.species_list)

        rxn2 = Reaction.from_massaction(inputs=[self.s1],
                                        outputs=[self.s3],
                                        k_forward=0.1)
        # test warning raised if a species (in the reaction outputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning, f'are not part of any reactions in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn2],
                species=self.species_list,
                show_warnings=True)

        rxn3 = Reaction.from_massaction(inputs=[self.s4],
                                        outputs=[self.s2],
                                        k_forward=0.1)
        # test warning raised if a species (in the reaction inputs) is detected which is not part of the species list
        with self.assertWarnsRegex(
                Warning, f'are not part of any reactions in the CRN'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn3],
                species=self.species_list,
                show_warnings=True)

        # test warning if reaction has unlisted species
        rxn4 = Reaction.from_massaction(inputs=[self.s4, self.s3],
                                        outputs=[self.s2],
                                        k_forward=0.1)
        with self.assertWarnsRegex(
                Warning,
                f'are not listed in the Species list, but part of the reactions'
        ):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=[rxn4],
                species=[self.s4, self.s2],
                show_warnings=True)

        # test duplicate reactions are both added
        rxn_list = [self.rx1, self.rx1]

        CRN = ChemicalReactionNetwork(species=[self.s1, self.s2],
                                      reactions=rxn_list)
        self.assertTrue(CRN.reactions.count(self.rx1) == 2)

        with self.assertWarnsRegex(Warning,
                                   'may be duplicated in CRN definitions'):
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list,
                species=self.species_list,
                show_warnings=True)

        # test warning suppression
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            ChemicalReactionNetwork.check_crn_validity(
                reactions=rxn_list,
                species=self.species_list,
                show_warnings=False)

        assert not w