Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial attempt at compartments #1193

Draft
wants to merge 4 commits into
base: devel
Choose a base branch
from

Conversation

akaviaLab
Copy link
Contributor

Very initial attempt at compartments. Just to see if I'm heading in the right direction. Will not be committed as is.

@akaviaLab akaviaLab marked this pull request as draft March 25, 2022 22:32
@cdiener
Copy link
Member

cdiener commented Mar 27, 2022

I think for efficiency it would be nice if it could derive from the Group class already implemented in core/group.py. You could add new attributes specific to the compartment.



class Compartment(Object):
class Compartment(Group):
"""
Manage groups via this implementation of the SBML group specification.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably wrong. First sentence should describe Compartment not Group. Better Documentation of class needed.

dimensions: Optional[float] = None,
):
def __init__(self, id: str, name: str = "", members: Optional[Iterable] = None,
dimensions: Optional[float] = None):
"""Initialize the group object.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Initialize the Compartment object."


Raises
------
TypeError if given anything other than metaoblites or reactions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: metabolites

src/cobra/core/compartment.py Outdated Show resolved Hide resolved
@@ -137,7 +80,7 @@ def add_members(self, new_members: Union[str, Metabolite, Reaction,

Raises
------
TypeError - if given any object other than Metaoblite or Gene
TypeError - if given any object other than Metaoblite or Reaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo "Metabolite"

@@ -137,7 +80,7 @@ def add_members(self, new_members: Union[str, Metabolite, Reaction,

Raises
------
TypeError - if given any object other than Metaoblite or Gene
TypeError - if given any object other than Metaoblite or Reaction
"""
if isinstance(new_members, str) or hasattr(new_members, "id"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code duplication here. Same code below again. This is not very robust and the warning message is not informative. Be more precise, e.g. "members should be provided as list`.

@@ -180,25 +123,64 @@ def metabolites(self) -> DictList[Metabolite]:
return self._members.query(lambda x: isinstance(x, Metabolite))

@property
def reactions(self) -> Optional[FrozenSet[Reaction]]:
def inferred_reactions(self) -> FrozenSet[Reaction]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I always prefer to use names, so that code completion shows me the options below each other. I.e. reactions_inferred and reactions_assigned are already much better. Also be more precise. There could be many ways for inferral, so I would just state the method.
I.e. better names could be: reactions_from_metabolites and reactions_from_manual

Returns
-------
FrozenSet of cobra.Reactions
Reactions that have metabolites that belong to this compartment.
"""
direct_set = set(self._members.query(lambda x: isinstance(x, Reaction)))
rxn_set = set()
for met in self.metabolites:
rxn_set.update(met._reactions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems just wrong. I understand what you are doing is: "Adding all reactions with at least 1 metabolite in the compartment". What you should be doing is "Add only reactions with all metabolites in the compartment!". Please check this!

src/cobra/core/compartment.py Outdated Show resolved Hide resolved
Copy link
Member

@Midnighter Midnighter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial observations. I think we should nail down a few more details on paper before actually coding it up.

src/cobra/core/compartment.py Show resolved Hide resolved


class Compartment(Object):
class Compartment(Group):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if inheriting from Group is really desirable or we should just have a similar class interface.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another point in favor is that .members is a bit awkward here. We rather want attributes .reactions and .metabolites.

def __contains__(self, member: Union[Metabolite, Gene]):
return member.compartment is self
def __contains__(self, member: Union[Metabolite, Reaction]):
return self.members.__contains__(member)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we keep members then more pythonic would be

Suggested change
return self.members.__contains__(member)
return member in self.members

@cdiener cdiener added the stale The issue or pull request lacks activity. label Apr 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale The issue or pull request lacks activity.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants