def get_reaction(pi_structure=pi_structure, ec='1.1.1.1'): return data_model.Reaction( participants=[ data_model.ReactionParticipant(coefficient=-1, specie=data_model.Specie(structure=atp_structure)), data_model.ReactionParticipant(coefficient=-1, specie=data_model.Specie(structure=h2o_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=adp_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=pi_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=h_structure)), ], cross_references=[ data_model.Resource(namespace='ec-code', id=ec) ])
def setUpClass(cls): cls.cache_dirname = tempfile.mkdtemp() cls.flk = common_schema.CommonSchema(cache_dirname=cls.cache_dirname) cls.q = reaction_kinetics.ReactionKineticsQuery( cache_dirname=cls.cache_dirname, include_variants=True) cls.reaction = data_model.Reaction( participants = [ data_model.ReactionParticipant( specie = data_model.Specie( id = 'Dihydrofolate', structure = 'InChI=1S/C19H21N7O6/c20-19-25-15-14(17(30)26-19)23-11(8-22-15)'+\ '7-21-10-3-1-9(2-4-10)16(29)24-12(18(31)32)5-6-13(27)28/h1-4,12,21H,5-8H2,'+\ '(H,24,29)(H,27,28)(H,31,32)(H4,20,22,25,26,30)'), coefficient = -1), data_model.ReactionParticipant( specie = data_model.Specie( id = 'NADPH', structure = 'InChI=1S/C21H30N7O17P3/c22-17-12-19(25-7-24-17)28(8-26-12)21-16'+\ '(44-46(33,34)35)14(30)11(43-21)6-41-48(38,39)45-47(36,37)40-5-10-13(29)15(31)'+\ '20(42-10)27-3-1-2-9(4-27)18(23)32/h1,3-4,7-8,10-11,13-16,20-21,29-31H,2,5-6H2,'+\ '(H2,23,32)(H,36,37)(H,38,39)(H2,22,24,25)(H2,33,34,35)'), coefficient = -1), data_model.ReactionParticipant( specie = data_model.Specie( id = 'H+', structure = 'InChI=1S/H'), coefficient = -1), data_model.ReactionParticipant( specie = data_model.Specie( id = 'NADP+', structure = 'InChI=1S/C21H28N7O17P3/c22-17-12-19(25-7-24-17)28(8-26-12)21-16('+\ '44-46(33,34)35)14(30)11(43-21)6-41-48(38,39)45-47(36,37)40-5-10-13(29)15(31)20'+\ '(42-10)27-3-1-2-9(4-27)18(23)32/h1-4,7-8,10-11,13-16,20-21,29-31H,5-6H2,(H7-,22'+\ ',23,24,25,32,33,34,35,36,37,38,39)/p+1'), coefficient = 1), data_model.ReactionParticipant( specie = data_model.Specie( id = '5,6,7,8-Tetrahydrofolate', structure = 'InChI=1S/C19H23N7O6/c20-19-25-15-14(17(30)26-19)23-11(8-22-15)7-21-'+\ '10-3-1-9(2-4-10)16(29)24-12(18(31)32)5-6-13(27)28/h1-4,11-12,21,23H,5-8H2,(H,24,29'+\ ')(H,27,28)(H,31,32)(H4,20,22,25,26,30)'), coefficient = 1) ])
def test_normalize(self): rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant( specie=data_model.Specie(structure=self.atp, id='atp'), compartment=data_model.Compartment(id='c'), coefficient=-1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.atp, id='atp'), compartment=data_model.Compartment(id='c'), coefficient=-1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.atp, id='atp'), compartment=data_model.Compartment(id='c'), coefficient=1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.atp, id='atp'), compartment=data_model.Compartment(id='c'), coefficient=0), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.atp, id='atp'), compartment=data_model.Compartment(id='e'), coefficient=-1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.adp, id='adp'), compartment=data_model.Compartment(id='c'), coefficient=1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.adp, id='adp'), compartment=data_model.Compartment(id='c'), coefficient=3), ]) ordered_participants = rxn.get_ordered_participants() self.assertEqual(len(ordered_participants), 4) part = list( filter( lambda p: p.specie.id == 'atp' and p.compartment.id == 'c' and p.coefficient < 0, ordered_participants)) self.assertEqual(len(part), 1) self.assertEqual(part[0].coefficient, -2) part = list( filter( lambda p: p.specie.id == 'atp' and p.compartment.id == 'c' and p.coefficient > 0, ordered_participants)) self.assertEqual(len(part), 1) self.assertEqual(part[0].coefficient, 1) part = list( filter(lambda p: p.specie.id == 'atp' and p.compartment.id == 'e', ordered_participants)) self.assertEqual(len(part), 1) self.assertEqual(part[0].coefficient, -1) part = list( filter(lambda p: p.specie.id == 'adp', ordered_participants)) self.assertEqual(len(part), 1) self.assertEqual(part[0].coefficient, 4)
def make_reaction(self): return data_model.Reaction(participants=[ data_model.ReactionParticipant( specie=data_model.Specie(structure=self.atp, id='atp'), compartment=data_model.Compartment(id='c'), coefficient=-1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.h2o, id='h2o'), compartment=data_model.Compartment(id='c'), coefficient=-1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.adp, id='adp'), compartment=data_model.Compartment(id='c'), coefficient=1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.pi, id='pi'), compartment=data_model.Compartment(id='c'), coefficient=1), data_model.ReactionParticipant( specie=data_model.Specie(structure=self.h, id='h'), compartment=data_model.Compartment(id='c'), coefficient=1), ])
def get_reaction(ntp=atp, glc=glc): return data_model.Reaction( participants=[ data_model.ReactionParticipant(coefficient=-1, specie=ntp), data_model.ReactionParticipant(coefficient=-1, specie=h2o), data_model.ReactionParticipant(coefficient=1, specie=adp), data_model.ReactionParticipant(coefficient=1, specie=pi), data_model.ReactionParticipant(coefficient=1, specie=h), data_model.ReactionParticipant(coefficient=0, specie=glc), ])
def parse_participants(side, coefficient, reaction, errors): for participant in side.split(' + '): participant = participant.strip() pubchem_compounds = pubchempy.get_compounds(participant, 'name') if len(pubchem_compounds) == 1: structure = pubchem_compounds[0].inchi elif molecule_util.Molecule(structure=participant).get_format(): structure = participant else: structure = '' errors.append(participant) reaction.participants.append(data_model.ReactionParticipant( specie=data_model.Specie(structure=structure), coefficient=coefficient, ))
def _port(self, reaction_list): """ Converts SQL model reaction into a Obj Model based data_model reaction Args: reaction_list :obj:`list` of :obj:`models.Reaction`:): list of reaction participants Returns: :obj:`data_model.Reaction`: a cohesive reaction data object """ references = [] participants = [] for rxn_part in reaction_list: if rxn_part._is_reactant: coef = -1 elif rxn_part._is_product: coef = 1 elif rxn_part._is_modifier: coef = 0 part = data_model.ReactionParticipant(specie=data_model.Specie( name=rxn_part.metabolite.metabolite_name, structure=rxn_part.metabolite.structure._value_inchi if rxn_part.metabolite.structure else None), coefficient=coef) participants.append(part) if len(references) < 1: for item in rxn_part.kinetic_law._metadata.resource: references.append( data_model.Resource(namespace=item.namespace, id=item._id, assignment_method=data_model. ResourceAssignmentMethod.manual)) rxn = data_model.Reaction( participants=participants, cross_references=references, kinetic_law_id=reaction_list[0].kinetic_law_id) rxn.name = rxn.stringify() return rxn
def test_run(self): rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['atp'], id='atp'), compartment=data_model.Compartment( id='c'), coefficient=-1, order=0), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['h2o'], id='h2o'), compartment=data_model.Compartment( id='c'), coefficient=-1, order=1), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['adp'], id='adp'), compartment=data_model.Compartment( id='c'), coefficient=1, order=2), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['ppi'], id='ppi'), compartment=data_model.Compartment( id='c'), coefficient=1, order=3), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['h'], id='h'), compartment=data_model.Compartment( id='c'), coefficient=1, order=4), ]) self.assertEqual(rxn.get_reactants()[0].specie.id, 'atp') self.assertEqual(rxn.get_products()[0].specie.id, 'adp') self.assertEqual(rxn.get_reactant_product_pairs()[0][0].specie.id, 'atp') self.assertEqual(rxn.get_reactant_product_pairs()[0][1].specie.id, 'adp') self.assertEqual(rxn.get_reactant_product_pairs()[1][0].specie.id, 'h2o') self.assertEqual(rxn.get_reactant_product_pairs()[1][1].specie.id, 'ppi') result = ezyme.Ezyme().run(rxn) print(result) self.assertEqual(result[0].ec_number, '3.6.1') # true EC is 3.6.1.3 # example where Ezyme predicts no EC number when the order is swapped rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['t3p1'], id='atp'), coefficient=-1, order=0), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['s7p'], id='h2o'), coefficient=-1, order=1), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['x5p'], id='adp'), coefficient=1, order=2), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['r5p'], id='ppi'), coefficient=1, order=3), ]) result = ezyme.Ezyme().run(rxn) self.assertEqual(result[0].ec_number, "4.1.2") # true EC is 2.2.1.1 self.assertEqual(result[1].ec_number, "2.2.1") rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['s7p'], id='atp'), coefficient=-1, order=0), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['t3p1'], id='h2o'), coefficient=-1, order=1), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['x5p'], id='adp'), coefficient=1, order=2), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['r5p'], id='ppi'), coefficient=1, order=3), ]) result = ezyme.Ezyme().run(rxn) self.assertEqual(result, []) # example where Ezyme predicts different EC numbers when the order is swapped rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['e1dGMP'], id='atp'), coefficient=-1, order=0), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['h2o'], id='h2o'), coefficient=-1, order=1), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['e1dG'], id='adp'), coefficient=1, order=2), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['pi'], id='ppi'), coefficient=1, order=3), ]) result = ezyme.Ezyme().run(rxn) self.assertEqual(result[0].ec_number, "3.1.3") # true EC is 3.1.3.89 rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['h2o'], id='atp'), coefficient=-1, order=1), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['e1dGMP'], id='h2o'), coefficient=-1, order=0), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['e1dG'], id='adp'), coefficient=1, order=2), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['pi'], id='ppi'), coefficient=1, order=3), ]) result = ezyme.Ezyme().run(rxn) self.assertEqual(result[0].ec_number, "3.1.3") # true EC is 3.1.3.89 # example where a structure is not defined rxn = data_model.Reaction(participants=[ data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['h2o'], id='atp'), coefficient=-1, order=1), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['e1dGMP'], id='h2o'), coefficient=-1, order=0), data_model.ReactionParticipant(specie=data_model.Specie( structure=self.molecules['e1dG'], id='adp'), coefficient=1, order=2), data_model.ReactionParticipant(specie=data_model.Specie( structure='', id='ppi'), coefficient=1, order=3), ]) result = ezyme.Ezyme().run(rxn) self.assertEqual(result, None)
def get_observed_result(self, reaction): """ Find observed kinetics for the reaction or similar reactions TODO: Add compartment infomrmation 1. Find kinetics observed for the reaction a. Find the metabolite(s) of each participant b. Find the reaction(s) which contain all of these metabolites c. Find the kinetic laws associated with these reactions 2. Find kinetics observed for similar reactions a. Find kinetics observed for the assigned EC number(s) b. Find kinetics observed for EC number(s) predicted by tools such as E-zyme Args: reaction (:obj:`data_model.Reaction`): reaction to find data for Returns: :obj:`list` of :obj:`data_model.ObservedValue`: list of relevant observed values """ q_law = self.get_kinetic_laws_by_reaction(reaction) observed_vals = [] for law in q_law: common_schema_reaction_id = next(xr._id for xr in law._metadata.resource if xr.namespace == 'sabiork.reaction') reaction = data_model.Reaction( cross_references=[ data_model.Resource(namespace='common_schema.kinetic_law_id', id=str(law.kinetic_law_id)), data_model.Resource(namespace='sabiork.reaction', id=common_schema_reaction_id), ], ) species = {} compartments = {} cs_rxn = self.data_source.session.query(models.Reaction).filter_by(kinetic_law_id = law.kinetic_law_id) reactants = cs_rxn.filter_by(_is_reactant = True).all() products = cs_rxn.filter_by(_is_product = True).all() modifiers = cs_rxn.filter_by(_is_modifier = True).all() for reactant in reactants: part = data_model.ReactionParticipant(coefficient=-1) if reactant.metabolite_id not in species: species[reactant.metabolite_id] = data_model.Specie(name=reactant.metabolite.metabolite_name) part.specie = species[reactant.metabolite_id] if reactant.metabolite.structure_id: part.specie.structure = reactant.metabolite.structure._value_inchi if reactant.compartment_id: if reactant.compartment.name not in compartments: compartments[reactant.compartment.name] = data_model.Compartment(name=reactant.compartment.name) part.compartment = compartments[reactant.compartment.name] reaction.participants.append(part) for product in products: part = data_model.ReactionParticipant(coefficient=1) if product.metabolite_id not in species: species[product.metabolite_id] = data_model.Specie(name=product.metabolite.metabolite_name) part.specie = species[product.metabolite_id] if product.metabolite.structure_id: part.specie.structure = product.metabolite.structure._value_inchi if product.compartment_id: if product.compartment.name not in compartments: compartments[product.compartment.name] = data_model.Compartment(name=product.compartment.name) part.compartment = compartments[product.compartment.name] reaction.participants.append(part) for modifier in modifiers: part = data_model.ReactionParticipant(coefficient=0) if modifier.metabolite_id not in species: species[modifier.metabolite_id] = data_model.Specie(name=modifier.metabolite.metabolite_name) part.specie = species[modifier.metabolite_id] if modifier.metabolite.structure_id: part.specie.structure = modifier.metabolite.structure._value_inchi if modifier.compartment_id: if modifier.compartment.name not in compartments: compartments[modifier.compartment.name] = data_model.Compartment(name=modifier.compartment.name) part.compartment = compartments[modifier.compartment.name] reaction.participants.append(part) metadata = self.metadata_dump(law) for parameter in law.parameter: if parameter.value is None: continue observable = data_model.Observable( interaction=reaction, property=parameter.observed_name, ) if parameter.metabolite_id: observable.specie = species[parameter.metabolite_id] # if parameter.compartment: # observable.compartment = data_model.Compartment( # id=parameter.compartment.name, # ) observed_vals.append(data_model.ObservedValue( metadata=metadata, observable=observable, value=parameter.value, error=parameter.error, units=parameter.units, )) return observed_vals
def test_ReactionSimilarityFilter(self): atp_structure = ( 'InChI=1S/C10H16N5O13P3/c11-8-5-9(13-2-12-8)15(3-14-5)10-7(17)6(16)4(26-10)1-25-30(21,22)28-31(23,24)27-29(18,19)20' '/h2-4,6-7,10,16-17H,1H2,(H,21,22)(H,23,24)(H2,11,12,13)(H2,18,19,20)/p-4/t4-,6-,7-,10-/m1/s1' ) h2o_structure = 'InChI=1S/H2O/h1H2' adp_structure = ( 'InChI=1S/C10H15N5O10P2/c11-8-5-9(13-2-12-8)15(3-14-5)10-7(17)6(16)4(24-10)1-23-27(21,22)25-26(18,19)20' '/h2-4,6-7,10,16-17H,1H2,(H,21,22)(H2,11,12,13)(H2,18,19,20)/p-3/t4-,6-,7-,10-/m1/s1' ) pi_structure = 'InChI=1S/H3O4P/c1-5(2,3)4/h(H3,1,2,3,4)/p-2' h_structure = 'InChI=1S/p+1/i/hH' def get_reaction(pi_structure=pi_structure, ec='1.1.1.1'): return data_model.Reaction( participants=[ data_model.ReactionParticipant(coefficient=-1, specie=data_model.Specie(structure=atp_structure)), data_model.ReactionParticipant(coefficient=-1, specie=data_model.Specie(structure=h2o_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=adp_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=pi_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=h_structure)), ], cross_references=[ data_model.Resource(namespace='ec-code', id=ec) ]) rxn = get_reaction() f = data_query.ReactionSimilarityFilter(min_ec_level=3, scale=1) # same participants ov = data_model.ObservedValue(observable=data_model.Observable(interaction=get_reaction())) numpy.testing.assert_almost_equal(f.score(rxn, ov), 1, decimal=3) # similiar participants ov = data_model.ObservedValue(observable=data_model.Observable(interaction=get_reaction(pi_structure='InChI=1S/H3O4P/c1-5(2,3)4'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), 1, decimal=3) # different participants, same 4-digit EC ov = data_model.ObservedValue(observable=data_model.Observable(interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), math.exp(-1), decimal=3) # different participants, same 3-digit EC ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.1.2'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), math.exp(-2), decimal=3) ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.1'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), math.exp(-2), decimal=3) ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.1.'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), math.exp(-2), decimal=3) ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.1.-'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), math.exp(-2), decimal=3) # different participants, same 2-digit EC ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.2.1'))) numpy.testing.assert_almost_equal(f.score(rxn, ov), -1, decimal=3) # target reaction only has 3 digits rxn_1_1_1 = get_reaction(ec='1.1.1') rxn_1_1_1_1 = get_reaction(ec='1.1.1.1') f1 = data_query.ReactionSimilarityFilter(min_ec_level=3, scale=1) f2 = data_query.ReactionSimilarityFilter(min_ec_level=3, scale=1) ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.1'))) numpy.testing.assert_almost_equal(f1.score(rxn_1_1_1, ov), math.exp(-2), decimal=3) numpy.testing.assert_almost_equal(f2.score(rxn_1_1_1_1, ov), math.exp(-2), decimal=3) ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.1.1'))) numpy.testing.assert_almost_equal(f1.score(rxn_1_1_1, ov), math.exp(-2), decimal=3) numpy.testing.assert_almost_equal(f2.score(rxn_1_1_1_1, ov), math.exp(-1), decimal=3) ov = data_model.ObservedValue(observable=data_model.Observable( interaction=get_reaction(pi_structure='InChI=1S/H4O4P/c1-5(2,3)4', ec='1.1.2.1'))) numpy.testing.assert_almost_equal(f1.score(rxn_1_1_1, ov), -1, decimal=3) numpy.testing.assert_almost_equal(f2.score(rxn_1_1_1_1, ov), -1, decimal=3) # reverse direction, different numbers of reactants/products f = data_query.ReactionSimilarityFilter(min_ec_level=3, scale=1) for_rxn = get_reaction() rev_rxn = get_reaction() for part in rev_rxn.participants: part.coefficient = -1 * part.coefficient ov = data_model.ObservedValue(observable=data_model.Observable(interaction=for_rxn)) self.assertEqual(f.score(for_rxn, ov), 1.) ov = data_model.ObservedValue(observable=data_model.Observable(interaction=rev_rxn)) self.assertEqual(f.score(for_rxn, ov), -1.) # reverse direction, same numbers of reactants/products for_rxn = data_model.Reaction( participants=[ data_model.ReactionParticipant(coefficient=-1, specie=data_model.Specie(structure=atp_structure)), data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=adp_structure)), ], cross_references=[ data_model.Resource(namespace='ec-code', id='1.1.1.1') ]) rev_rxn = data_model.Reaction( participants=[ data_model.ReactionParticipant(coefficient=1, specie=data_model.Specie(structure=atp_structure)), data_model.ReactionParticipant(coefficient=-1, specie=data_model.Specie(structure=adp_structure)), ], cross_references=[ data_model.Resource(namespace='ec-code', id='1.1.1.1') ]) ov = data_model.ObservedValue(observable=data_model.Observable(interaction=for_rxn)) self.assertEqual(f.score(for_rxn, ov), 1.) ov = data_model.ObservedValue(observable=data_model.Observable(interaction=rev_rxn)) self.assertEqual(f.score(for_rxn, ov), -1.)
def parse_reaction_equation(self, equation, compartments, species): """ Parse a reaction equation, e.g. * [c]: ATP + H2O ==> ADP + PI + H * GLC[e] + ATP[c] + H2O[c] ==> GLC[c] + ADP[c] + PI[c] + H[c] Args: equation (:obj:`str`): reaction equation compartments (:obj:`list` of :obj:`data_model.Compartment`): list of compartments species (:obj:`list` of :obj:`data_model.Specie`): list of species Returns: :obj:`data_model.Reaction`: reaction """ compartments_dict = {c.id: c for c in compartments} species_dict = {s.id: s for s in species} global_comp = r'\[(?P<comp>[a-z0-9_]+)\]: *' global_part = r' *(([0-9\.]+) )?([a-z0-9_]+)' global_lhs = r'(?P<lhs>{}( *\+ *{})*)'.format(global_part, global_part) global_rhs = r'(?P<rhs>{}( *\+ *{})*)'.format(global_part, global_part) local_part = r' *(([0-9\.]+) )?([a-z0-9_]+)\[([a-z0-9_]+)\]' local_lhs = r'(?P<lhs>{}( *\+ *{})*)'.format(local_part, local_part) local_rhs = r'(?P<rhs>{}( *\+ *{})*)'.format(local_part, local_part) sep = r' *(?P<sep><{0,1})[-=]{1,2}> *' global_pattern = global_comp + global_lhs + sep + global_rhs local_pattern = local_lhs + sep + local_rhs global_match = re.match(global_pattern, equation.rstrip(), re.IGNORECASE) local_match = re.match(local_pattern, equation.rstrip(), re.IGNORECASE) if global_match: global_comp = global_match.groupdict()['comp'] sep = global_match.groupdict()['sep'] lhs = global_match.groupdict()['lhs'] rhs = global_match.groupdict()['rhs'] participants = [] for part in re.findall(global_part, lhs, re.IGNORECASE): participants.append( data_model.ReactionParticipant( specie=species_dict[part[2]], compartment=compartments_dict[global_comp], coefficient=-float(part[0][0:-1] or 1.), )) for part in re.findall(global_part, rhs, re.IGNORECASE): participants.append( data_model.ReactionParticipant( specie=species_dict[part[2]], compartment=compartments_dict[global_comp], coefficient=float(part[0][0:-1] or 1.), )) elif local_match: sep = local_match.groupdict()['sep'] lhs = local_match.groupdict()['lhs'] rhs = local_match.groupdict()['rhs'] participants = [] for part in re.findall(local_part, lhs, re.IGNORECASE): participants.append( data_model.ReactionParticipant( specie=species_dict[part[2]], compartment=compartments_dict[part[3]], coefficient=-float(part[0][0:-1] or 1.), )) for part in re.findall(local_part, rhs, re.IGNORECASE): participants.append( data_model.ReactionParticipant( specie=species_dict[part[2]], compartment=compartments_dict[part[3]], coefficient=float(part[0][0:-1] or 1.), )) else: raise ValueError('Reaction is not parseable: {}'.format(equation)) # save specified participant order for i_part, part in enumerate(participants): part.order = i_part return data_model.Reaction(participants=participants, reversible=sep == '<')
def test_parse_reaction_equation(self): c = data_model.Compartment(id='c') e = data_model.Compartment(id='e') compartments = [c, e] Complex_Acp = data_model.Specie(id='Complex_Acp') ATP = data_model.Specie(id='ATP') HDCA = data_model.Specie(id='HDCA') PPI = data_model.Specie(id='PPI') AMP = data_model.Specie(id='AMP') Complex_Acp_hdc = data_model.Specie(id='Complex_Acp_hdc') A = data_model.Specie(id='A') B2 = data_model.Specie(id='B2') B_2 = data_model.Specie(id='B_2') C = data_model.Specie(id='C') D = data_model.Specie(id='D') E = data_model.Specie(id='E') F = data_model.Specie(id='F') species = [ Complex_Acp, ATP, HDCA, PPI, AMP, Complex_Acp_hdc, A, B2, B_2, C, D, E, F, ] eq = "[c]: Complex_Acp + ATP + HDCA ==> PPI + AMP + Complex_Acp_hdc" response = io.InputReader().parse_reaction_equation(eq, compartments, species) expected_answer = data_model.Reaction( participants=[ data_model.ReactionParticipant(specie=Complex_Acp, compartment=c, coefficient=-1, order=0), data_model.ReactionParticipant(specie=ATP, compartment=c, coefficient=-1, order=1), data_model.ReactionParticipant(specie=HDCA, compartment=c, coefficient=-1, order=2), data_model.ReactionParticipant(specie=PPI, compartment=c, coefficient=1, order=3), data_model.ReactionParticipant(specie=AMP, compartment=c, coefficient=1, order=4), data_model.ReactionParticipant(specie=Complex_Acp_hdc, compartment=c, coefficient=1, order=5), ], reversible=False, ) self.assertTrue(self.are_reactions_equal(response, expected_answer)) eq = "A[c] + B2[e] + 2 C[c] ==> 2.5 D[c] + E[c] + F[c]" response = io.InputReader().parse_reaction_equation(eq, compartments, species) expected_answer = data_model.Reaction( participants=[ data_model.ReactionParticipant(specie=A, compartment=c, coefficient=-1., order=0), data_model.ReactionParticipant(specie=B2, compartment=e, coefficient=-1., order=1), data_model.ReactionParticipant(specie=C, compartment=c, coefficient=-2., order=2), data_model.ReactionParticipant(specie=D, compartment=c, coefficient=2.5, order=3), data_model.ReactionParticipant(specie=E, compartment=c, coefficient=1., order=4), data_model.ReactionParticipant(specie=F, compartment=c, coefficient=1., order=5), ], reversible=False, ) self.assertTrue(self.are_reactions_equal(response, expected_answer)) eq = "A[c]+B_2[e]+2 C[c]<==>2.5 D[c] + E[c] + F[c]" response = io.InputReader().parse_reaction_equation(eq, compartments, species) expected_answer = data_model.Reaction( participants=[ data_model.ReactionParticipant(specie=A, compartment=c, coefficient=-1., order=0), data_model.ReactionParticipant(specie=B_2, compartment=e, coefficient=-1., order=1), data_model.ReactionParticipant(specie=C, compartment=c, coefficient=-2., order=2), data_model.ReactionParticipant(specie=D, compartment=c, coefficient=2.5, order=3), data_model.ReactionParticipant(specie=E, compartment=c, coefficient=1., order=4), data_model.ReactionParticipant(specie=F, compartment=c, coefficient=1., order=5), ], reversible=True, ) self.assertTrue(self.are_reactions_equal(response, expected_answer)) # alternative separators expected_answer = data_model.Reaction( participants=[ data_model.ReactionParticipant(specie=A, compartment=c, coefficient=-1., order=0), data_model.ReactionParticipant(specie=B2, compartment=e, coefficient=-1., order=1), data_model.ReactionParticipant(specie=C, compartment=c, coefficient=-2., order=2), data_model.ReactionParticipant(specie=D, compartment=c, coefficient=2.5, order=3), data_model.ReactionParticipant(specie=E, compartment=c, coefficient=1., order=4), data_model.ReactionParticipant(specie=F, compartment=c, coefficient=1., order=5), ], reversible=False, ) eq = "A[c] + B2[e] + 2 C[c] ==> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) eq = "A[c] + B2[e] + 2 C[c] => 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) eq = "A[c] + B2[e] + 2 C[c] --> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) eq = "A[c] + B2[e] + 2 C[c] -> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) expected_answer = data_model.Reaction( participants=[ data_model.ReactionParticipant(specie=A, compartment=c, coefficient=-1., order=0), data_model.ReactionParticipant(specie=B2, compartment=e, coefficient=-1., order=1), data_model.ReactionParticipant(specie=C, compartment=c, coefficient=-2., order=2), data_model.ReactionParticipant(specie=D, compartment=c, coefficient=2.5, order=3), data_model.ReactionParticipant(specie=E, compartment=c, coefficient=1., order=4), data_model.ReactionParticipant(specie=F, compartment=c, coefficient=1., order=5), ], reversible=True, ) eq = "A[c] + B2[e] + 2 C[c] <==> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) eq = "A[c] + B2[e] + 2 C[c] <=> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) eq = "A[c] + B2[e] + 2 C[c] <--> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) eq = "A[c] + B2[e] + 2 C[c] <-> 2.5 D[c] + E[c] + F[c]" self.are_reactions_equal(io.InputReader().parse_reaction_equation(eq, compartments, species), expected_answer) # negative examples eq = "[c]: A[c] + B2[e] + 2 C[c] ==> 2.5 D[c] + E[c] + F[c]" self.assertRaises(ValueError, io.InputReader().parse_reaction_equation, eq, compartments, species) eq = "[c]: A + B2 + 2 C[c] ==> 2.5 D + E + F" self.assertRaises(ValueError, io.InputReader().parse_reaction_equation, eq, compartments, species) eq = "A + B2 + 2 C[c] ==> 2.5 D + E + F" self.assertRaises(ValueError, io.InputReader().parse_reaction_equation, eq, compartments, species) eq = "A[c] + B-2[e] + 2 C[c] ==> 2.5 D[c] + E[c] + F[c]" self.assertRaises(ValueError, io.InputReader().parse_reaction_equation, eq, compartments, species) eq = "A[c] + B2[e] + 2 C[c] ===> 2.5 D[c] + E[c] + F[c]" self.assertRaises(ValueError, io.InputReader().parse_reaction_equation, eq, compartments, species) eq = "A[c] + B2[e] + 2 C[c] ---> 2.5 D[c] + E[c] + F[c]" self.assertRaises(ValueError, io.InputReader().parse_reaction_equation, eq, compartments, species)