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)
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)
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_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
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)
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)
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))
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')
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)
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_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)
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)
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)
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)
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)
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_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