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
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)
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
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
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
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
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()
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
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)
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]
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
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))
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)
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
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)
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
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
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)