Skip to content

Commit

Permalink
Merge pull request #247 from jonls/sbml-annotations
Browse files Browse the repository at this point in the history
sbml: Allow access to SBML annotations
  • Loading branch information
jonls committed May 26, 2017
2 parents d721033 + ce9168c commit 196c95b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
9 changes: 7 additions & 2 deletions psamm/datasource/sbml.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class ParseError(Exception):


class _SBMLEntry(object):
"""Base class for compound and reaction entries"""
"""Base class for compound and reaction entries."""

def __init__(self, reader, root):
self._reader = reader
Expand All @@ -107,9 +107,14 @@ def id(self):

@property
def xml_notes(self):
"""Access the entity notes as an XML document fragment"""
"""Access the entity notes as an XML document fragment."""
return self._root.find(self._reader._sbml_tag('notes'))

@property
def xml_annotation(self):
"""Access the entity annotation as an XML document fragment."""
return self._root.find(self._reader._sbml_tag('annotation'))


class SBMLSpeciesEntry(_SBMLEntry, BaseCompoundEntry):
"""Species entry in the SBML file"""
Expand Down
40 changes: 38 additions & 2 deletions psamm/tests/test_datasource_sbml.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,12 +625,23 @@ def setUp(self):
level="3" version="1"
fbc:required="false">
<model id="test_model" name="Test model">
<notes>
<body xmlns="http://www.w3.org/1999/xhtml">
<p>This is model information intended to be seen by humans.</p>
</body>
</notes>
<listOfCompartments>
<compartment id="C_c" name="cell" constant="true"/>
<compartment id="C_b" name="boundary" constant="true"/>
</listOfCompartments>
<listOfSpecies>
<species id="M_Glucose" name="Glucose" compartment="C_c" constant="false" boundaryCondition="false" hasOnlySubstanceUnits="false" fbc:charge="0" fbc:chemicalFormula="C6H12O6"/>
<species id="M_Glucose" metaid="meta_M_Glucose" name="Glucose" compartment="C_c" constant="false" boundaryCondition="false" hasOnlySubstanceUnits="false" fbc:charge="0" fbc:chemicalFormula="C6H12O6">
<notes>
<body xmlns="http://www.w3.org/1999/xhtml">
<p>This is compound information intended to be seen by humans.</p>
</body>
</notes>
</species>
<species id="M_Glucose_6_P" name="Glucose-6-P" compartment="C_c" constant="false" boundaryCondition="false" hasOnlySubstanceUnits="false" fbc:charge="-2" fbc:chemicalFormula="C6H11O9P"/>
<species id="M_H2O" name="H2O" compartment="C_c" constant="false" boundaryCondition="false" hasOnlySubstanceUnits="false" fbc:charge="0" fbc:chemicalFormula="H2O"/>
<species id="M_Phosphate" name="Phosphate" compartment="C_c" constant="false" boundaryCondition="false" hasOnlySubstanceUnits="false" fbc:charge="-2" fbc:chemicalFormula="HO4P"/>
Expand All @@ -642,7 +653,7 @@ def setUp(self):
<parameter constant="true" id="P_upper_default" value="1000"/>
</listOfParameters>
<listOfReactions>
<reaction id="R_G6Pase" reversible="true" fast="false" fbc:lowerFluxBound="P_lower_G6Pase" fbc:upperFluxBound="P_upper_default">
<reaction id="R_G6Pase" metaid="meta_R_G6Pase" reversible="true" fast="false" fbc:lowerFluxBound="P_lower_G6Pase" fbc:upperFluxBound="P_upper_default">
<listOfReactants>
<speciesReference species="M_Glucose" stoichiometry="2" constant="true"/>
<speciesReference species="M_Phosphate" stoichiometry="2" constant="true"/>
Expand All @@ -651,6 +662,23 @@ def setUp(self):
<speciesReference species="M_H2O" stoichiometry="2" constant="true"/>
<speciesReference species="M_Glucose_6_P" stoichiometry="2" constant="true"/>
</listOfProducts>
<notes>
<body xmlns="http://www.w3.org/1999/xhtml">
<p>This is reaction information intended to be seen by humans.</p>
</body>
</notes>
<annotation>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:bqbiol="http://biomodels.net/biology-qualifiers/">
<Description about="#meta_R_G6Pase">
<bqbiol:isVersionOf>
<Bag>
<li resource="http://identifiers.org/ec-code/3.1.3.9"/>
</Bag>
</bqbiol:isVersionOf>
</Description>
</RDF>
</annotation>
</reaction>
<reaction id="R_Biomass" reversible="false" fast="false" fbc:lowerFluxBound="P_lower_zero" fbc:upperFluxBound="P_upper_default">
<listOfReactants>
Expand Down Expand Up @@ -696,13 +724,15 @@ def test_compounds_exist(self):
self.assertFalse(species['M_Glucose'].boundary)
self.assertEqual(species['M_Glucose'].formula, 'C6H12O6')
self.assertEqual(species['M_Glucose'].charge, 0)
self.assertIsNotNone(species['M_Glucose'].xml_notes)

self.assertEqual(species['M_Glucose_6_P'].id, 'M_Glucose_6_P')
self.assertEqual(species['M_Glucose_6_P'].name, 'Glucose-6-P')
self.assertEqual(species['M_Glucose_6_P'].compartment, 'C_c')
self.assertFalse(species['M_Glucose_6_P'].boundary)
self.assertEqual(species['M_Glucose_6_P'].formula, 'C6H11O9P')
self.assertEqual(species['M_Glucose_6_P'].charge, -2)
self.assertIsNone(species['M_Glucose_6_P'].xml_notes)

self.assertEqual(species['M_H2O'].id, 'M_H2O')
self.assertEqual(species['M_H2O'].name, 'H2O')
Expand Down Expand Up @@ -733,6 +763,9 @@ def test_g6pase_reaction_exists(self):
self.assertEqual(reaction.properties['lower_flux'], -10)
self.assertEqual(reaction.properties['upper_flux'], 1000)

self.assertIsNotNone(reaction.xml_notes)
self.assertIsNotNone(reaction.xml_annotation)

def test_biomass_reaction_exists(self):
reader = sbml.SBMLReader(self.doc, ignore_boundary=False)
reaction = reader.get_reaction('R_Biomass')
Expand All @@ -748,6 +781,9 @@ def test_biomass_reaction_exists(self):
self.assertEqual(reaction.properties['lower_flux'], 0)
self.assertEqual(reaction.properties['upper_flux'], 1000)

self.assertIsNone(reaction.xml_notes)
self.assertIsNone(reaction.xml_annotation)

def test_objective_exists(self):
reader = sbml.SBMLReader(self.doc)
objectives = {entry.id: entry for entry in reader.objectives}
Expand Down

0 comments on commit 196c95b

Please sign in to comment.