opencobra/cobrapy

How can I load the BIGG universal model with COBRApy?

Closed this issue ยท 10 comments

Trying to load the latest universal_model.json file from BiGG returns the following error:

~/opt/miniconda3/envs/py37/lib/python3.7/site-packages/cobra/core/object.py in annotation(self, annotation)
     48     def annotation(self, annotation):
     49         if not isinstance(annotation, dict):
---> 50             raise TypeError("Annotation must be a dict")
     51         else:
     52             self._annotation = annotation

TypeError: Annotation must be a dict

Might be related to #736 but would need a bit more diving into...

It's due to a more recent change #930 where we moved to more consistent formats but once again didn't account for file format backward compatibility. ๐Ÿ˜ž

I guess an annoying workaround would be to load the JSON with an older version of cobrapy, write it to SBML, and then load it again in the latest version if you need the latest version of cobrapy at all.

The workaround (loading the JSON model with cobrapy v.0.17, but saving as SBML) isn't quite working for me.
It results in the error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-16-49d4759b12c1> in <module>
      9 for reaction in universal.reactions:
     10     reaction.annotation = {}
---> 11 cobra.io.write_sbml_model(universal, '/projectnb2/talbot-lab-data/metabolic_models/scripts/metabolic_model_curation/reference_data/universal_model.sbml')

~/.local/lib/python3.8/site-packages/cobra/io/sbml.py in write_sbml_model(cobra_model, filename, f_replace, **kwargs)
    798                     obj = metaid_map[member.getMetaIdRef()]
    799 
--> 800                 typecode = obj.getTypeCode()
    801                 obj_id = _check_required(obj, obj.getIdAttribute(), "id")
    802 

~/.local/lib/python3.8/site-packages/cobra/io/sbml.py in _model_to_sbml(cobra_model, f_replace, units)
    943         if "annotation" in meta:
    944             _sbase_annotations(doc, meta["annotation"])
--> 945         if "notes" in meta:
    946             _sbase_notes_dict(doc, meta["notes"])
    947 

~/.local/lib/python3.8/site-packages/cobra/io/sbml.py in _sbase_annotations(sbase, annotation)
   1336                  ["<p>{}: {}</p>".format(k, v) for (k, v) in notes.items()] + \
   1337                  ["</html>"]
-> 1338         _check(
   1339             sbase.setNotes("\n".join(tokens)),
   1340             "Setting notes on sbase: {}".format(sbase)

AttributeError: 'list' object has no attribute 'items'

Example script here

In your notebook, you load the model successfully. Did you try to write it to SBML it without modifying the reactions' annotation attribute?

No, after loading the model & before saving as SBML, I removed the annotation attributes as follows (lines 9-10 in the error message above):

for reaction in univ_bigg.reactions: 
    reaction.annotation = {}

Okay, I think we need to implement a better solution here. Probably, a wrapper that can upgrade old JSON versions to the newer format.

Is BIGG still alive? It looks like it has been abandoned at this point... The easiest solution would still be for them to update the universal model...

No idea, if it's still alive tbh. It's probably not worth the effort but I feel personally responsible for the current JSON reading mess.

I mean we could just convert the annotations in the JSON to the new standard and provide a repaired one then.

As a workaround, I added a fixed version to our wiki.