fbergmann / libSEDML

SED-ML library based on libSBML
BSD 2-Clause "Simplified" License
9 stars 12 forks source link

libsedml python bindings overwrite libsbml python functionality #21

Open matthiaskoenig opened 8 years ago

matthiaskoenig commented 8 years ago

Importing libsedml in python overwrites the SBMLDocument.getModel functionality in libsbml, so that the libsbml model cannot be accessed any more. See the attached example code (Ubuntu, x64, libsbml and libsedml build from latest commits with cmake).

from __future__ import print_function

sbml_str = """<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by libAntimony version v2.8.1 on 2016-02-11 15:30 with libSBML version 5.12.1. -->
<sbml xmlns="http://www.sbml.org/sbml/level3/version1/core" level="3" version="1">
  <model id="test" name="test">
    <listOfCompartments>
      <compartment sboTerm="SBO:0000410" id="default_compartment" spatialDimensions="3" size="1" constant="true"/>
    </listOfCompartments>
    <listOfSpecies>
      <species id="S1" compartment="default_compartment" initialConcentration="10" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
      <species id="S2" compartment="default_compartment" initialConcentration="0" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
    </listOfSpecies>
    <listOfParameters>
      <parameter id="k1" value="1" constant="true"/>
    </listOfParameters>
    <listOfReactions>
      <reaction id="J0" reversible="true" fast="false">
        <listOfReactants>
          <speciesReference species="S1" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="S2" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML">
            <apply>
              <times/>
              <ci> k1 </ci>
              <ci> S1 </ci>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
    </listOfReactions>
  </model>
</sbml>
"""

# load doc with libsbml
import libsbml
doc = libsbml.readSBMLFromString(sbml_str)
model = doc.getModel()
print(type(doc))
print(type(model))

print('*' * 80)  # Everything good until here

# importing libsedml overwrites the libsbml.getModel !!!
# suddenly libsedml.Model is returned when calling getModel on doc !
import libsedml

model = doc.getModel()
print(type(doc))
print(type(model))  # <class 'libsedml.Model'> ??

# not even this works any more
model = libsbml.SBMLDocument.getModel(doc)
print(type(model))  # <class 'libsedml.Model'>

print(libsbml.__version__)  # Updated to revision 22780
print(libsedml.getLibSEDMLVersion())  # commit 31d92030c91e21d9db7

Results in

<class 'libsbml.SBMLDocument'>
<class 'libsedml.Model'>
********************************************************************************
<class 'libsbml.SBMLDocument'>
<class 'libsedml.Model'>
<class 'libsedml.Model'>
5.12.1
401

I.e. after importing libsedml I cannot access the libsbml model from an SBMLDocument any more.

fbergmann commented 8 years ago

Can't reproduce this right now, for me this works just fine. Allthough I'm not working on linux right now. I will try and find time on the weekend to look into this. But since it works for me i obviously need more information:

Here is my test session, does something like that work?

D:\Development\build_sedml\bindings\python>c:\Python27_32\python
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import libsbml
>>> doc = libsbml.readSBMLFromFile('/users/fbergmann/documents/sbml models/borisejb.xml')
>>> mod = doc.getModel()
>>> print mod.id
BorisEJB
>>> import libsedml
>>> print mod.id
BorisEJB
>>> print mod.toSBML()
<model id="BorisEJB" name="BorisEJB">
  <annotation>
    <jd2:JDesignerLayout xmlns:jd2="http://www.sys-bio.org/sbml/jd2" 

...
    </reaction>
  </listOfReactions>
</model>
>>>
...
>>> type(mod)
<class 'libsbml.Model'>
>>> print libsbml.getLibSBMLDottedVersion()
5.12.1
>>> print libsedml.getLibSEDMLDottedVersion()
0.4.1
matthiaskoenig commented 8 years ago

Hi Frank, I could just reproduce it on a second computer with similar installation. Is Ubuntu 14.04 LTS, Linux 3.13.0-74-generic (kernel version not identical with first computer).

libsbml installation is via cloning the the libsbml sourceforge repository svn checkout http://svn.code.sf.net/p/sbml/code/trunk $SBMLCODE and building with

cmake -DENABLE_COMP=ON -DENABLE_FBC=ON -DENABLE_LAYOUT=ON -DENABLE_QUAL=ON -DWITH_EXAMPLES=ON -DWITH_PYTHON=ON -DWITH_R=ON ${SVN_DIR}/$SBMLCODE/libsbml
make
make install

followed by exporting the pythonpath.

libsedml via cloning the github repository followed by

cmake -DEXTRA_LIBS="xml2;z;bz2;" -DWITH_EXAMPLES=ON -DWITH_JAVA=ON -DWITH_PYTHON=ON -DWITH_R=ON ${GIT_DIR}/$SEDMLCODE
make
make install

and exporting pythonpath. Always building in the order libsbml -> libsedml.

matthiaskoenig commented 8 years ago

Python version: python 2.7.6 gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 Here the full build logs for libsedml and libsedml (on this computer the build is from 28th January), on the other it is from today, but has the same issue). libsbml.txt libsedml.txt

I just installed in with pip in a clean virtualenv

pip install python-libsbml python-libsedml

and exactly the same issue there.

Everything works fine with libsbml before importing libsedml. Never used libsedml in combination with libsbml before, only separetely, but than never had problems.

After importing libsedml not even basic model things are working after importing libsedml (see test session below similar to yours). The AttributeError: id is mainly how I found this.

>>> import libsbml
>>> doc = libsbml.readSBMLFromFile('/home/mkoenig/git/multiscale-galactose/python/multiscalepy/multiscale/examples/models/demo/Koenig_demo_10.xml')
>>> mod = doc.getModel()
>>> print mod.id
Koenig_demo_10
>>> type(mod)
<class 'libsbml.Model'>
>>> import libsedml
>>> mod.id
'Koenig_demo_10'
>>> mod2 = doc.getModel()
>>> mod2.id
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/libsedml/libsedml.py", line 9657, in <lambda>
    __getattr__ = lambda self, name: _swig_getattr(self, Model, name)
  File "/usr/local/lib/python2.7/site-packages/libsedml/libsedml.py", line 57, in _swig_getattr
    raise AttributeError(name)
AttributeError: id
fbergmann commented 8 years ago

thank you ... the key idea behind the pip question is to have both libsbml and libsedml from pip. Both libraries now include all dependencies, and so there ought to be little chance of symbols clashing.

For now as workaround ... can you just include libsedml first? would that not solve the issue for now?

matthiaskoenig commented 8 years ago

Yes.

import libsedml
import libsbml

is a workaround which solves my issues right now. Thanks.

On Thu, Feb 11, 2016 at 7:04 PM, Frank Bergmann notifications@github.com wrote:

thank you ... the key idea behind the pip question is to have both libsbml and libsedml from pip. Both libraries now include all dependencies, and so there ought to be little chance of symbols clashing.

For now as workaround ... can you just include libsedml first? would that not solve the issue for now?

— Reply to this email directly or view it on GitHub https://github.com/fbergmann/libSEDML/issues/21#issuecomment-182981715.

Matthias König Junior Group Leader LiSym - Systems Medicine of the Liver Humboldt-University Berlin, Institute for Theoretical Biology https://www.livermetabolism.com konigmatt@googlemail.com Tel: +49 30 20938450 Tel: +49 176 81168480

matthiaskoenig commented 8 years ago

Hi Frank,

this is still a major issue, because I am unable to control the import order if a project is not a simple 1 file script. If a module which imports libsbml is loaded before importing libsedml the libsbml python bindings break.

This is a a problem for instance in unit tests, because I have no control over the order in which the test modules are loaded and executed. If unit tests of a module which only depends on libsbml are executed before a unit test which import libsedml than the order is wrong.

Matthias

fbergmann commented 8 years ago

I agree it needs to be sorted, but this is an issue of libSBML. It will be addressed once there is a version of libSBML that separates the xml parsing layer and math layer, but there is literally nothing i can do about at this point.

matthiaskoenig commented 8 years ago

I see. I found a workaround by forcing a libsbml reload everywhere I import libsedml, i.e.

import libsedml
reload(libsbml)

This fixes my unit test issues for now, because I have only very few modules with libsedml imports. M

yannikschaelte commented 4 years ago

Still an issue in November 2019 :) with (pip installed) libsbml 5.18.0 and libsedml 0.4.3, on linux with python 3.7. Importing libsedml before libsbml also no option for me in a more involved project. The suggestion above to reload works if must be. On >=python3.4, use

import importlib
importlib.reload(libsbml)