Source code for cameo.io

# Copyright 2014 Novo Nordisk Foundation Center for Biosustainability, DTU.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import, print_function

try:
    import cPickle as pickle
except ImportError:
    import pickle

import os
import optlang
from cobra.io import read_sbml_model, load_json_model

from cobra import Model
from cameo.config import solvers

import logging

logger = logging.getLogger(__name__)


[docs]def load_model(path_or_handle, solver_interface=optlang, sanitize=True): """Read a metabolic model . Parameters ---------- path_or_handle : path, fhandle or name. One of: * file path of a model file; * file handle to a SBML or pickled model; or * the identifier of a model in a web database (optflux.org/models) solver_interface : solver_interface, optional E.g. optlang.glpk_interface or any other optlang interface. sanitize : boolean, optional If reaction and metabolite IDs should be sanitized (works only for SBML models). """ solver_interface = solvers.get(solver_interface, solver_interface) if isinstance(path_or_handle, str) and not os.path.isfile(path_or_handle): from cameo.models.webmodels import load_webmodel logger.debug("Given path is not a file. Trying to load from webmodels") model = load_webmodel(path_or_handle, solver_interface) else: if isinstance(path_or_handle, str): # Open the given file path = path_or_handle handle = open(path_or_handle, 'rb') elif hasattr(path_or_handle, 'read'): # Argument is already an open file path = path_or_handle.name handle = path_or_handle else: raise ValueError('Provided argument %s has to be either a string or a file handle' % path_or_handle) model = _load_model_from_file(path, handle) # Parse model from the file if sanitize: sanitize_ids(model) if solver_interface is not None and not isinstance(model.solver, solver_interface.Model): logger.debug("Changing solver interface to %s" % solver_interface) model.solver = solver_interface return model
def _load_model_from_file(path, handle): """Try to parse a model from a file handle using different encodings.""" logger.debug('Reading file from %s assuming pickled model.' % path) try: model = pickle.load(handle) except (TypeError, pickle.UnpicklingError): logger.debug('Cannot unpickle %s. Assuming json model next.' % path) try: model = load_json_model(path) except ValueError: logger.debug("Cannot import %s as json model. Assuming sbml model next." % path) try: model = read_sbml_model(path) except AttributeError as e: logger.error("cobrapy doesn't raise a proper exception if a file does not contain an SBML model") raise e except Exception as e: logger.error( "Looks like something blow up while trying to import {} as a SBML model." "Try validating the model at http://sbml.org/Facilities/Validator/ to get more information.".format( path)) raise e return model ID_SANITIZE_RULES_SIMPHENY = [('_DASH_', '-'), ('_FSLASH_', '/'), ('_BSLASH_', "\\"), ('_LPAREN_', '('), ('_LSQBKT_', '['), ('_RSQBKT_', ']'), ('_RPAREN_', ')'), ('_COMMA_', ','), ('_PERIOD_', '.'), ('_APOS_', "'"), ('&amp;', '&'), ('&lt;', '<'), ('&gt;', '>'), ('&quot;', '"')] ID_SANITIZE_RULES_TAB_COMPLETION = [('_DASH_', '_dsh_'), ('_FSLASH_', '_fsh_'), ('_BSLASH_', "_bsh_"), ('_LPAREN_', '_lp_'), ('_LSQBKT_', '_lb_'), ('_RSQBKT_', '_rb_'), ('_RPAREN_', '_rp_'), ('_COMMA_', '_cm_'), ('_PERIOD_', '_prd_'), ('_APOS_', "_apo_"), ('&amp;', '_amp_'), ('&lt;', '_lt_'), ('&gt;', '_gt_'), ('&quot;', '_qot_')] def _apply_sanitize_rules(id, rules): for rule in rules: id = id.replace(*rule) return id
[docs]def sanitize_ids(model): """Makes IDs crippled by the XML specification less annoying. For example, EX_glc_LPAREN_e_RPAREN_ will be converted to EX_glc_lp_e_rp_. Furthermore, reactions and metabolites will be equipped with a nice_id attribute that provides the original ID, i.e., EX_glc(d). Parameters ---------- model : model Notes ----- Will add a nice_id attribute. """ for metabolite in model.metabolites: met_id = metabolite.id metabolite.id = _apply_sanitize_rules(met_id, ID_SANITIZE_RULES_TAB_COMPLETION) metabolite.nice_id = _apply_sanitize_rules(met_id, ID_SANITIZE_RULES_SIMPHENY) metabolite.name = _apply_sanitize_rules(metabolite.name, ID_SANITIZE_RULES_SIMPHENY) for reaction in model.reactions: if isinstance(model, Model): forward_variable = reaction.forward_variable reverse_variable = reaction.reverse_variable rxn_id = reaction.id reaction.id = _apply_sanitize_rules(rxn_id, ID_SANITIZE_RULES_TAB_COMPLETION) reaction.nice_id = _apply_sanitize_rules(rxn_id, ID_SANITIZE_RULES_SIMPHENY) if reaction.name is not None: reaction.name = _apply_sanitize_rules(reaction.name, ID_SANITIZE_RULES_SIMPHENY) if isinstance(model, Model): forward_variable.name = reaction.id if reverse_variable is not None: reverse_variable.name = reaction.reverse_id if isinstance(model, Model): for constraint in model.solver.constraints: constraint.name = _apply_sanitize_rules(constraint.name, ID_SANITIZE_RULES_TAB_COMPLETION) model.repair()