Source code for cobra.manipulation.modify

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

from __future__ import absolute_import

from ast import NodeTransformer
from itertools import chain
from warnings import warn

from six import iteritems

from cobra.core import Reaction
from cobra.core.gene import ast2str
from cobra.manipulation.delete import get_compiled_gene_reaction_rules
from cobra.util.solver import set_objective


[docs]_renames = ( (".", "_DOT_"), ("(", "_LPAREN_"), (")", "_RPAREN_"), ("-", "__"), ("[", "_LSQBKT"), ("]", "_RSQBKT"), (",", "_COMMA_"), (":", "_COLON_"), (">", "_GT_"), ("<", "_LT"), ("/", "_FLASH"), ("\\", "_BSLASH"), ("+", "_PLUS_"), ("=", "_EQ_"), (" ", "_SPACE_"), ("'", "_SQUOT_"), ('"', "_DQUOT_"),
)
[docs]def _escape_str_id(id_str): """make a single string id SBML compliant""" for c in ("'", '"'): if id_str.startswith(c) and id_str.endswith(c) and id_str.count(c) == 2: id_str = id_str.strip(c) for char, escaped_char in _renames: id_str = id_str.replace(char, escaped_char) return id_str
[docs]class _GeneEscaper(NodeTransformer):
[docs] def visit_Name(self, node): node.id = _escape_str_id(node.id) return node
[docs]def escape_ID(cobra_model): """makes all ids SBML compliant""" for x in chain( [cobra_model], cobra_model.metabolites, cobra_model.reactions, cobra_model.genes ): x.id = _escape_str_id(x.id) cobra_model.repair() gene_renamer = _GeneEscaper() for rxn, rule in iteritems(get_compiled_gene_reaction_rules(cobra_model)): if rule is not None: rxn._gene_reaction_rule = ast2str(gene_renamer.visit(rule))
[docs]def rename_genes(cobra_model, rename_dict): """renames genes in a model from the rename_dict""" recompute_reactions = set() # need to recomptue related genes remove_genes = [] for old_name, new_name in iteritems(rename_dict): # undefined if there a value matches a different key # because dict is unordered try: gene_index = cobra_model.genes.index(old_name) except ValueError: gene_index = None old_gene_present = gene_index is not None new_gene_present = new_name in cobra_model.genes if old_gene_present and new_gene_present: old_gene = cobra_model.genes.get_by_id(old_name) # Added in case not renaming some genes: if old_gene is not cobra_model.genes.get_by_id(new_name): remove_genes.append(old_gene) recompute_reactions.update(old_gene._reaction) elif old_gene_present and not new_gene_present: # rename old gene to new gene gene = cobra_model.genes[gene_index] # trick DictList into updating index cobra_model.genes._dict.pop(gene.id) # ugh gene.id = new_name cobra_model.genes[gene_index] = gene elif not old_gene_present and new_gene_present: pass else: # if not old gene_present and not new_gene_present # the new gene's _model will be set by repair # This would add genes from rename_dict # that are not associated with a rxn # cobra_model.genes.append(Gene(new_name)) pass cobra_model.repair() class Renamer(NodeTransformer): def visit_Name(self, node): node.id = rename_dict.get(node.id, node.id) return node gene_renamer = Renamer() for rxn, rule in iteritems(get_compiled_gene_reaction_rules(cobra_model)): if rule is not None: rxn._gene_reaction_rule = ast2str(gene_renamer.visit(rule)) for rxn in recompute_reactions: rxn.gene_reaction_rule = rxn._gene_reaction_rule for i in remove_genes: cobra_model.genes.remove(i)