Source code for geckopy.reaction

# Copyright 2021 Ginkgo Bioworks

# 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.

"""Extend cobra.Reaction to point to proteins."""

from typing import Optional

import cobra

from .protein import Protein


[docs]class Reaction(cobra.Reaction): """geckopy.Reaction has an additional attribute `.proteins`.""" @property
[docs] def proteins(self): """Retrieve metabolites participating in the reaction that are proteins.""" return { met: stoich for met, stoich in self._metabolites.copy().items() if isinstance(met, Protein)
}
[docs] def add_protein( self, id: str, kcat: float, concentration: Optional[float] = None, name: Optional[str] = None, ): """Add a protein to the reaction. Parameters ========== id: str kcat: float (1/s) concentration: float name: str """ prot_id = str(id) name = name if name is not None else prot_id prot = Protein(prot_id, name=name) coefficient = -1 / (kcat * 3600) prot.add_concentration(concentration) _id_to_metabolites = {x.id: x for x in self._metabolites} if prot_id in _id_to_metabolites: self._metabolites[_id_to_metabolites[prot_id]] = coefficient else: # If the reaction is in a model, ensure we aren't using # a duplicate metabolite. if self._model: try: prot = self._model.proteins.get_by_id(prot_id) except KeyError: pass self._metabolites[prot] = coefficient # make the metabolite aware that it is involved in this # reaction prot._reaction.add(self) # from cameo ... model = self.model if model is not None: model.add_proteins([prot]) # the protein is added to both sides of the reaction in case the # latter is reversible (it has to be consumed in both cases) model.constraints[prot.id].set_linear_coefficients( { self.forward_variable: coefficient, self.reverse_variable: coefficient,
} ) # context = get_context(self) # if context and reversibly: # if combine: # # Just subtract the metabolites that were added # context( # partial( # self.subtract_metabolites, # metabolites_to_add, # combine=True, # reversibly=False, # ) # ) # else: # # Reset them with add_metabolites # mets_to_reset = { # key: old_coefficients[model.metabolites.get_by_any(key)[0]] # for key in iterkeys(metabolites_to_add) # } # context( # partial( # self.add_metabolites, # mets_to_reset, # combine=False, # reversibly=False, # ) # )