Skip to content

Commit 318d0fa

Browse files
committed
refactor: add a compartment class
This represents the state of the work done by @MaxGreil. refactor: add methods feat: mimic previous behaviour when comparing compartments with strings fix: use compartment IDs instead of objects when converting model to dict fix: ensure backwards compatibility when importing JSON following the previous schema fix: add importlib-resources to setup chore: regenerate pickle models and fix SBML and mat importer fix: update compartment handling on mat and sbml input fix: change version type in json schema from int to str fix: satisfy flake8 fix: better checking for sane IDs chore: update pickels again fix: update documentation notebooks building_model and getting_started test: add tests for compartments and metabolites fix: flake8 is a cruel mistress style: add blank line in test_compartment
1 parent 0fc8ea2 commit 318d0fa

36 files changed

+3743
-430
lines changed

cobra/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from cobra import flux_analysis, io
1212
from cobra.core import (
13-
DictList, Gene, Metabolite, Model, Object, Reaction, Species)
13+
DictList, Gene, Metabolite, Model, Object, Reaction, Species, Compartment)
1414
from cobra.util import show_versions
1515

1616
__version__ = "0.13.4"

cobra/core/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
from cobra.core.reaction import Reaction
1111
from cobra.core.solution import Solution, LegacySolution, get_solution
1212
from cobra.core.species import Species
13+
from cobra.core.compartment import Compartment

cobra/core/compartment.py

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""Provide a class for compartments."""
4+
5+
from __future__ import absolute_import
6+
7+
from copy import deepcopy
8+
from cobra.util import format_long_string, is_not_sane
9+
from six import string_types
10+
11+
from cobra.core.object import Object
12+
13+
14+
class Compartment(Object):
15+
"""
16+
Compartment is a class for holding information regarding
17+
a compartment in a cobra.Model object
18+
19+
Parameters
20+
----------
21+
id : string
22+
An identifier for the compartment
23+
name : string
24+
A human readable name.
25+
26+
"""
27+
def __init__(self, id=None, name=""):
28+
super(Compartment, self).__init__(id=id, name=name)
29+
self._id = None
30+
self.id = id
31+
32+
def __contains__(self, metabolite):
33+
return metabolite.compartment is self
34+
35+
def __eq__(self, other):
36+
if self is other:
37+
return True
38+
if isinstance(other, string_types):
39+
return self._id == other
40+
if isinstance(other, Compartment):
41+
return self._id == other.id
42+
else:
43+
return False
44+
45+
def __ne__(self, other):
46+
return not self.__eq__(other)
47+
48+
def __hash__(self):
49+
return hash(self._id)
50+
51+
def copy(self):
52+
return deepcopy(self)
53+
54+
@property
55+
def id(self):
56+
return self._id
57+
58+
@id.setter
59+
def id(self, value):
60+
if is_not_sane(value):
61+
raise TypeError("The compartment ID must be a non-empty string")
62+
self._id = value
63+
64+
def _repr_html_(self):
65+
return """
66+
<table>
67+
<tr>
68+
<td><strong>Compartment identifier</strong></td><td>{id}</td>
69+
</tr><tr>
70+
<td><strong>Name</strong></td><td>{name}</td>
71+
</tr><tr>
72+
<td><strong>Memory address</strong></td>
73+
<td>{address}</td>
74+
</tr>
75+
</table>""".format(id=self.id, name=format_long_string(self.name),
76+
address='0x0%x' % id(self))

cobra/core/metabolite.py

+27-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
from cobra.core.formula import elements_and_molecular_weights
1313
from cobra.core.species import Species
1414
from cobra.util.solver import check_solver_status
15-
from cobra.util.util import format_long_string
15+
from cobra.util.util import format_long_string, is_not_sane
16+
from cobra.core.compartment import Compartment
1617

1718

1819
# Numbers are not required because of the |(?=[A-Z])? block. See the
@@ -35,15 +36,16 @@ class Metabolite(Species):
3536
A human readable name.
3637
charge : float
3738
The charge number of the metabolite
38-
compartment: str or None
39-
Compartment of the metabolite.
39+
compartment: cobra.Compartment, str or None
40+
Compartment or compartment ID that the the metabolite is in.
4041
"""
4142

4243
def __init__(self, id=None, formula=None, name="",
4344
charge=None, compartment=None):
4445
Species.__init__(self, id, name)
4546
self.formula = formula
4647
# because in a Model a metabolite may participate in multiple Reactions
48+
self._compartment = None
4749
self.compartment = compartment
4850
self.charge = charge
4951

@@ -58,6 +60,28 @@ def _set_id_with_model(self, value):
5860
self._id = value
5961
self.model.metabolites._generate_index()
6062

63+
@property
64+
def compartment(self):
65+
return self._compartment
66+
67+
@compartment.setter
68+
def compartment(self, value):
69+
if value is None:
70+
self._compartment = None
71+
elif isinstance(value, Compartment):
72+
if self._model and value.id in self._model.compartments:
73+
self._compartment = \
74+
self._model.compartments.get_by_id(value.id)
75+
else:
76+
self._compartment = value
77+
elif not is_not_sane(value):
78+
if self._model and value in self._model.compartments:
79+
self._compartment = self._model.compartments.get_by_id(value)
80+
else:
81+
self._compartment = Compartment(value)
82+
else:
83+
raise TypeError("The compartment ID must be a non-empty string")
84+
6185
@property
6286
def constraint(self):
6387
"""Get the constraints associated with this metabolite from the solve

0 commit comments

Comments
 (0)