def dump_model(bigg_id): session = Session() # find the model model_db = (session .query(Model) .filter(Model.bigg_id == bigg_id) .first()) if model_db is None: session.commit() session.close() raise Exception('Could not find model %s' % bigg_id) model = cobra.core.Model(bigg_id) # COBRApy uses the description as the ID sometimes. See # https://github.com/opencobra/cobrapy/pull/152 model.description = bigg_id # genes logging.debug('Dumping genes') gene_names = (session .query(Gene.bigg_id, Gene.name) .join(ModelGene) .filter(ModelGene.model_id == model_db.id) .order_by(Gene.bigg_id) ) for gene_id, gene_name in gene_names: gene = cobra.core.Gene(gene_id) gene.name = gene_name model.genes.append(gene) # reactions logging.debug('Dumping reactions') reactions_db = (session .query(Reaction, ModelReaction, Synonym) .join(ModelReaction) .join(OldIDSynonym, OldIDSynonym.ome_id == ModelReaction.id) .join(Synonym, Synonym.id == OldIDSynonym.synonym_id) .filter(ModelReaction.model_id == model_db.id) .order_by(Reaction.bigg_id) ) # make dictionaries and cast results result_dicts = [] for r_db, mr_db, synonym_db in reactions_db: d = {} d['bigg_id'] = r_db.bigg_id d['name'] = r_db.name d['gene_reaction_rule'] = mr_db.gene_reaction_rule d['lower_bound'] = float(mr_db.lower_bound) d['upper_bound'] = float(mr_db.upper_bound) d['objective_coefficient'] = float(mr_db.objective_coefficient) d['original_bigg_id'] = synonym_db.synonym result_dicts.append(d) def filter_duplicates(result_dicts): """Find the reactions with multiple ModelReactions and increment names.""" tups_by_bigg_id = defaultdict(list) # for each ModelReaction for d in result_dicts: # add to duplicates tups_by_bigg_id[d['bigg_id']].append(d) # duplicates have multiple ModelReactions duplicates = {k: v for k, v in tups_by_bigg_id.iteritems() if len(v) > 1} for bigg_id, dup_dicts in duplicates.iteritems(): # add -copy1, copy2, etc. to the bigg ids for the duplicates last = bigg_id for d in dup_dicts: last = increment_id(last, 'copy') d['bigg_id'] = last return result_dicts # fix duplicates result_filtered = filter_duplicates(result_dicts) reactions = [] for result_dict in result_filtered: r = cobra.core.Reaction(result_dict['bigg_id']) r.name = result_dict['name'] r.gene_reaction_rule = result_dict['gene_reaction_rule'] r.lower_bound = result_dict['lower_bound'] r.upper_bound = result_dict['upper_bound'] r.objective_coefficient = result_dict['objective_coefficient'] r.notes = {'original_bigg_id': result_dict['original_bigg_id']} reactions.append(r) model.add_reactions(reactions) # metabolites logging.debug('Dumping metabolites') metabolites_db = \ (session .query(Component.bigg_id, Compartment.bigg_id, Component.name) .join(CompartmentalizedComponent) .join(Compartment) .join(ModelCompartmentalizedComponent) .filter(ModelCompartmentalizedComponent.model_id == model_db.id) .order_by(Component.bigg_id) ) metabolites = [] compartments = set() for component_id, compartment_id, component_name in metabolites_db: if component_id is not None and compartment_id is not None: m = cobra.core.Metabolite( id=component_id + '_' + compartment_id, compartment=compartment_id) m.name = component_name compartments.add(compartment_id) metabolites.append(m) model.add_metabolites(metabolites) # compartments compartment_db = (session.query(Compartment) .filter(Compartment.bigg_id.in_(compartments))) model.compartments = {i.bigg_id: i.name for i in compartment_db} # reaction matrix logging.debug('Dumping reaction matrix') matrix_db = (session .query(ReactionMatrix.stoichiometry, Reaction.bigg_id, Component.bigg_id, Compartment.bigg_id) # component, compartment .join(CompartmentalizedComponent) .join(Component) .join(Compartment) # reaction .join(Reaction) .join(ModelReaction) .filter(ModelReaction.model_id == model_db.id) .distinct()) # make sure we don't duplicate # load metabolites for stoich, reaction_id, component_id, compartment_id in matrix_db: try: m = model.metabolites.get_by_id(component_id + '_' + compartment_id) except KeyError: logging.warn('Metabolite not found %s in compartment %s for reaction %s' % \ (component_id, compartment_id, reaction_id)) continue # add to reactions if reaction_id in model.reactions: # check again that we don't duplicate r = model.reactions.get_by_id(reaction_id) if m not in r.metabolites: r.add_metabolites({m: float(stoich)}) else: # try incremented ids while True: reaction_id = increment_id(reaction_id, 'copy') try: # check again that we don't duplicate r = model.reactions.get_by_id(reaction_id) if m not in r.metabolites: r.add_metabolites({m: float(stoich)}) except KeyError: break session.commit() session.close() return model