def __define_instance_variables(self): """ Define instance variables :return: """ self.__universal_model = Model("universal_model") self.__swapped = [] self.__compounds_ontology = CompoundsDBAccessor() self.__compoundsAnnotationConfigs = file_utilities.read_conf_file( COMPOUNDS_ANNOTATION_CONFIGS_PATH) self.__reactionsAnnotationConfigs = file_utilities.read_conf_file( REACTIONS_ANNOTATION_CONFIGS_PATH) self.__compoundsIdConverter = CompoundsIDConverter() self.__compounds_revisor = CompoundsRevisor(self.model, self.__universal_model) biocyc.set_organism("meta") self.mapper = ModelMapper(self.model, self.__compoundsAnnotationConfigs, self.__compoundsIdConverter) self.__compounds_revisor.set_model_mapper(self.mapper) self.granulator = Granulator(self.model, self.mapper, self.__database_format, self.__compoundsIdConverter, self.__compoundsAnnotationConfigs)
def swap_from_generic(self, targets: list, components: list, same_components=False, progress_bar_processes_left=1): """ Swap compounds from a generic target and components. The algorithm acts as follows: 1st: Starts for identifying the reactions present in the requested biosynthetic pathway; 2nd: Creates a virtual model; 3rd: Calls the granulator to granulate the biosynthetic pathway; :param list<str> targets: list of lipid targets :param list<str> components: list of components :param bool same_components: boolean for same or mix of components :param int progress_bar_processes_left: :return: """ targets_generic_ontology_id, components_ont_ids = \ self.transform_targets_and_components_into_boimmg_ids(targets,components) self.__virtual_model = Model("virtual_model") self.__add_hydrogen_to_virtual_model() self.__virtual_model_mapper = ModelMapper( self.__virtual_model, self.__compoundsAnnotationConfigs, self.__compoundsIdConverter) self.__virtual_compounds_revisor = CompoundsRevisor( self.__virtual_model, self.__universal_model, self.__compoundsAnnotationConfigs) self.__virtual_compounds_revisor.set_model_mapper( self.__virtual_model_mapper) self.granulator.set_virtual_model(self.__virtual_model, self.__virtual_model_mapper, self.__virtual_compounds_revisor) for target_generic_ontology_id in targets_generic_ontology_id: biosynthesis_reactions = self.granulator.identify_biosynthesis_pathway( target_generic_ontology_id) self.__biosynthesis_reactions = deepcopy(biosynthesis_reactions) self.__add_new_reactions_to_virtual_model( self.__biosynthesis_reactions) self.__model.remove_reactions(biosynthesis_reactions) self.granulator.granulate(target_generic_ontology_id, components_ont_ids, same_components, progress_bar_processes_left) self.generateISAreactions()
def __define_instance_variables(self): """ Method to define a set of instance values :return: """ self.__swapped = [] self.lineage = [] # self.__compounds_ontology = CompoundsDBAccessor() self.__compoundsAnnotationConfigs = file_utilities.read_conf_file( COMPOUNDS_ANNOTATION_CONFIGS_PATH) self.__reactionsAnnotationConfigs = file_utilities.read_conf_file( REACTIONS_ANNOTATION_CONFIGS_PATH) self.__compoundsAnnotationConfigs = file_utilities.read_conf_file( COMPOUNDS_ANNOTATION_CONFIGS_PATH) self.__reactionsAnnotationConfigs = file_utilities.read_conf_file( REACTIONS_ANNOTATION_CONFIGS_PATH) self.__compoundsIdConverter = CompoundsIDConverter() # self.__ptw_handler_quinones = PathwayHandler(self.__modelseedCompoundsDb, self.__compoundsIdConverter) # self.__ptw_handler_quinones.load_from_file(self.__home_path__ + self.__configs["quinones_pathways"]) self.__not_to_change_classes = ["cpd03476"] self.__set_not_to_change_compounds() self.__compounds_revisor = CompoundsRevisor(self.model, self.__universal_model) biocyc.set_organism("meta") self.__swapper = MetaboliteSwapper( self.model, None, None, 0, self.__modelseedCompoundsDb, model_database=self.__database_format, compoundsIdConverter=self.__compoundsIdConverter, universal_model=self.__universal_model, not_to_change_compounds=self.__not_to_change_compounds) self.__mapper = ModelMapper(self.model, self.__compoundsAnnotationConfigs, self.__compoundsIdConverter) self.__swapper.set_model_mapper(self.__mapper) self.__compounds_revisor.set_model_mapper(self.__mapper)
class RedundantCaseSolver(RepresentationProblemSolver): def __init__(self, model, database_format): """ Class constructor :param Model model: cobrapy model :param str database_format: ModelSEED, BiGG or KEGG """ self.model = model self.objective = linear_reaction_coefficients(self.model) if self.objective: self.objective = list(self.objective.keys())[0] else: raise Exception("No objective found") self.__compounds_ontology = CompoundsDBAccessor() self.model = model self.__database_format = database_format self.__configs = file_utilities.read_conf_file(TOOL_CONFIG_PATH) self.__home_path__ = ROOT_DIR self.__modelseedCompoundsDb = ModelSeedCompoundsDB() self.__define_instance_variables() self.write_in_progress_bar("mapping model... ", 1) self.mapper.map_model(database_format) self.write_in_progress_bar("model mapped ", 10) @property def model(self): return self.__model @model.setter def model(self, value): self.__model = value @property def mapper(self): return self.__mapper @mapper.setter def mapper(self, value): self.__mapper = value def write_in_progress_bar(self, message, value): with open(PROGRESS_BAR, "w") as file: file.write(message + ":" + str(value)) def __define_instance_variables(self): """ Define instance variables :return: """ self.__universal_model = Model("universal_model") self.__swapped = [] self.__compounds_ontology = CompoundsDBAccessor() self.__compoundsAnnotationConfigs = file_utilities.read_conf_file( COMPOUNDS_ANNOTATION_CONFIGS_PATH) self.__reactionsAnnotationConfigs = file_utilities.read_conf_file( REACTIONS_ANNOTATION_CONFIGS_PATH) self.__compoundsIdConverter = CompoundsIDConverter() self.__compounds_revisor = CompoundsRevisor(self.model, self.__universal_model) biocyc.set_organism("meta") self.mapper = ModelMapper(self.model, self.__compoundsAnnotationConfigs, self.__compoundsIdConverter) self.__compounds_revisor.set_model_mapper(self.mapper) self.granulator = Granulator(self.model, self.mapper, self.__database_format, self.__compoundsIdConverter, self.__compoundsAnnotationConfigs) def __add_hydrogen_to_virtual_model(self): """ This method set searches for the hydrogen in each compartment of the model. The hydrogens are used to balance reactions. """ compartments = self.__model.compartments metabolites_in_model = self.__model.metabolites res = [] i = 0 while i < len(metabolites_in_model): metabolite = metabolites_in_model[i] if metabolite.formula == "H" and metabolite.compartment in compartments: res.append(metabolite) i += 1 self.__virtual_model.add_metabolites(res) def swap_and_gap_fill(self, target_ontology_id): pass def generalize_model(self, target_ontology_id): pass def gap_fill_model_by_target(self, target_ontology_id: int, components_ont_ids: list): pass def write_reports(self, file_path): metabolites_report_material = self.granulator.metabolite_report_material reactions_report_material = self.granulator.reaction_report_material with open(file_path, "w") as f: f.write("--Metabolites--\n") f.write("metabolite in model,replacer metabolite\n") for metabolite in metabolites_report_material: f.write(metabolite + ",") f.write(metabolites_report_material[metabolite] + "\n") f.write("--Reactions--\n") f.write("reaction in model,replacer reaction\n") for reaction in reactions_report_material: f.write(reaction + ",") f.write(reactions_report_material[reaction] + "\n") def swap_from_generic(self, targets: list, components: list, same_components=False, progress_bar_processes_left=1): """ Swap compounds from a generic target and components. The algorithm acts as follows: 1st: Starts for identifying the reactions present in the requested biosynthetic pathway; 2nd: Creates a virtual model; 3rd: Calls the granulator to granulate the biosynthetic pathway; :param list<str> targets: list of lipid targets :param list<str> components: list of components :param bool same_components: boolean for same or mix of components :param int progress_bar_processes_left: :return: """ targets_generic_ontology_id, components_ont_ids = \ self.transform_targets_and_components_into_boimmg_ids(targets,components) self.__virtual_model = Model("virtual_model") self.__add_hydrogen_to_virtual_model() self.__virtual_model_mapper = ModelMapper( self.__virtual_model, self.__compoundsAnnotationConfigs, self.__compoundsIdConverter) self.__virtual_compounds_revisor = CompoundsRevisor( self.__virtual_model, self.__universal_model, self.__compoundsAnnotationConfigs) self.__virtual_compounds_revisor.set_model_mapper( self.__virtual_model_mapper) self.granulator.set_virtual_model(self.__virtual_model, self.__virtual_model_mapper, self.__virtual_compounds_revisor) for target_generic_ontology_id in targets_generic_ontology_id: biosynthesis_reactions = self.granulator.identify_biosynthesis_pathway( target_generic_ontology_id) self.__biosynthesis_reactions = deepcopy(biosynthesis_reactions) self.__add_new_reactions_to_virtual_model( self.__biosynthesis_reactions) self.__model.remove_reactions(biosynthesis_reactions) self.granulator.granulate(target_generic_ontology_id, components_ont_ids, same_components, progress_bar_processes_left) self.generateISAreactions() def __subtract_reactions_in_list(self, reactions, reactions_to_subtract): res = [] for reaction in reactions: if reaction.id not in reactions_to_subtract: res.append(reaction) return res # def solve_components_reactions(self,same_components=False): # # self.__virtual_model = Model("virtual_model") # self.__universal_model = Model("universal_model") # # self.__virtual_model_mapper = ModelMapper(self.__virtual_model, self.__compoundsAnnotationConfigs, # self.__compoundsIdConverter) # # self.__virtual_compounds_revisor = CompoundsRevisor(self.__virtual_model, self.__universal_model, # self.__compoundsAnnotationConfigs) # # self.__virtual_compounds_revisor.set_model_mapper(self.__virtual_model_mapper) # # granulator = Granulator(self.model, self.mapper, self.__database_format, self.__modelseedCompoundsDb, # self.__compoundsIdConverter, self.__compoundsAnnotationConfigs) # # granulator.set_virtual_model(self.__virtual_model, self.__virtual_model_mapper, # self.__virtual_compounds_revisor) # # granulator.solve_components_reactions(same_components) def __add_new_reactions_to_virtual_model(self, new_reactions): self.__virtual_model_mapper.add_new_reactions_to_model(new_reactions) self.__virtual_model.add_reactions(new_reactions) def __add_new_reactions_to_model(self, new_reactions): self.mapper.add_new_reactions_to_model(new_reactions) self.model.add_reactions(new_reactions) def generateISAreactions(self): parents_and_children = self.get_parent_and_children_in_model() objective_reactants = [ reactant.id for reactant in self.objective.reactants ] reactions = [] for parent in parents_and_children: if parent in objective_reactants: for child in parents_and_children[parent]: name = "ISA_reaction_" + child id = "ISA_reaction_" + child newISAreaction = Reaction(id=id, name=name) child_cobra_container = self.model.metabolites.get_by_id( child) parent_cobra_container = self.model.metabolites.get_by_id( parent) stoichiometry = { child_cobra_container: -1, parent_cobra_container: 1 } newISAreaction.add_metabolites(stoichiometry) reactions.append(newISAreaction) self.model.add_reactions(reactions) def get_parent_and_children_in_model(self): res = {} for model_compound_id in self.mapper.boimmg_db_model_map.keys(): boimmg_id = self.mapper.boimmg_db_model_map[model_compound_id] node = self.__compounds_ontology.get_node_by_ont_id(boimmg_id) if not node.generic: parents = self.__compounds_ontology.get_successors_by_ont_id_rel_type( boimmg_id, "is_a") if parents: parent = parents[0] if parent in self.mapper.boimmg_db_model_map_reverse.keys( ): parents_in_model = self.mapper.boimmg_db_model_map_reverse[ parent] if len(parents_in_model) == 1: parent_in_model = parents_in_model[0] if parent_in_model in res: res[parent_in_model].append(model_compound_id) else: res[parent_in_model] = [model_compound_id] return res def transform_targets_and_components_into_boimmg_ids( self, targets, components): """ Conversion of components and lipid targets into BOIMMG's format :param targets: :param components: :return: """ targets_res = [] components_res = [] accessor = CompoundsDBAccessor() boimmg_prefix = self.__compoundsAnnotationConfigs[ "BOIMMG_ID_CONSTRUCTION"] for target in targets: new_target = self._transform_database_ids_into_boimmg_ids( target, accessor, boimmg_prefix) if not new_target: exit(2) targets_res.append(new_target) for component in components: new_component = self._transform_database_ids_into_boimmg_ids( component, accessor, boimmg_prefix) if not new_component: exit(2) components_res.append(new_component) return targets_res, components_res def _transform_database_ids_into_boimmg_ids(self, target: str, accessor: CompoundsDBAccessor, boimmg_prefix: str): """ Convert target lipid identifier into BOIMMG's format :param str target: :param CompoundsDBAccessor accessor: :param str boimmg_prefix: :return: """ targets_res = '' if boimmg_prefix in target: targets_res = int(target.replace(boimmg_prefix, "")) elif re.match("^[0-9]*$", target): targets_res = int(target) elif "cpd" not in target: model_seed_ids = self.__compoundsIdConverter.convert_db_id_to_model_seed_by_db_id( target) else: model_seed_ids = [target] if not targets_res: for model_seed_id in model_seed_ids: node1 = accessor.get_node_from_model_seed_id(model_seed_id) if node1: targets_res = node1.id break return targets_res
class SimpleCaseSolver(): def __init__(self, model: Model, database_format: str, db_accessor=CompoundsDBAccessor()): """ Class constructor :param Model model: model being analysed :param database_format: database format (ModelSEED, BiGG or KEGG) :param modelseed_compoundsdb: """ self.__universal_model = Model("universal_model") self.model = model self.__database_format = database_format self.__configs = file_utilities.read_conf_file(TOOL_CONFIG_PATH) self.__home_path__ = ROOT_DIR self.__compounds_ontology = db_accessor self.__modelseedCompoundsDb = ModelSeedCompoundsDB() self.__define_instance_variables() def dump_maps(self, destination: str): """ It creates a dump of all the model metabolite maps :param str destination: destination folder :return: """ self.__mapper.create_map_dump(destination) def load_maps(self, folder): """ Load all the metabolite maps in a given folder :param str folder: folder path :return: """ self.__mapper.upload_maps(folder) def map_model(self): """ Creates maps for all the metabolites in the model :return: """ start = time.time() self.write_in_progress_bar("mapping the model... ", 10) self.__mapper.map_model(self.__database_format) self.write_in_progress_bar("model mapped ", 31) finished = time.time() logger.info("mapping finished: %d" % (finished - start)) def write_in_progress_bar(self, message: str, value: float): """ Write information related to the progress bar :param str message: message of what is being done :param float value: value to assign in the progress bar :return: """ with open(PROGRESS_BAR, "w") as file: file.write(message + ":" + str(value)) def get_progress_bar_state(self) -> float: """ This method reads the progress bar message and the respective value :return float state: value to assign in the progress bar """ with open(PROGRESS_BAR, "r") as file: line = file.read() line = line.strip() state = line.split(":")[1] return float(state) def calculate_division_for_progress_bar(self, state, total_processes_left): left = 100 - state for_each_part = left / total_processes_left return for_each_part @property def model(self): return self.__model @model.setter def model(self, value): if isinstance(value, Model): self.__model = value else: raise ValueError("introduce a cobrapy model") def __define_instance_variables(self): """ Method to define a set of instance values :return: """ self.__swapped = [] self.lineage = [] # self.__compounds_ontology = CompoundsDBAccessor() self.__compoundsAnnotationConfigs = file_utilities.read_conf_file( COMPOUNDS_ANNOTATION_CONFIGS_PATH) self.__reactionsAnnotationConfigs = file_utilities.read_conf_file( REACTIONS_ANNOTATION_CONFIGS_PATH) self.__compoundsAnnotationConfigs = file_utilities.read_conf_file( COMPOUNDS_ANNOTATION_CONFIGS_PATH) self.__reactionsAnnotationConfigs = file_utilities.read_conf_file( REACTIONS_ANNOTATION_CONFIGS_PATH) self.__compoundsIdConverter = CompoundsIDConverter() # self.__ptw_handler_quinones = PathwayHandler(self.__modelseedCompoundsDb, self.__compoundsIdConverter) # self.__ptw_handler_quinones.load_from_file(self.__home_path__ + self.__configs["quinones_pathways"]) self.__not_to_change_classes = ["cpd03476"] self.__set_not_to_change_compounds() self.__compounds_revisor = CompoundsRevisor(self.model, self.__universal_model) biocyc.set_organism("meta") self.__swapper = MetaboliteSwapper( self.model, None, None, 0, self.__modelseedCompoundsDb, model_database=self.__database_format, compoundsIdConverter=self.__compoundsIdConverter, universal_model=self.__universal_model, not_to_change_compounds=self.__not_to_change_compounds) self.__mapper = ModelMapper(self.model, self.__compoundsAnnotationConfigs, self.__compoundsIdConverter) self.__swapper.set_model_mapper(self.__mapper) self.__compounds_revisor.set_model_mapper(self.__mapper) def __set_not_to_change_compounds(self): """ One would want to protect few compounds of being changed. :return: """ self.__not_to_change_compounds = [] for compound_class in self.__not_to_change_classes: parent_id = self.__compounds_ontology.get_node_id_from_model_seed_id( compound_class) children = self.__compounds_ontology.get_predecessors_by_ont_id_rel_type( parent_id, "is_a") self.__not_to_change_compounds.extend(children) def swap_compound(self, compound_in_model: str, compound_to_change: str, compounds_left=1): """ This method aims at swapping all the biosynthetic precursors, and the conjugated acid and base of a given target. It accepts all types of changes. :param str compound_in_model: compound in model :param str compound_to_change: compound to replace the one in the model :param str compounds_left: compounds left in the swapping operation :return: """ if not self.__mapper.mapped: self.map_model() compound_in_model = self.transform_input_into_boimmg_ids( compound_in_model) if not compound_to_change: exit(2) compound_to_change = self.transform_input_into_boimmg_ids( compound_to_change) if not compound_to_change: exit(2) compound_in_model_node = self.__compounds_ontology.get_node_by_ont_id( compound_in_model) compound_to_change_node = self.__compounds_ontology.get_node_by_ont_id( compound_to_change) state = self.get_progress_bar_state() per_iteration = self.calculate_division_for_progress_bar( state, compounds_left) self.write_in_progress_bar( "Swapping " + compound_in_model_node.name + " to " + compound_to_change_node.name, state) logger.info( "Swapping " + compound_in_model_node.name + " to " + compound_to_change_node.name, state) type = 0 if compound_in_model_node.generic and not compound_to_change_node.generic: parents = self.__compounds_ontology.get_successors_by_ont_id_rel_type( compound_to_change, "is_a") if compound_in_model in parents: type = 2 else: type = 3 elif compound_to_change_node.generic and not compound_in_model_node.generic: parents = self.__compounds_ontology.get_successors_by_ont_id_rel_type( compound_in_model, "is_a") if compound_to_change in parents: type = 2 else: type = 3 elif not compound_to_change_node.generic and not compound_in_model_node.generic: parents1 = self.__compounds_ontology.get_successors_by_ont_id_rel_type( compound_in_model, "is_a") parents2 = self.__compounds_ontology.get_successors_by_ont_id_rel_type( compound_to_change, "is_a") if parents1 and parents2: if parents1[0] == parents2[0]: type = 1 else: type = 2 if type != 0: self.__swapper.set_type(type) self.__swapper.set_compound_in_model(compound_in_model) self.__swapper.set_new_compound(compound_to_change) self.__swapper.swap_metabolites() else: self.__swapper.set_type(type) self.__swapper.set_compound_in_model(compound_in_model) self.__swapper.set_new_compound(compound_to_change) self.__swapper.swap_only_metabolites_and_conjugates() self.write_in_progress_bar("Swap performed", per_iteration) logger.info("Swap performed") def __check_if_compound_exists_in_model_by_ontology_id( self, ontology_id: int) -> list: """ This method will check whether a BOIMMG compound exists in the model. :param int ontology_id: BOIMMG id :return list: compounds in model """ res = [] for model_id, boimmg_id in self.__mapper.boimmg_db_model_map.items(): if boimmg_id == ontology_id: model_compound_container = self.model.metabolites.get_by_id( model_id) res.append(model_compound_container) return res def __replace_electron_donors_and_acceptors(self): """ This method will swap all the generic electron donors and acceptors eventually added when introducing MetaCyc reactions. :return: """ donor_model_seed_id = "cpd26978" electron_transfer_quinol = 749301 ontology_id = self.__compounds_ontology.get_node_id_from_model_seed_id( donor_model_seed_id) container = self.__compounds_ontology.get_node_by_ont_id(ontology_id) inchikey = container.inchikey aliases = self.__compoundsIdConverter.get_all_aliases_by_modelSeedID( donor_model_seed_id) metabolites_in_model = self.__mapper.check_metabolites_in_model( inchikey, aliases) self.__swapper.set_compound_in_model(ontology_id) self.__swapper.set_type(0) if metabolites_in_model: leaves = self.__compounds_ontology.get_leaves_from_ont_id( ontology_id) for metabolite in metabolites_in_model: compartment = metabolite.compartment found_leaf = False i = 0 while not found_leaf and i < len(leaves): parents = self.__compounds_ontology.get_all_parents( leaves[i]) if electron_transfer_quinol not in parents: leaf_container = self.__compounds_ontology.get_node_by_ont_id( leaves[i]) modelseedid = leaf_container.model_seed_id inchikey = leaf_container.inchikey aliases = self.__compoundsIdConverter.get_all_aliases_by_modelSeedID( modelseedid) metabolites_in_model_to_change = \ self.__mapper.check_metabolites_in_model(inchikey, aliases, leaf_container) found_compartment_leaf = False j = 0 while not found_compartment_leaf and j < len( metabolites_in_model_to_change): if metabolites_in_model_to_change[ j].compartment == compartment: found_compartment_leaf = True found_leaf = True self.__swapper.set_new_compound(leaves[i]) self.__swapper.swap_only_metabolites_and_conjugates( metabolite, metabolites_in_model_to_change[j]) else: j += 1 i += 1 def __swap_metabolites(self, metabolite_in_model: int, new_metabolite: int, type: int, target=False) -> list: """ This method aims at calling the MetaboliteSwapper to swap a given metabolite, their biosynthetic precursors and their conjugated base and acid, eventually. :param int metabolite_in_model: BOIMMG id of the metabolite in model :param int new_metabolite: BOIMMG id of the new metabolite :param int type: type of swap :param boolean target: whether the new metabolite is the target metabolite or not :return: """ self.__swapper.set_compound_in_model(metabolite_in_model) self.__swapper.set_new_compound(new_metabolite) self.__swapper.set_type(type) if type == 2: self.__type_2_isGeneric_setter(metabolite_in_model) if not target: changed_reactions = self.__swapper.swap_only_metabolites_and_conjugates( ) self.__swapped.append(new_metabolite) else: changed_reactions = self.__swapper.swap_metabolites() self.__universal_model = self.__swapper.get_universal_model() return changed_reactions def __type_2_isGeneric_setter(self, metabolite_in_model): container = self.__compounds_ontology.get_node_by_ont_id( metabolite_in_model) if container.generic: self.__swapper.setType2_isGenericInModel(True) else: self.__swapper.setType2_isGenericInModel(False) def __check_and_change_all_children(self, parent: int, new_metabolite: int, target=False) -> list: """ This method absorbs all the compounds of a specific chemical type and swap them into the :param new_metabolite :param int parent: BOIMMG id of the structural parent :param int new_metabolite: BOIMMG id of the metabolite that will prevail :param boolean target: whether the new metabolite is the target or not :return list: changed reactions """ children = self.__compounds_ontology.get_predecessors_by_ont_id_rel_type( parent, "is_a") changed_reactions = [] for child in children: if child != new_metabolite: child_container = self.__compounds_ontology.get_node_by_ont_id( child) aliases = AliasesTransformer.transform_boimmg_aliases_into_model_seed( child_container.aliases) model_seed_id = child_container.model_seed_id if model_seed_id: converted_aliases = self.__compoundsIdConverter.get_all_aliases_by_modelSeedID( model_seed_id) merged_aliases = self.merge_dictionaries( converted_aliases, aliases) child_in_model = self.__mapper.check_metabolites_in_model( child_container.inchikey, merged_aliases) else: child_in_model = self.__mapper.check_metabolites_in_model( child_container.inchikey, child_container.aliases, child_container) if child_in_model: changed_reactions = self.__swap_metabolites( child, new_metabolite, 1, target) return changed_reactions def convert_aliases_into_mapper_format(self, aliases): """ Such method can convert the aliases from retrieved from ModelSEED into the mapper format :param dict aliases: aliases from ModelSEED :return dict new_aliases: the converted dictionary """ new_aliases = {} for alias in aliases: if alias in self.__compoundsAnnotationConfigs.keys(): new_key = self.__compoundsAnnotationConfigs[alias] new_aliases[new_key] = aliases[alias] return new_aliases @staticmethod def merge_dictionaries(dict1, dict2): for key in dict1: if key in dict2: dict1[key].extend(dict2[key]) return dict1 def generate_new_metabolite(self, compound_container): """ Such method generates a whole new metabolite using a ModelSEED compound wrapper or a CompoundNode :param compound_container: ModelSEED compound wrapper :return list: list of newly generated metabolites """ if isinstance(compound_container, ModelSeedCompound): model_metabolites = \ model_utilities.generate_model_compounds_by_database_format(self.model, compound_container.getDbId(), self.__compoundsIdConverter, self.__modelseedCompoundsDb, self.__database_format) elif isinstance(compound_container, CompoundNode): model_metabolites = model_utilities.generate_model_compounds_by_database_format( self.model, compound_container.model_seed_id, self.__compoundsIdConverter, self.__modelseedCompoundsDb, self.__database_format) else: raise ValueError("Not expected type") self.__model.add_metabolites(model_metabolites) self.__mapper.add_new_metabolites_to_maps(model_metabolites) return model_metabolites def generate_new_boimmg_metabolite(self, boimmg_container: CompoundNode) -> list: """ Such method generates new BOIMMG compounds and adds them to the model (same compound in different compartments) :param CompoundNode boimmg_container: BOIMMG container for model addition :return list<Metabolite>: list of model metabolites in different compartments """ model_metabolites = model_utilities.generate_boimmg_metabolites( self.model, boimmg_container, self.__database_format, self.__compoundsIdConverter, self.__compoundsAnnotationConfigs, ) self.__model.add_metabolites(model_metabolites) self.__mapper.add_new_metabolites_to_maps(model_metabolites) return model_metabolites def add_metabolites_to_model(self, metabolites): for metabolite in metabolites: container = self.__compounds_ontology.get_node_by_ont_id( metabolite) metabolites_in_model = self.__mapper.check_metabolites_in_model( container.inchikey, container.aliases, container) if not metabolites_in_model: if container.model_seed_id: ms_container = self.__modelseedCompoundsDb.get_compound_by_id( container.model_seed_id) self.generate_new_metabolite(ms_container) else: self.generate_new_boimmg_metabolite(container) def transform_input_into_boimmg_ids(self, target: str) -> str: """ Method that converts a target ID from an external database into BOIMMG's :param str target: target identifier of an external database :return str: boimmg identifier """ accessor = CompoundsDBAccessor() boimmg_prefix = self.__compoundsAnnotationConfigs[ "BOIMMG_ID_CONSTRUCTION"] target_res = self._transform_database_ids_into_boimmg_ids( target, accessor, boimmg_prefix) return target_res def _transform_database_ids_into_boimmg_ids(self, target: str, accessor: CompoundsDBAccessor, boimmg_prefix: str) -> str: """ Such method transforms a target ID from an external database into BOIMMG's :param str target: target identifier from an external database :param CompoundsDBAccessor accessor: :param str boimmg_prefix: BOIMMG prefix :return: """ targets_res = '' if boimmg_prefix in target: targets_res = int(target.replace(boimmg_prefix, "")) elif re.match("^[0-9]*$", target): targets_res = int(target) elif "cpd" not in target: model_seed_ids = self.__compoundsIdConverter.convert_db_id_to_model_seed_by_db_id( target) else: model_seed_ids = [target] if not targets_res: for model_seed_id in model_seed_ids: node1 = accessor.get_node_from_model_seed_id(model_seed_id) if node1: targets_res = node1.id break return targets_res