1+ #!/usr/bin/env python3
12""" @package amici.sbml_import The python sbml import module for python
23"""
3- #!/usr/bin/env python3
44
55import sympy as sp
66import libsbml as sbml
@@ -31,15 +31,15 @@ class SbmlImporter:
3131
3232 Attributes:
3333
34- check_validity : indicates whether the validity of the SBML document
35- should be checked @type bool
34+ show_sbml_warnings : indicates whether libSBML warnings should be
35+ displayed @type bool
3636
3737 symbols: dict carrying symbolic definitions @type dict
3838
3939 SBMLreader: the libSBML sbml reader [!not storing this will result
4040 in a segfault!]
4141
42- sbml_doc: document carrying the sbml defintion [!not storing this
42+ sbml_doc: document carrying the sbml definition [!not storing this
4343 will result in a segfault!]
4444
4545 sbml: sbml definition [!not storing this will result in a segfault!]
@@ -62,25 +62,25 @@ class SbmlImporter:
6262
6363 compartmentSymbols: compartment ids @type sympy.Matrix
6464
65- compartmentVolume: numeric/symbnolic compartment volumes @type
65+ compartmentVolume: numeric/symbolic compartment volumes @type
6666 sympy.Matrix
6767
68- stoichiometricMatrix: stoichiometrix matrix of the model @type
68+ stoichiometricMatrix: stoichiometric matrix of the model @type
6969 sympy.Matrix
7070
7171 fluxVector: reaction kinetic laws @type sympy.Matrix
7272
7373 """
7474
75- def __init__ (self , SBMLFile , check_validity = True ):
75+ def __init__ (self , SBMLFile , show_sbml_warnings = False ):
7676 """Create a new Model instance.
7777
7878 Arguments:
7979
8080 SBMLFile: Path to SBML file where the model is specified @type string
8181
82- check_validity: Flag indicating whether the validity of the SBML
83- document should be checked @type bool
82+ show_sbml_warnings: indicates whether libSBML warnings should be
83+ displayed @type bool
8484
8585 Returns:
8686 SbmlImporter instance with attached SBML document
@@ -89,7 +89,7 @@ def __init__(self, SBMLFile, check_validity=True):
8989
9090 """
9191
92- self .check_validity = check_validity
92+ self .show_sbml_warnings = show_sbml_warnings
9393
9494 self .loadSBMLFile (SBMLFile )
9595
@@ -123,10 +123,11 @@ def loadSBMLFile(self, SBMLFile):
123123
124124 self .SBMLreader = sbml .SBMLReader ()
125125 self .sbml_doc = self .SBMLreader .readSBML (SBMLFile )
126- self .checkLibSBMLErrors ()
127- # If any of the above calls produces an error, this will be added to
128- # the SBMLError log in the sbml document. Thus, it is sufficient to
129- # check the error log just once after all conversion/validation calls.
126+
127+ # Ensure we got a valid SBML model, otherwise further processing
128+ # might lead to undefined results
129+ self .sbml_doc .validateSBML ()
130+ checkLibSBMLErrors (self .sbml_doc , self .show_sbml_warnings )
130131
131132 # apply several model simplifications that make our life substantially
132133 # easier
@@ -139,45 +140,13 @@ def loadSBMLFile(self, SBMLFile):
139140 getDefaultProperties ()
140141 self .sbml_doc .convert (convertConfig )
141142
142- if self .check_validity :
143- self .sbml_doc .validateSBML ()
144-
145143 # If any of the above calls produces an error, this will be added to
146144 # the SBMLError log in the sbml document. Thus, it is sufficient to
147145 # check the error log just once after all conversion/validation calls.
148- self . checkLibSBMLErrors ()
146+ checkLibSBMLErrors (self . sbml_doc , self . show_sbml_warnings )
149147
150148 self .sbml = self .sbml_doc .getModel ()
151149
152- def checkLibSBMLErrors (self ):
153- """Checks the error log in the current self.sbml_doc
154-
155- Arguments:
156-
157- Returns:
158-
159- Raises:
160- raises SBMLException if errors with severity ERROR or FATAL have
161- occured
162-
163- """
164- num_warning = self .sbml_doc .getNumErrors (sbml .LIBSBML_SEV_WARNING )
165- num_error = self .sbml_doc .getNumErrors (sbml .LIBSBML_SEV_ERROR )
166- num_fatal = self .sbml_doc .getNumErrors (sbml .LIBSBML_SEV_FATAL )
167- if num_warning + num_error + num_fatal :
168- for iError in range (0 , self .sbml_doc .getNumErrors ()):
169- error = self .sbml_doc .getError (iError )
170- # we ignore any info messages for now
171- if error .getSeverity () >= sbml .LIBSBML_SEV_WARNING :
172- category = error .getCategoryAsString ()
173- severity = error .getSeverityAsString ()
174- error_message = error .getMessage ()
175- print (f'libSBML { severity } ({ category } ): { error_message } ' )
176- if num_error + num_fatal :
177- raise SBMLException (
178- 'SBML Document failed to load (see error messages above)'
179- )
180-
181150 def sbml2amici (self ,
182151 modelName ,
183152 output_dir = None ,
@@ -766,11 +735,13 @@ def processObservables(self, observables, sigmas):
766735
767736 if sigmas is None :
768737 sigmas = {}
769- elif len (set (sigmas .keys ()) - set (observables .keys ())):
770- # Ensure no non-existing observableIds have been specified (no problem here, but usually an upstream bug)
771- raise ValueError (f'Sigma provided for an unknown observableId: { set (sigmas .keys ()) - set (observables .keys ())} ' )
772-
773-
738+ else :
739+ # Ensure no non-existing observableIds have been specified
740+ # (no problem here, but usually an upstream bug)
741+ unknown_observables = set (sigmas .keys ()) - set (observables .keys ())
742+ if unknown_observables :
743+ raise ValueError ('Sigma provided for an unknown observableId: '
744+ + str (unknown_observables ))
774745
775746 speciesSyms = self .symbols ['species' ]['identifier' ]
776747
@@ -1101,3 +1072,38 @@ def l2s(inputs):
11011072
11021073 """
11031074 return [str (inp ) for inp in inputs ]
1075+
1076+
1077+ def checkLibSBMLErrors (sbml_doc , show_warnings = False ):
1078+ """Checks the error log in the current self.sbml_doc
1079+
1080+ Arguments:
1081+ sbml_doc: SBML document @type libsbml.SBMLDocument
1082+ show_warnings: display SBML warnings @type bool
1083+
1084+ Returns:
1085+
1086+ Raises:
1087+ raises SBMLException if errors with severity ERROR or FATAL have
1088+ occurred
1089+ """
1090+ num_warning = sbml_doc .getNumErrors (sbml .LIBSBML_SEV_WARNING )
1091+ num_error = sbml_doc .getNumErrors (sbml .LIBSBML_SEV_ERROR )
1092+ num_fatal = sbml_doc .getNumErrors (sbml .LIBSBML_SEV_FATAL )
1093+
1094+ if num_warning + num_error + num_fatal :
1095+ for iError in range (0 , sbml_doc .getNumErrors ()):
1096+ error = sbml_doc .getError (iError )
1097+ # we ignore any info messages for now
1098+ if error .getSeverity () >= sbml .LIBSBML_SEV_ERROR \
1099+ or (show_warnings and
1100+ error .getSeverity () >= sbml .LIBSBML_SEV_WARNING ):
1101+ category = error .getCategoryAsString ()
1102+ severity = error .getSeverityAsString ()
1103+ error_message = error .getMessage ()
1104+ print (f'libSBML { severity } ({ category } ): { error_message } ' )
1105+
1106+ if num_error + num_fatal :
1107+ raise SBMLException (
1108+ 'SBML Document failed to load (see error messages above)'
1109+ )
0 commit comments