Open CiaranWelsh opened 4 years ago
I've added a method to SBMLLayout
to convert to level 3 version 1:
def _convertToLatestSBML(self):
"""
Convert `doc` to latest sbml version
if it is not already
Args:
doc: sbml document
Returns: sbml document
"""
latestLevel = self._doc.getDefaultLevel()
latestVersion = self._doc.getDefaultVersion()
self._doc.setLevelAndVersion(3, 1)
return self._doc
However I still get the same error.
Error
Traceback (most recent call last):
File "C:\Miniconda3\envs\testing-libsbml-draw\lib\unittest\case.py", line 59, in testPartExecutor
yield
File "C:\Miniconda3\envs\testing-libsbml-draw\lib\unittest\case.py", line 628, in run
testMethod()
File "D:\libsbml-draw\tests\test_working_with_biomodels.py", line 78, in test_save_sbml_to_file
self.sl.writeSBMLFile(self.sbml_layout_fname)
File "D:\libsbml-draw\src\python\libsbml_draw\layout.py", line 825, in writeSBMLFile
This level {level} version {version} document has no layout information.""") # noqa
Exception: Cannot write file.
This level 3 version 1 document has no layout information.
Note this is a custom error in writeSBMLFile which checks that the number of species glyphs is > 0.
def writeSBMLFile(self, out_file_name):
"""Writes the model as an SBML file.
Args:
out_file_name (str): name of the file to write
Returns: None
"""
level = self._doc.getLevel()
version = self._doc.getVersion()
layout_number = self._layout_number
layout_plugin = self._doc.getModel().getPlugin("layout")
if not layout_plugin:
raise ValueError('Could not find layout plugin')
if layout_plugin.getNumLayouts() > 0:
layout = layout_plugin.getLayout(layout_number)
else:
raise ValueError('No layouts in your sbml model')
if layout.getNumSpeciesGlyphs() == 0:
raise ValueError(f"""Cannot write file.
This level {level} version {version} document has no layout information.""") # noqa
self._addRenderInformation()
print(layout.getNumSpeciesGlyphs())
libsbml.writeSBML(self._doc, out_file_name)
This implies that no layout information was ever added to the model. I don't know the functions, but your script implies that some should have been added either with the construction of the SBMLLayout(fname) line or (less likely) in the 'drawNetwork' function. It also implies that the .png was indeed created: can you look at it? Is it blank?
Yes, I think your right in all accounts. The png is created and is what you would expect. The layout information is generated but apparently isn't being updated (perhaps). I've checked that lisbml can do this, which it can, so the problem is somewhere in libsbml-draw. Will keep digging.
One thing that you might find helpful is that libsbml will return error codes when it fails to do something, and the error code is usually a hint about what went wrong. I have seen (and written) a lot of code that doesn't check the codes at all, but here you might find it helpful. If (say) you have a 'model.addLayout(layoutobj)' line, you can change it from:
model.addLayout(obj)
to
code = model.addLayout(obj) assert(code == libsbml.LIBSBML_OPERATION_SUCCESS) #Or however you write this in Python; this is a guess.
The underlying C++ package has methods for writing to sbml but the libsbml-draw does not use them for writing, instead preferring libsbml directly. I suspect this is why we are having the issue with missing render/layout information when we save to file. Specifically, in sbnw these methods are between lines 2171 and 2210 in layout.h.
To use these other methods we need to extend the c api using ctypes. I have begun this process on the develop branch lines 148-180 and the corresponding test (begins on line 75).
The throws returns the following error:
Error
Traceback (most recent call last):
File "C:\Miniconda3\envs\py37\lib\unittest\case.py", line 59, in testPartExecutor
yield
File "C:\Miniconda3\envs\py37\lib\unittest\case.py", line 628, in run
testMethod()
File "D:\libsbml-draw\tests\test_working_with_biomodels.py", line 87, in test_new_write_to_sbml
self.sl.writeSBML(self.sbml_layout_fname)
File "D:\libsbml-draw\src\python\libsbml_draw\layout.py", line 784, in writeSBML
return sbnw.writeSBMLwithLayout(filename, self._h_model, self._h_layout_info)
File "D:\libsbml-draw\src\python\libsbml_draw\sbnw.py", line 180, in writeSBMLwithLayout
return slib.gf_writeSBMLwithLayout(filename, model, layout)
Exception: argument 1: <class 'TypeError'>: wrong type
-------------------- >> begin captured logging << --------------------
matplotlib: DEBUG: CACHEDIR=C:\Users\cwelsh\.matplotlib
matplotlib.font_manager: DEBUG: Using fontManager instance from C:\Users\cwelsh\.matplotlib\fontlist-v310.json
matplotlib.pyplot: DEBUG: Loaded backend module://backend_interagg version unknown.
urllib3.connectionpool: DEBUG: Starting new HTTPS connection (1): www.ebi.ac.uk:443
urllib3.connectionpool: DEBUG: https://www.ebi.ac.uk:443 "GET /biomodels-main/download?mid=BIOMD0000000091 HTTP/1.1" 200 None
--------------------- >> end captured logging << ---------------------
So there is a type mismatch somewhere, which sounds like it should be easy to fix. However, nothing I have tried has worked so far.
Fails with: