Source code for cocomico.facts

# -*- coding: utf-8 -*-

"""
CoCoMiCo LP facts.
"""

import re
from typing import Iterable, Tuple

from clyngor.as_pyasp import Atom

from cocomico.base import (
    Biomolecule,
    Exchange,
    Metabolite,
    MetaboliteSet,
    Reaction,
    Seeds,
    Taxon,
)
from cocomico.model import Model

# Translate SBML models into LP facts


[docs] def seed_facts(seeds: Seeds) -> list[Atom]: """ Convert a set of nutritional seed metabolites in LP facts, lexicographically ordered for clarity. seed(Taxon) :param seeds: a set of seed metabolites :returns: a set of LP facts """ seed_atoms = [Atom("seed", [f'"{s}"']) for s in sorted(seeds)] return seed_atoms
[docs] def network_facts(models: dict[Taxon, Model], biomolecules_only=False) -> list[Atom]: """ Convert an SBML model into list LP facts, lexicographically ordered by predicate, taxon, and reaction, for clarity. taxon(Taxon). biomolecule(Metabolite Name, Taxon). reaction(Reaction Id, Taxon). product(Metabolite Name, Reaction Id, Taxon). reactant(Metabolite Name, Reaction Id, Taxon). :param models: a dict mapping taxa to models :returns: a set of LP facts """ taxa = sorted(models.keys()) taxon_atoms = [Atom(kind, [f'"{ taxon }"']) for taxon in taxa for kind in ["taxon"]] # Rely on Metabolite provenance, always same as taxon biomolecule_atoms = [ Atom( "biomolecule", [f'"{ metabolite.biomolecule }"', f'"{ metabolite.provenance }"'], ) for taxon in taxa for metabolite in models[taxon].biomolecule ] # Ignore taxon in tuples since always determined by relations key. # Community.relations keys are the same as Atom predicates. relation_atoms = [ Atom( kind, [ f'"{ m.biomolecule if biomolecules_only else str(m) }"', f'"{ r.name }"', f'"{ taxon }"', ], ) for taxon in taxa for kind in ["product", "reactant"] for m, r, _ in models[taxon].relations[kind] ] reaction_atoms = [ Atom("reaction", [f'"{ rid }"', f'"{ taxon }"']) for taxon in taxa for rid in sorted( # use set because reactions will have multiple produce, reactant relations { r.name for kind in ["product", "reactant"] for _, r, _ in models[taxon].relations[kind] } ) ] return taxon_atoms + biomolecule_atoms + reaction_atoms + relation_atoms
[docs] def to_metabolite(atoms: Iterable[Atom]) -> MetaboliteSet: """ Decode a set of clyngor.as_pyasp.Atom of the form metabolite(Biomolecule,Taxon) :param atoms: metabolite atoms :returns: MetaboliteSet """ r_metabolite = re.compile( r"""\( (?: (?:\'metabolite\((.*?),\s*(.*?)\)) # nested metabolite/2 | (?:(?!\'metabolite\()([^,]*?),\s*([^,]*?),) # flattened biomolecule, provenance ) .*\)""", re.VERBOSE, ) return MetaboliteSet( { Metabolite( biomolecule=Biomolecule((g.group(1) or g.group(3)).strip("\"'")), provenance=Taxon((g.group(2) or g.group(4)).strip("\"'")), ) for atom in atoms if (g := r_metabolite.search(str(atom))) is not None } )
[docs] def to_reaction(atoms: Iterable[Atom]) -> set[Reaction]: """ Decode a set of clyngor.as_pyasp.Atom of the form reaction(Name,Taxon) :param atoms: metabolite atoms :returns: set[Reaction] """ r_reaction = re.compile( r"""\( (?: (?:\'reaction\(([^,]*?),\s*(.*?)\)) # nested reaction/2 | (?:(?!\'reaction\()([^,]*?),\s*([^,]*?),) # flattened reaction, taxon ) .*\)""", re.VERBOSE, ) return { Reaction( name=(g.group(1) or g.group(3)).strip("\"'"), taxon=Taxon((g.group(2) or g.group(4)).strip("\"'")), ) for atom in atoms if (g := r_reaction.search(str(atom))) is not None }
[docs] def to_exchange(tuples: Iterable[Tuple[Atom, Atom, Atom]]) -> set[Exchange]: """ Decode a tuple of clyngor.as_pyasp.Atom of the form # reaction(Name,Taxon) (Taxon, Taxon) :param atoms: Taxon tuple :returns: set[Tuple[Taxon, Taxon]] """ return set( Exchange(Taxon(p.strip('"')), Taxon(c.strip("\"'"))) for m, p, c in tuples )
[docs] def to_biomolecule(atoms: Iterable[Atom]) -> set[Biomolecule]: """ Decode a set of clyngor.as_pyasp.Atom of the form (Biomolecule) :param atoms: biomolecule name atoms :returns: set[Biomolecule] """ return {Biomolecule(atom[0].strip("\"'")) for atom in atoms}