AMICI-dev / AMICI

Advanced Multilanguage Interface to CVODES and IDAS
https://amici.readthedocs.io/
Other
109 stars 31 forks source link

AMICI cannot be imported twice in different modules #1369

Closed jonrkarr closed 3 years ago

jonrkarr commented 3 years ago

What did you expect to happen? Be able to import AMICI arbitrarily many times

What has happened instead? It appears all code that uses AMICI has to be put in a single module, which is a strong limitation.

To Reproduce

  1. Import AMICI in a module
  2. Import another module which imports AMICI
  3. Second module imports SBML model
  4. This generates the error below
    constant_parameters=constant_parameters)
/usr/local/lib/python3.7/site-packages/amici/sbml_import.py:339: in sbml2amici
    self._process_sbml(constant_parameters)
/usr/local/lib/python3.7/site-packages/amici/logging.py:194: in wrapper_timer
    rval = func(*args, **kwargs)
/usr/local/lib/python3.7/site-packages/amici/sbml_import.py:380: in _process_sbml
    self._gather_locals()
/usr/local/lib/python3.7/site-packages/amici/logging.py:194: in wrapper_timer
    rval = func(*args, **kwargs)
/usr/local/lib/python3.7/site-packages/amici/sbml_import.py:432: in _gather_locals
    self._gather_base_locals()
/usr/local/lib/python3.7/site-packages/amici/sbml_import.py:463: in _gather_base_locals
    for x_ref in _get_list_of_species_references(self.sbml):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

sbml_model = <Model BIOMD0000000002 "Edelstein1996 - EPSP ACh species">

    def _get_list_of_species_references(sbml_model: sbml.Model) \
            -> List[sbml.SpeciesReference]:
        """
        Extracts list of species references as SBML doesn't provide a native
        function for this.

        :param sbml_model:
            SBML model instance

        :return:
            ListOfSpeciesReferences
        """
        return [
            reference
>           for element in sbml_model.all_elements
            if isinstance(element, sbml.ListOfSpeciesReferences)
            for reference in element
        ]
E       TypeError: 'SBaseList' object is not iterable

/usr/local/lib/python3.7/site-packages/amici/sbml_import.py:1833: TypeError

AMICI version and system environment

How to fix Seems like a problem due to dynamically manipulating the AMICI module. Side effects on import are often problematic.

dweindl commented 3 years ago

@jonrkarr I was not able to reproduce this problem. (Tested with model BIOMD0000000002_url.xml)

I tested the following:

file1.py:

import amici

sbml_file="BIOMD0000000002_url.xml"
sbml_importer = amici.SbmlImporter(sbml_file)
sbml_importer.sbml2amici("test", "deleteme")

file2.py:

import amici
import file1

Is that the scenario you were referring to? Does this example work for you? Which version of python-libsbml are you using?

jonrkarr commented 3 years ago

I distilled down the issue. It appears to be due to an interaction with libsedml. This was problematic with libsedml 2.0.11. Then I updated to 2.0.13 and the problem went away. I then reinstalled 2.0.11 and I don't get the problem anymore. There must have been an issue with my installation of libsedml 2.0.11.

Example

Running python3 file2.py with the files below produced the error below

Error

Traceback (most recent call last):
  File "file2.py", line 5, in <module>
    import_model_from_sbml()
  File "/home/jonrkarr/Documents/Biosimulators_AMICI/file1.py", line 9, in import_model_from_sbml
    observables=observables)
  File "/usr/local/lib/python3.7/site-packages/amici/sbml_import.py", line 339, in sbml2amici
    self._process_sbml(constant_parameters)
  File "/usr/local/lib/python3.7/site-packages/amici/logging.py", line 194, in wrapper_timer
    rval = func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/amici/sbml_import.py", line 380, in _process_sbml
    self._gather_locals()
  File "/usr/local/lib/python3.7/site-packages/amici/logging.py", line 194, in wrapper_timer
    rval = func(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/amici/sbml_import.py", line 432, in _gather_locals
    self._gather_base_locals()
  File "/usr/local/lib/python3.7/site-packages/amici/sbml_import.py", line 463, in _gather_base_locals
    for x_ref in _get_list_of_species_references(self.sbml):
  File "/usr/local/lib/python3.7/site-packages/amici/sbml_import.py", line 1833, in _get_list_of_species_references
    for element in sbml_model.all_elements

file1.py

import amici

def import_model_from_sbml():
    filename = 'tests/fixtures/biomd0000000002.xml'
    sbml_importer = amici.SbmlImporter(filename)
    observables = {var: {'name': var, 'formula': var} for var in ['BLL', 'IL', 'AL']}
    sbml_importer.sbml2amici('model',
                             'model_dir',
                             observables=observables)

file2.py

from file1 import import_model_from_sbml
import libsedml

import_model_from_sbml()

My environment