Example #1
0
    def __init__(
        self,
        model,
        Exclude_list=[],
        tolerance_integral=1e-9,
        compartment_info=None,
        membrane_potential=None,
    ):

        self.compartment_info = compartment_info
        self.membrane_potential = membrane_potential

        do_not_copy_by_ref = {
            "metabolites",
            "reactions",
            "genes",
            "notes",
            "annotation",
        }
        for attr in model.__dict__:
            if attr not in do_not_copy_by_ref:
                self.__dict__[attr] = model.__dict__[attr]

        self.metabolites = DictList()
        do_not_copy_by_ref = {"_reaction", "_model"}
        for metabolite in model.metabolites:
            new_met = Thermo_met(
                metabolite=metabolite,
                updated_model=self,
            )
            self.metabolites.append(new_met)

        self.genes = DictList()
        for gene in model.genes:
            new_gene = gene.__class__(None)
            for attr, value in iteritems(gene.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_gene.__dict__[attr] = (copy(value)
                                               if attr == "formula" else value)
            new_gene._model = self
            self.genes.append(new_gene)

        self.reactions = DictList()
        do_not_copy_by_ref = {"_model", "_metabolites", "_genes"}
        for reaction in model.reactions:
            new_reaction = thermo_reaction(
                cobra_rxn=reaction,
                updated_model=self,
            )
            self.reactions.append(new_reaction)

        try:
            self._solver = deepcopy(model.solver)
            # Cplex has an issue with deep copies
        except Exception:  # pragma: no cover
            self._solver = copy(model.solver)  # pragma: no cover

        self.Exclude_list = Exclude_list
        self.solver.configuration.tolerances.integrality = tolerance_integral
        self._var_update = False
Example #2
0
    def __init__(self, id_or_model=None, name=None):
        if isinstance(id_or_model, Model):
            Object.__init__(self, name=name)
            self.__setstate__(id_or_model.__dict__)
            if not hasattr(self, "name"):
                self.name = None
            self._solver = id_or_model.solver
        else:
            Object.__init__(self, id_or_model, name=name)
            self._trimmed = False
            self._trimmed_genes = []
            self._trimmed_reactions = {}
            self.genes = DictList()
            self.reactions = DictList()  # A list of cobra.Reactions
            self.metabolites = DictList()  # A list of cobra.Metabolites
            # genes based on their ids {Gene.id: Gene}
            self.compartments = dict()
            self._contexts = []

            # from cameo ...

            # if not hasattr(self, '_solver'):  # backwards compatibility
            # with older cobrapy pickles?
            interface = solvers[get_solver_name()]
            self._solver = interface.Model()
            self._solver.objective = interface.Objective(S.Zero)
            self._populate_solver(self.reactions, self.metabolites)
Example #3
0
    def __init__(self, id, name="", members=None, kind=None):
        Object.__init__(self, id, name)

        self._members = DictList() if members is None else DictList(members)
        self._kind = None
        self.kind = "collection" if kind is None else kind
        # self.model is None or refers to the cobra.Model that
        # contains self
        self._model = None
Example #4
0
def list_model_reactions(model_id):
    """
    List all reactions in a model.

    Parameters
    ----------
    model_id : str
        A valid id for a model in BiGG.

    Returns
    -------
    reactions : DictList
        All model reactions.

    Raises
    ------
    requests.HTTPError
        If the request has failed.

    """
    data = _get("reactions", None, model_id)

    LOGGER.info("Found %i reactions", data[RESULTS_COUNT])
    reactions = DictList()
    for reaction_data in data[RESULTS]:
        reaction_id = reaction_data[BIGG_ID]
        if reaction_id in reactions:
            continue
        reaction = Reaction(id=reaction_id, name=reaction_data[NAME])
        reactions.append(reaction)

    return reactions
Example #5
0
def list_model_metabolites(model_id):
    """
    List all metabolites in a model.

    Parameters
    ----------
    model_id : str
        A model id present in BiGG.

    Returns
    -------
    metabolites : DictList
        A list of metabolites.

    Raises
    ------
    requests.HTTPError
        If the request has failed.
    """
    data = _get("metabolites", None, model_id)

    LOGGER.info("Found %i reactions", data[RESULTS_COUNT])
    metabolites = DictList()

    for metabolites_data in data[RESULTS]:
        metabolite_id = metabolites_data[BIGG_ID] + "_" + metabolites_data[
            COMPARTMENT_BIGG_ID]
        if metabolite_id in metabolites:
            continue
        metabolite = Metabolite(id=metabolite_id, name=metabolites_data[NAME])
        metabolites.append(metabolite)

    return metabolites
Example #6
0
def list_reactions():
    """
    List all reactions available in BiGG. The reactions do not contain stoichiometry.
    To retrieve the full reaction use *get_reaction*.

    Returns
    -------
    reactions : list
        A list of Reaction.

    Raises
    ------
    requests.HTTPError
        If the request has failed.
    """
    data = _get("reactions", None, None)

    LOGGER.info("Found %i reactions", data[RESULTS_COUNT])
    reactions = DictList()
    for reaction_data in data[RESULTS]:
        reaction_id = reaction_data[BIGG_ID]
        if reaction_id in reactions:
            continue
        reaction = Reaction(id=reaction_data[BIGG_ID],
                            name=reaction_data[NAME])
        reactions.append(reaction)

    return reactions
Example #7
0
 def __init__(self, data=None, info=None, args=None):
     super().__init__(data, info, args, 'KBaseFBA.FBAModel')
     self.metabolites = DictList()
     model_compounds = []
     ids = set()
     for o in self.data['modelcompounds']:
         if o['id'] not in ids:
             ids.add(o['id'])
             model_compounds.append(o)
     self.data['modelcompounds'] = model_compounds
     self.update_indexes()
Example #8
0
    def _from_json(self, data):
        # Should find better solution for this ...
        # Converting every list of hashes containing objects with id fields into DictList
        for field in data.keys():
            if isinstance(data[field], list) and len(data[field]) > 0:
                if field == "mediacompounds":
                    for item in data[field]:
                        if not "id" in item:
                            item["id"] = item["compound_ref"].split("/").pop()
                            if item["id"] == "cpd00000":
                                item["id"] = item["name"]

                if isinstance(data[field][0], dict) and "id" in data[field][0]:
                    data[field] = DictList(map(lambda x: self._to_object(field, x), data[field]))

        return data
Example #9
0
 def __init__(
     self,
     id_or_model: Union[str, cobra.Model] = None,
     name: str = None,
     hardcoded_rev_reactions: bool = True,
 ):
     """Initialize model."""
     # TODO: refactor from cobra.Model so that internal matrix does not get
     # repopulated 100 times
     self.proteins = DictList()
     self.hardcoded_rev_reactions = hardcoded_rev_reactions
     if isinstance(id_or_model,
                   cobra.Model) and not hasattr(id_or_model, "proteins"):
         self.from_cobra(id_or_model, name)
     else:
         super().__init__(id_or_model, name)
Example #10
0
    def add_groups(self, group_list):
        """Add groups to the model.

        Groups with identifiers identical to a group already in the model are
        ignored.

        If any group contains members that are not in the model, these members
        are added to the model as well. Only metabolites, reactions, and genes
        can have groups.

        Parameters
        ----------
        group_list : list
            A list of `cobra.Group` objects to add to the model.
        """
        def existing_filter(group):
            if group.id in self.groups:
                logger.warning("Ignoring group '%s' since it already exists.",
                               group.id)
                return False
            return True

        if isinstance(group_list, string_types) or hasattr(group_list, "id"):
            warn("need to pass in a list")
            group_list = [group_list]

        pruned = DictList(filter(existing_filter, group_list))

        for group in pruned:
            group._model = self
            for member in group.members:
                # If the member is not associated with the model, add it
                if isinstance(member, Metabolite):
                    if member not in self.metabolites:
                        self.add_metabolites([member])
                if isinstance(member, Reaction):
                    if member not in self.reactions:
                        self.add_reactions([member])
                # TODO(midnighter): `add_genes` method does not exist.
                # if isinstance(member, Gene):
                #     if member not in self.genes:
                #         self.add_genes([member])

            self.groups += [group]
Example #11
0
def list_metabolites():
    """
    List all metabolites present in BiGG.

    Returns
    -------
    metabolites : DictList
        A list of metabolites.

    Raises
    ------
    requests.HTTPError
        If the request has failed.
    """
    data = _get("metabolites", None, None)

    LOGGER.info("Found %i metabolites", data[RESULTS_COUNT])
    metabolites = DictList()
    for metabolites_data in data[RESULTS]:
        metabolite = Metabolite(id=metabolites_data[BIGG_ID],
                                name=metabolites_data[NAME])
        metabolites.append(metabolite)

    return metabolites
Example #12
0
    def add_reactions(self, reaction_list):
        """Add reactions to the model.

        Reactions with identifiers identical to a reaction already in the
        model are ignored.

        The change is reverted upon exit when using the model as a context.

        Parameters
        ----------
        reaction_list : list
            A list of `cobra.Reaction` objects
        """
        def existing_filter(rxn):
            if rxn.id in self.reactions:
                logger.warning(
                    "Ignoring reaction '%s' since it already exists.", rxn.id)
                return False
            return True

        # First check whether the reactions exist in the model.
        pruned = DictList(filter(existing_filter, reaction_list))

        context = get_context(self)

        # Add reactions. Also take care of genes and metabolites in the loop.
        for reaction in pruned:
            reaction._model = self
            # Build a `list()` because the dict will be modified in the loop.
            for metabolite in list(reaction.metabolites):
                # TODO: Should we add a copy of the metabolite instead?
                if metabolite not in self.metabolites:
                    self.add_metabolites(metabolite)
                # A copy of the metabolite exists in the model, the reaction
                # needs to point to the metabolite in the model.
                else:
                    # FIXME: Modifying 'private' attributes is horrible.
                    stoichiometry = reaction._metabolites.pop(metabolite)
                    model_metabolite = self.metabolites.get_by_id(
                        metabolite.id)
                    reaction._metabolites[model_metabolite] = stoichiometry
                    model_metabolite._reaction.add(reaction)
                    if context:
                        context(
                            partial(model_metabolite._reaction.remove,
                                    reaction))

            for gene in list(reaction._genes):
                # If the gene is not in the model, add it
                if not self.genes.has_id(gene.id):
                    self.genes += [gene]
                    gene._model = self

                    if context:
                        # Remove the gene later
                        context(partial(self.genes.__isub__, [gene]))
                        context(partial(setattr, gene, "_model", None))

                # Otherwise, make the gene point to the one in the model
                else:
                    model_gene = self.genes.get_by_id(gene.id)
                    if model_gene is not gene:
                        reaction._dissociate_gene(gene)
                        reaction._associate_gene(model_gene)

        self.reactions += pruned

        if context:
            context(partial(self.reactions.__isub__, pruned))
Example #13
0
    def add_reactions(self, reaction_list: Iterator[Reaction]):
        """Add reactions to the model.

        Reactions with identifiers identical to a reaction already in the
        model are ignored.
        The change is reverted upon exit when using the model as a context.
        Enzyme Constrained changes: avoid adding proteins as metabolites.

        Parameters
        ----------
        reaction_list : list
            A list of `cobra.Reaction` objects
        """
        def existing_filter(rxn):
            if rxn.id in self.reactions:
                LOGGER.warning(
                    f"Ignoring reaction '{rxn.id}' since it already exists.")
                return False
            return True

        # First check whether the reactions exist in the model.
        pruned = DictList(filter(existing_filter, reaction_list))

        context = get_context(self)

        # Add reactions. Also take care of genes and metabolites in the loop.
        for reaction in pruned:
            reaction._model = self
            # Build a `list()` because the dict will be modified in the loop.
            for metabolite in list(reaction.metabolites):
                is_prot = isinstance(metabolite, Protein)
                target = self.proteins if is_prot else self.metabolites
                if metabolite not in target:
                    if is_prot:
                        self.add_proteins([metabolite])
                    else:
                        self.add_metabolites(metabolite)

                # A copy of the metabolite exists in the model, the reaction
                # needs to point to the metabolite in the model.
                else:
                    stoichiometry = reaction._metabolites.pop(metabolite)

                    model_metabolite = target.get_by_id(metabolite.id)
                    reaction._metabolites[model_metabolite] = stoichiometry
                    model_metabolite._reaction.add(reaction)
                    if context:
                        context(
                            partial(model_metabolite._reaction.remove,
                                    reaction))

            for gene in list(reaction._genes):
                # If the gene is not in the model, add it
                if not self.genes.has_id(gene.id):
                    self.genes += [gene]
                    gene._model = self

                    if context:
                        # Remove the gene later
                        context(partial(self.genes.__isub__, [gene]))
                        context(partial(setattr, gene, "_model", None))

                # Otherwise, make the gene point to the one in the model
                else:
                    model_gene = self.genes.get_by_id(gene.id)
                    if model_gene is not gene:
                        reaction._dissociate_gene(gene)
                        reaction._associate_gene(model_gene)

        self.reactions += pruned

        if context:
            context(partial(self.reactions.__isub__, pruned))

        # from cameo ...
        self._populate_solver(pruned)
Example #14
0
    def copy(self):
        """Provide a partial 'deepcopy' of the Model.

        All of the Metabolite, Gene, and Reaction objects are created anew but
        in a faster fashion than deepcopy.
        Enzyme constrained changes: also deepcopy proteins.
        """
        new = self.__class__()
        do_not_copy_by_ref = {
            "metabolites",
            "reactions",
            "proteins",
            "genes",
            "notes",
            "annotation",
            "groups",
        }
        for attr in self.__dict__:
            if attr not in do_not_copy_by_ref:
                new.__dict__[attr] = self.__dict__[attr]
        new.notes = deepcopy(self.notes)
        new.annotation = deepcopy(self.annotation)

        new.metabolites = DictList()
        do_not_copy_by_ref = {"_reaction", "_model"}
        for metabolite in self.metabolites:
            new_met = metabolite.__class__()
            for attr, value in metabolite.__dict__.items():
                if attr not in do_not_copy_by_ref:
                    new_met.__dict__[attr] = copy(
                        value) if attr == "formula" else value
            new_met._model = new
            new.metabolites.append(new_met)

        new.proteins = DictList()
        for protein in self.proteins:
            new_protein = protein.__class__()
            for attr, value in protein.__dict__.items():
                if attr not in do_not_copy_by_ref:
                    new_protein.__dict__[attr] = (copy(value) if attr
                                                  == "formula" else value)
            new_protein._model = new
            for attr, value in protein.__dict__.items():
                if attr not in do_not_copy_by_ref:
                    new_protein.__dict__[attr] = copy(value)
            new_protein._model = new
            new.proteins.append(new_protein)
            # update awareness
            for metabolite, stoic in protein._metabolites.items():
                if metabolite not in new.proteins:
                    new_met = new.metabolites.get_by_id(metabolite.id)
                    new_protein._metabolites[new_met] = stoic
                    new_met._reaction.add(new_protein)
            new_protein.kcats._protein = new_protein

        new.genes = DictList()
        for gene in self.genes:
            new_gene = gene.__class__(None)
            for attr, value in gene.__dict__.items():
                if attr not in do_not_copy_by_ref:
                    new_gene.__dict__[attr] = (copy(value)
                                               if attr == "formula" else value)
            new_gene._model = new
            new.genes.append(new_gene)

        new.reactions = DictList()
        do_not_copy_by_ref = {"_model", "_metabolites", "_genes"}
        for reaction in self.reactions:
            new_reaction = reaction.__class__()
            for attr, value in reaction.__dict__.items():
                if attr not in do_not_copy_by_ref:
                    new_reaction.__dict__[attr] = copy(value)
            new_reaction._model = new
            new.reactions.append(new_reaction)
            # update awareness
            for metabolite, stoic in reaction._metabolites.items():
                if metabolite in new.proteins:
                    new_met = new.proteins.get_by_id(metabolite.id)
                    new_reaction._metabolites[new_met] = stoic
                    new_met._reaction.add(new_reaction)
                else:
                    # regular met
                    new_met = new.metabolites.get_by_id(metabolite.id)
                    new_reaction._metabolites[new_met] = stoic
                    new_met._reaction.add(new_reaction)
            for gene in reaction._genes:
                new_gene = new.genes.get_by_id(gene.id)
                new_reaction._genes.add(new_gene)
                new_gene._reaction.add(new_reaction)

        new.groups = DictList()
        do_not_copy_by_ref = {"_model", "_members"}
        # Groups can be members of other groups. We initialize them first and
        # then update their members.
        for group in self.groups:
            new_group = group.__class__(group.id)
            for attr, value in group.__dict__.items():
                if attr not in do_not_copy_by_ref:
                    new_group.__dict__[attr] = copy(value)
            new_group._model = new
            new.groups.append(new_group)
        for group in self.groups:
            new_group = new.groups.get_by_id(group.id)
            # update awareness, as in the reaction copies
            new_objects = []
            for member in group.members:
                if isinstance(member, Metabolite):
                    new_object = new.metabolites.get_by_id(member.id)
                elif isinstance(member, Reaction):
                    new_object = new.reactions.get_by_id(member.id)
                elif isinstance(member, cobra.Gene):
                    new_object = new.genes.get_by_id(member.id)
                elif isinstance(member, Protein):
                    new_object = new.proteins.get_by_id(member.id)
                elif isinstance(member, cobra.core.Group):
                    new_object = new.genes.get_by_id(member.id)
                else:
                    raise TypeError(
                        "The group member {!r} is unexpectedly not a "
                        "metabolite, reaction, gene, nor another "
                        "group.".format(member))
                new_objects.append(new_object)
            new_group.add_members(new_objects)

        try:
            new._solver = deepcopy(self.solver)
            # Cplex has an issue with deep copies
        except Exception:  # pragma: no cover
            new._solver = copy(self.solver)  # pragma: no cover

        # it doesn't make sense to retain the context of a copied model so
        # assign a new empty context
        new._contexts = list()

        return new
Example #15
0
    def add_reactions(self, reaction_list):
        """Will add a cobra.Reaction object to the model, if
        reaction.id is not in self.reactions.

        The change is reverted upon exit when using the model as a context.

        Parameters
        ----------
        reaction_list : list
            A list of `cobra.Reaction` objects

        """

        try:
            reaction_list = DictList(reaction_list)
        except TypeError:
            reaction_list = DictList([reaction_list])

        # Only add the reaction if one with the same ID is not already
        # present in the model.
        reactions_in_model = [
            i.id for i in reaction_list if i.id in self.reactions
        ]

        if len(reactions_in_model) > 0:
            raise Exception("Reactions already in the model: " +
                            ", ".join(reactions_in_model))

        context = get_context(self)

        # Add reactions. Also take care of genes and metabolites in the loop
        for reaction in reaction_list:
            reaction._reset_var_cache()
            reaction._model = self  # the reaction now points to the model
            # keys() is necessary because the dict will be modified during
            # the loop
            for metabolite in list(reaction._metabolites.keys()):
                # if the metabolite is not in the model, add it
                # should we be adding a copy instead.
                if metabolite not in self.metabolites:
                    self.add_metabolites(metabolite)
                # A copy of the metabolite exists in the model, the reaction
                # needs to point to the metabolite in the model.
                else:
                    stoichiometry = reaction._metabolites.pop(metabolite)
                    model_metabolite = self.metabolites.get_by_id(
                        metabolite.id)
                    reaction._metabolites[model_metabolite] = stoichiometry
                    model_metabolite._reaction.add(reaction)
                    if context:
                        context(
                            partial(model_metabolite._reaction.remove,
                                    reaction))

            for gene in list(reaction._genes):
                # If the gene is not in the model, add it
                if not self.genes.has_id(gene.id):
                    self.genes += [gene]
                    gene._model = self

                    if context:
                        # Remove the gene later
                        context(partial(self.genes.__isub__, [gene]))
                        context(partial(setattr, gene, '_model', None))

                # Otherwise, make the gene point to the one in the model
                else:
                    model_gene = self.genes.get_by_id(gene.id)
                    if model_gene is not gene:
                        reaction._dissociate_gene(gene)
                        reaction._associate_gene(model_gene)

        self.reactions += reaction_list

        if context:
            context(partial(self.reactions.__isub__, reaction_list))

        # from cameo ...
        self._populate_solver(reaction_list)
Example #16
0
    def copy(self):
        """Provides a partial 'deepcopy' of the Model.  All of the Metabolite,
        Gene, and Reaction objects are created anew but in a faster fashion
        than deepcopy
        """
        new = self.__class__()
        do_not_copy_by_ref = {
            "metabolites", "reactions", "genes", "notes", "annotation"
        }
        for attr in self.__dict__:
            if attr not in do_not_copy_by_ref:
                new.__dict__[attr] = self.__dict__[attr]
        new.notes = deepcopy(self.notes)
        new.annotation = deepcopy(self.annotation)

        new.metabolites = DictList()
        do_not_copy_by_ref = {"_reaction", "_model"}
        for metabolite in self.metabolites:
            new_met = metabolite.__class__()
            for attr, value in iteritems(metabolite.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_met.__dict__[attr] = copy(
                        value) if attr == "formula" else value
            new_met._model = new
            new.metabolites.append(new_met)

        new.genes = DictList()
        for gene in self.genes:
            new_gene = gene.__class__(None)
            for attr, value in iteritems(gene.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_gene.__dict__[attr] = copy(
                        value) if attr == "formula" else value
            new_gene._model = new
            new.genes.append(new_gene)

        new.reactions = DictList()
        do_not_copy_by_ref = {"_model", "_metabolites", "_genes"}
        for reaction in self.reactions:
            new_reaction = reaction.__class__()
            for attr, value in iteritems(reaction.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_reaction.__dict__[attr] = copy(value)
            new_reaction._model = new
            new.reactions.append(new_reaction)
            # update awareness
            for metabolite, stoic in iteritems(reaction._metabolites):
                new_met = new.metabolites.get_by_id(metabolite.id)
                new_reaction._metabolites[new_met] = stoic
                new_met._reaction.add(new_reaction)
            for gene in reaction._genes:
                new_gene = new.genes.get_by_id(gene.id)
                new_reaction._genes.add(new_gene)
                new_gene._reaction.add(new_reaction)

        for reaction in new.reactions:
            reaction._reset_var_cache()
        try:
            new._solver = deepcopy(self.solver)
            # Cplex has an issue with deep copies
        except Exception:  # pragma: no cover
            new._solver = copy(self.solver)  # pragma: no cover

        return new
Example #17
0
    def copy(self):
        """
        Returns a deep copy of the model.
        Overides default behaviour of cobra.Model copy which makes a breaking call to self.__class__()

        Does not copy the project or design
        :return: GSModutilsModel
        """
        new = self.__class__(self.project,
                             design=self.design,
                             mpath=self.mpath)
        do_not_copy_by_ref = {
            "metabolites", "reactions", "genes", "notes", "annotation"
        }
        for attr in self.__dict__:
            if attr not in do_not_copy_by_ref:
                new.__dict__[attr] = self.__dict__[attr]
        new.notes = deepcopy(self.notes)
        new.annotation = deepcopy(self.annotation)

        new.metabolites = DictList()
        do_not_copy_by_ref = {"_reaction", "_model"}
        for metabolite in self.metabolites:
            new_met = metabolite.__class__()
            for attr, value in iteritems(metabolite.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_met.__dict__[attr] = copy(
                        value) if attr == "formula" else value
            new_met._model = new
            new.metabolites.append(new_met)

        new.genes = DictList()
        for gene in self.genes:
            new_gene = gene.__class__(None)
            for attr, value in iteritems(gene.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_gene.__dict__[attr] = copy(
                        value) if attr == "formula" else value
            new_gene._model = new
            new.genes.append(new_gene)

        new.reactions = DictList()
        do_not_copy_by_ref = {"_model", "_metabolites", "_genes"}
        for reaction in self.reactions:
            new_reaction = reaction.__class__()
            for attr, value in iteritems(reaction.__dict__):
                if attr not in do_not_copy_by_ref:
                    new_reaction.__dict__[attr] = copy(value)
            new_reaction._model = new
            new.reactions.append(new_reaction)
            # update awareness
            for metabolite, stoic in iteritems(reaction._metabolites):
                new_met = new.metabolites.get_by_id(metabolite.id)
                new_reaction._metabolites[new_met] = stoic
                new_met._reaction.add(new_reaction)
            for gene in reaction._genes:
                new_gene = new.genes.get_by_id(gene.id)
                new_reaction._genes.add(new_gene)
                new_gene._reaction.add(new_reaction)
        try:
            new._solver = deepcopy(self.solver)
            # Cplex has an issue with deep copies
        except Exception:  # pragma: no cover
            new._solver = copy(self.solver)  # pragma: no cover

        # it doesn't make sense to retain the context of a copied model so
        # assign a new empty context
        new._contexts = list()

        return new
Example #18
0
    def add_reactions(self, reaction_list):
        """Add reactions to the model.

        Reactions with identifiers identical to a reaction already in the
        model are ignored.

        The change is reverted upon exit when using the model as a context.

        Parameters
        ----------
        reaction_list : list
            A list of `cobra.Reaction` objects
        """

        try:
            reaction_list = DictList(reaction_list)
        except TypeError:
            reaction_list = DictList([reaction_list])

        # First check whether the metabolites exist in the model
        existing = [rxn for rxn in reaction_list if rxn.id in self.reactions]
        for rxn in existing:
            LOGGER.info('skip adding reaction %s as already existing', rxn.id)
        reaction_list = [
            rxn for rxn in reaction_list if rxn.id not in existing
        ]

        context = get_context(self)

        # Add reactions. Also take care of genes and metabolites in the loop
        for reaction in reaction_list:
            reaction._reset_var_cache()
            reaction._model = self  # the reaction now points to the model
            # keys() is necessary because the dict will be modified during
            # the loop
            for metabolite in list(reaction._metabolites.keys()):
                # if the metabolite is not in the model, add it
                # should we be adding a copy instead.
                if metabolite not in self.metabolites:
                    self.add_metabolites(metabolite)
                # A copy of the metabolite exists in the model, the reaction
                # needs to point to the metabolite in the model.
                else:
                    stoichiometry = reaction._metabolites.pop(metabolite)
                    model_metabolite = self.metabolites.get_by_id(
                        metabolite.id)
                    reaction._metabolites[model_metabolite] = stoichiometry
                    model_metabolite._reaction.add(reaction)
                    if context:
                        context(
                            partial(model_metabolite._reaction.remove,
                                    reaction))

            for gene in list(reaction._genes):
                # If the gene is not in the model, add it
                if not self.genes.has_id(gene.id):
                    self.genes += [gene]
                    gene._model = self

                    if context:
                        # Remove the gene later
                        context(partial(self.genes.__isub__, [gene]))
                        context(partial(setattr, gene, '_model', None))

                # Otherwise, make the gene point to the one in the model
                else:
                    model_gene = self.genes.get_by_id(gene.id)
                    if model_gene is not gene:
                        reaction._dissociate_gene(gene)
                        reaction._associate_gene(model_gene)

        self.reactions += reaction_list

        if context:
            context(partial(self.reactions.__isub__, reaction_list))

        # from cameo ...
        self._populate_solver(reaction_list)