def save_sbml(filename, model, y0=None, volume=1.0, is_valid=True): """ Save a model in the SBML format. Parameters ---------- model : NetworkModel y0 : dict Initial condition. volume : Real or Real3, optional A size of the simulation volume. is_valid : bool, optional Check if the generated model is valid. True as a default. """ y0 = y0 or {} import libsbml document = export_sbml(model, y0, volume, is_valid) # with open(filename, 'w') as fout: # fout.write(libsbml.writeSBMLToString(document)) # writer = libsbml.SBMLWriter() # writer.writeSBML(document, filename) libsbml.writeSBML(document, filename)
def createFluxObj(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.genericModel('RetroPath_heterologous_pathway', 'rp_model', self.compXref) for meta in set([ i for step in steps for lr in ['left', 'right'] for i in step[lr] ]): try: inchi = rp_inchi[meta] except KeyError: inchi = None try: smiles = rp_smiles[meta] except KeyError: smiles = None rpsbml.createSpecies(meta, self.chemXref, None, inchi, smiles, 'MNXC3', 0, '') rpsbml.createPathway(path_id) step_id = 0 for stepNum in range(len(steps)): rpsbml.createReaction('RP_' + str(stepNum), 'B_999999', 'B__999999', steps[stepNum], reaction_smiles[stepNum], self.reacXref, 'testRid', 0.0, None, rpsbml.hetero_group, None) step_id += 1 rpsbml.createFluxObj('flux1', 'RP_1', 2.0, True) libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createFluxObj.sbml')
def test_WriteL3SBML_zip(self): file = [] file.append("../../../examples/sample-models/from-spec/level-3/algebraicrules.xml") file.append("../../../examples/sample-models/from-spec/level-3/assignmentrules.xml") file.append("../../../examples/sample-models/from-spec/level-3/boundarycondition.xml") file.append("../../../examples/sample-models/from-spec/level-3/delay.xml") file.append("../../../examples/sample-models/from-spec/level-3/dimerization.xml") file.append("../../../examples/sample-models/from-spec/level-3/enzymekinetics.xml") file.append("../../../examples/sample-models/from-spec/level-3/events.xml") file.append("../../../examples/sample-models/from-spec/level-3/functiondef.xml") file.append("../../../examples/sample-models/from-spec/level-3/multicomp.xml") file.append("../../../examples/sample-models/from-spec/level-3/overdetermined.xml") file.append("../../../examples/sample-models/from-spec/level-3/twodimensional.xml") file.append("../../../examples/sample-models/from-spec/level-3/units.xml") zipfile = "test.xml.zip" for f in file: d = libsbml.readSBML(f) self.assert_( d != None ) if not libsbml.SBMLWriter.hasZlib(): self.assert_( libsbml.writeSBML(d,zipfile) == 0 ) d = None continue result = libsbml.writeSBML(d,zipfile) self.assertEqual( 1, result ) dg = libsbml.readSBML(zipfile) self.assert_( dg != None ) self.assert_( ( dg.toSBML() != d.toSBML() ) == False ) d = None dg = None pass
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename, sbml_level=2, sbml_version=1, print_time=False, use_fbc_package=True): """Write a cobra.Model object to an SBML XML file. cobra_model: :class:`~cobra.core.Model.Model` object sbml_filename: The file to write the SBML XML to. sbml_level: 2 is the only level supported at the moment. sbml_version: 1 is the only version supported at the moment. use_fbc_package: Boolean. Convert the model to the FBC package format to improve portability. http://sbml.org/Documents/Specifications/SBML_Level_3/Packages/Flux_Balance_Constraints_(flux) TODO: Update the NOTES to match the SBML standard and provide support for Level 2 Version 4 """ sbml_doc = get_libsbml_document(cobra_model, sbml_level=sbml_level, sbml_version=sbml_version, print_time=print_time, use_fbc_package=use_fbc_package) writeSBML(sbml_doc, sbml_filename)
def createMergeModels(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.genericModel('RetroPath_heterologous_pathway', 'rp_model', self.compXref) for meta in set([ i for step in steps for lr in ['left', 'right'] for i in step[lr] ]): try: inchi = rp_inchi[meta] except KeyError: inchi = None try: smiles = rp_smiles[meta] except KeyError: smiles = None rpsbml.createSpecies(meta, self.chemXref, None, inchi, smiles, 'MNXC3', 0, '') rp_pathway = rpsbml.createPathway(path_id) #reactions step_id = 0 for stepNum in range(len(steps)): rpsbml.createReaction('RP_' + str(stepNum), 'B_999999', 'B__999999', steps[stepNum], reaction_smiles[stepNum], self.reacXref, 'testRid', 0.0, None, rpsbml.hetero_group, None) step_id += 1 #other model document = libsbml.readSBML(self.outputPath + 'bigg_iMM904.COBRA-sbml3.xml') model = document.getModel() rpsbml.mergeModels(model) libsbml.writeSBML(document, self.outputPath + 'test_mergeModels.sbml')
def createUnit(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.createModel('RetroPath_heterologous_pathway', 'rp_model') unitDef = rpsbml.createUnitDefinition('mmol_per_gDW_per_hr') rpsbml.createUnit(unitDef, libsbml.UNIT_KIND_MOLE, 1, -3, 1) rpsbml.createUnit(unitDef, libsbml.UNIT_KIND_GRAM, 1, 0, 1) rpsbml.createUnit(unitDef, libsbml.UNIT_KIND_SECOND, 1, 0, 3600) libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createUnit.sbml')
def main(args): """Usage: replaceOneFD filename functionDefinitionId reactionId outfile """ if (len(args) != 5): print( "Usage: replaceOneFD filename functionDefinitionId reactionId outfile" ) return 1 filename = args[1] outFile = args[4] functionDefinitionId = args[2] reactionId = args[3] document = libsbml.readSBML(filename) if (document.getNumErrors(libsbml.LIBSBML_SEV_ERROR) > 0): print( "The models contains errors, please correct them before continuing." ) document.printErrors() return 1 model = document.getModel() functionDefinition = model.getFunctionDefinition(functionDefinitionId) if (functionDefinition == None): print() print("No functiondefinition with the given id can be found.") return 1 reaction = model.getReaction(reactionId) if (reaction == None): print() print("No reaction with the given id can be found.") return 1 if (reaction.isSetKineticLaw() == False or reaction.getKineticLaw().isSetMath() == False): print() print("The reaction has no math set. ") return 1 # Until here it was all setup, all we needed was an ASTNode, in which we wanted to # replace calls to a function definition, with the function definitions content. # libsbml.SBMLTransforms.replaceFD(reaction.getKineticLaw().getMath(), functionDefinition) # finally write to file libsbml.writeSBML(document, outFile)
def write_sbml(self, outfile = ''): if not outfile: outfile = self.filename + '.xml' docu = libsbml.SBMLDocument() model = docu.createModel() model.setId(self.id) model.setName(self.pathway) model.setAnnotation( "a pathway from MetaFishNet project") """ ectype = libsbml.SpeciesType("enzyme") cpdtype = libsbml.SpeciesType("compound") model.addSpeciesType(ectype) model.addSpeciesType(cpdtype) """ ectype = model.createSpeciesType() ectype.setId("enzyme") cpdtype = model.createSpeciesType() cpdtype.setId("compound") for ec in self.eclist: sp = model.createSpecies() sp.setId(sidify(ec)) sp.setName(ec) sp.setSpeciesType("enzyme") for cpd in self.cmpds: ss = model.createSpecies() ss.setId(sidify(cpd)) ss.setName(cpd) ss.setSpeciesType("compound") for rxn in self.rxns: sbmrxn = model.createReaction() sbmrxn.setId(rxn.ID) m = sbmrxn.createModifier() if rxn.ecstr: m.setId(sidify(rxn.ecstr)) #m.setName(rxn.ecstr) for sub in rxn.reactants: r = sbmrxn.createReactant() r.setId(sidify(sub)) for prd in rxn.products: p = sbmrxn.createProduct() p.setId(sidify(prd)) #docu.setModel(model) libsbml.writeSBML(docu, outfile)
def writeExampleSBML(sbmlDoc, filename): result = libsbml.writeSBML(sbmlDoc, filename) if result == 1: print ("Wrote file '" + filename + "'") return True else: print ("Failed to write '" + filename + "'") return False
def main (args): """Usage: replaceOneFD filename functionDefinitionId reactionId outfile """ if (len(args) != 5): print("Usage: replaceOneFD filename functionDefinitionId reactionId outfile"); return 1; filename = args[1]; outFile = args[4]; functionDefinitionId = args[2]; reactionId = args[3]; document = libsbml.readSBML(filename); if (document.getNumErrors(libsbml.LIBSBML_SEV_ERROR) > 0): print("The models contains errors, please correct them before continuing."); document.printErrors(); return 1; model = document.getModel(); functionDefinition = model.getFunctionDefinition(functionDefinitionId); if (functionDefinition == None): print(); print("No functiondefinition with the given id can be found."); return 1; reaction = model.getReaction(reactionId); if (reaction == None): print(); print("No reaction with the given id can be found."); return 1; if (reaction.isSetKineticLaw() == False or reaction.getKineticLaw().isSetMath()== False): print(); print("The reaction has no math set. "); return 1; # Until here it was all setup, all we needed was an ASTNode, in which we wanted to # replace calls to a function definition, with the function definitions content. # libsbml.SBMLTransforms.replaceFD(reaction.getKineticLaw().getMath(), functionDefinition); # finally write to file libsbml.writeSBML(document, outFile);
def convert(self, kgml, sbml): """input kgml file, output sbml file""" w = open(kgml) tree = ElementTree.parse(w) note_dict = dict(tree.getroot().items()) model = self.docu.createModel() model.setName(note_dict['name']) model.setAnnotation(self.d2note(note_dict)) rxns = tree.findall('reaction') rlist = [self.parseRxn(x) for x in rxns] all_enzymes, all_cpds = [], [] for r in rlist: all_enzymes += r.enzymes all_cpds += r.cpds all_enzymes, all_cpds = set(all_enzymes), set(all_cpds) for ec in all_enzymes: sp = model.createSpecies() sp.setId(sidify(ec)) sp.setName(ec) sp.setSpeciesType("enzyme") for cpd in all_cpds: ss = model.createSpecies() ss.setId(sidify(cpd)) ss.setName(cpd) ss.setSpeciesType("compound") for rxn in rlist: sbmrxn = model.createReaction() sbmrxn.setName(rxn.ID) for enz in rxn.enzymes: m = sbmrxn.createModifier() m.setId(sidify(enz)) for sub in rxn.reactants: r = sbmrxn.createReactant() r.setId(sidify(sub)) for prd in rxn.products: p = sbmrxn.createProduct() p.setId(sidify(prd)) libsbml.writeSBML(self.docu, sbml)
def createSpecies(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.genericModel('RetroPath_heterologous_pathway', 'rp_model', self.compXref) for meta in set([ i for step in steps for lr in ['left', 'right'] for i in step[lr] ]): try: inchi = rp_inchi[meta] except KeyError: inchi = None try: smiles = rp_smiles[meta] except KeyError: smiles = None rpsbml.createSpecies(meta, self.chemXref, None, inchi, smiles, 'MNXC3', 0, '') libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createSpecies.sbml')
def write_sbml_file(self, filename, **kwargs): self.set_volumes() if self.volume: kwargs['volume'] = self.volume document, _ = self.crn.generate_sbml_model(**kwargs) else: document, _ = self.crn.generate_sbml_model(**kwargs) if document.getNumErrors() and self.warning_print: warnings.warn('SBML document has errors. It is recommended that you fix them before generating this model.') status = libsbml.writeSBML(document, filename) if status == libsbml.LIBSBML_OPERATION_SUCCESS: print('SBML file written successfully to {0}'.format(filename)) return document
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename, sbml_level=2, sbml_version=1, print_time=False, use_fbc_package=True): """Write a cobra.Model object to an SBML XML file. Parameters ---------- cobra_model : cobra.core.Model.Model The model object to write sbml_filename : string The file to write the SBML XML to. sbml_level : int 2 is the only supported level. sbml_version : int 1 is the only supported version. print_time : bool deprecated use_fbc_package : bool Convert the model to the FBC package format to improve portability. http://sbml.org/Documents/Specifications/SBML_Level_3/Packages/Flux_Balance_Constraints_(flux) Notes ----- TODO: Update the NOTES to match the SBML standard and provide support for Level 2 Version 4 """ if not libsbml: raise ImportError('write_cobra_model_to_sbml_file ' 'requires python-libsbml') sbml_doc = get_libsbml_document(cobra_model, sbml_level=sbml_level, sbml_version=sbml_version, print_time=print_time, use_fbc_package=use_fbc_package) libsbml.writeSBML(sbml_doc, sbml_filename)
def save_sbml(filename, model, y0={}, volume=1.0): """ Save a model in the SBML format. Parameters ---------- model : NetworkModel or ODENetworkModel y0 : dict Initial condition. volume : Real or Real3, optional A size of the simulation volume. """ import libsbml document = export_sbml(model, y0, volume) # with open(filename, 'w') as fout: # fout.write(libsbml.writeSBMLToString(document)) # writer = libsbml.SBMLWriter() # writer.writeSBML(document, filename) libsbml.writeSBML(document, filename)
def main (args): """Usage: printNotes filename """ if (len(args) != 3): print("Usage: inlineInitialAssignments filename outFile"); return 1; filename = args[1]; outFile = args[2]; document = libsbml.readSBML(filename); if (document.getNumErrors(libsbml.LIBSBML_SEV_ERROR) > 0): print("The models contains errors, please correct them before continuing."); document.printErrors(); return 1; model = document.getModel(); libsbml.SBMLTransforms.expandInitialAssignments(model); libsbml.writeSBML(document, outFile);
def main(args): """Usage: printNotes filename """ if (len(args) != 3): print("Usage: inlineInitialAssignments filename outFile") return 1 filename = args[1] outFile = args[2] document = libsbml.readSBML(filename) if (document.getNumErrors(libsbml.LIBSBML_SEV_ERROR) > 0): print( "The models contains errors, please correct them before continuing." ) document.printErrors() return 1 model = document.getModel() libsbml.SBMLTransforms.expandInitialAssignments(model) libsbml.writeSBML(document, outFile)
def save_sbml(filename, model, y0=None, volume=1.0): """ Save a model in the SBML format. Parameters ---------- model : NetworkModel or ODENetworkModel y0 : dict Initial condition. volume : Real or Real3, optional A size of the simulation volume. """ y0 = y0 or {} import libsbml document = export_sbml(model, y0, volume) # with open(filename, 'w') as fout: # fout.write(libsbml.writeSBMLToString(document)) # writer = libsbml.SBMLWriter() # writer.writeSBML(document, filename) libsbml.writeSBML(document, filename)
def write_sbml_file(self, filename, **kwargs): warnings.warn( "CRNLab is deprecated and will cease to function with future releases: to save a CRN to SBML, please use ChemicalReactionNetwork.write_sbml_file()", DeprecationWarning) self.set_volumes() if self.volume: kwargs['volume'] = self.volume document, _ = self.crn.generate_sbml_model(**kwargs) else: document, _ = self.crn.generate_sbml_model(**kwargs) if document.getNumErrors() and self.warning_print: warnings.warn( 'SBML document has errors. It is recommended that you fix them before generating this model.' ) status = libsbml.writeSBML(document, filename) if status == libsbml.LIBSBML_OPERATION_SUCCESS: print('SBML file written successfully to {0}'.format(filename)) return document
def to_SBML_l2v1(from_name, to_name): """ Convert an SBML file to level 2, version 1 using lisbml. from_name Name of file to read SBML from. to_name File to output SBML to. """ doc = libsbml.readSBML(os.path.abspath(from_name)) if isinstance(doc, int): logger.critical('Fatal Errors reading SBML from file %s!' % from_name) _print_sbml_fatals(doc) errors = doc.setLevel(2) if errors: logger.critical('Fatal Errors converting %f to level 2!' % from_name) _print_sbml_fatals(doc) errors = doc.setVersion(1) if errors: logger.critical('Fatal Errors converting %f to level 2, version 1!' % from_name) _print_sbml_fatals(doc) success = libsbml.writeSBML(doc, to_name) if not success: logger.critical('Error writing to %s' % to_name)
sbml_model = sbml_doc.getModel() for par in sbml_model.getListOfParameters(): if par.getName() == 'pPROT': phosphoId = par.getId() phosphoRule = \ sbml_model.getAssignmentRuleByVariable( phosphoId ).getFormula() totalId = [ par.getId() for par in sbml_model.getListOfParameters() if par.getName() == 'tPROT' ][0] totalRule = \ sbml_model.getAssignmentRuleByVariable( totalId ).getFormula() new_phosphoRule = '(' + phosphoRule + ')/(' + totalRule + ')' sbml_model.getAssignmentRuleByVariable(phosphoId).setFormula( new_phosphoRule) sbml_model.getAssignmentRuleByVariable(totalId).removeFromParentAndDelete() sbml_model.getParameter(totalId).removeFromParentAndDelete() libsbml.writeSBML(sbml_doc, outfile)
def createModel(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.createModel('RetroPath_heterologous_pathway', 'rp_model') libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createModel.sbml')
def printSBML(self, ofile, ver=['2', '3']): ''' Output the model to SBML. LibSBML must be installed. Arguments -- ofile: if specifed, output to this file ver: version of SBML ''' if sbml: p, r, s, v = self.parameters, self.reactions, self.species, self.variables # preliminaries: including SBML version, such as 2.3 document = libsbml.SBMLDocument(eval(ver[0]), eval(ver[1])) model = document.createModel() c = model.createCompartment() c.setId('cell') c.setVolume(1.0) # create species for spec in self.alphspecies: ss = model.createSpecies() ss.setId(spec) ss.setCompartment('cell') ss.setInitialAmount(eval(s[spec]['initial amount'])) # create parameters for par in p.keys(): pp = model.createParameter() pp.setId(par) pp.setConstant(True) pp.setValue(eval(p[par]['value'])) # variables must first be defined as parameters for var in v.keys(): pp = model.createParameter() pp.setId(var) pp.setConstant(False) # define all rate constants as parameters for reac in r.keys(): rvalue = r[reac]['rate value'] if rvalue: # a new rate constant is defined newrate = r[reac]['rate constant'] pp = model.createParameter() pp.setId(newrate) if self.isfloat(rvalue): # defined numerically pp.setConstant(True) pp.setValue(eval(rvalue)) else: # defined algebraically pp.setConstant(False) vv = model.createAssignmentRule() value = libsbml.parseFormula(rvalue) vv.setVariable(newrate) vv.setMath(value) # create variables for var in v.keys(): vv = model.createAssignmentRule() value = libsbml.parseFormula(v[var]['value']) vv.setVariable(var) vv.setMath(value) # create reactions for reac in r.keys(): rr = model.createReaction() rr.setId('r_' + reac) rr.setCompartment('cell') rr.setReversible(False) for i in range(len(r[reac]['reactants'])): rrr = rr.createReactant() rrr.setSpecies(r[reac]['reactants'][i]) for i in range(len(r[reac]['products'])): rrp = rr.createProduct() rrp.setSpecies(r[reac]['products'][i]) if r[reac]['mass action']: # find rate by mass action rrate = r[reac]['rate constant'] for reactant in r[reac]['reactants']: rrate += '*' + reactant mods = self.findmodifiers(rrate, exclude=list( set(r[reac]['reactants']))) else: # rate already specified rrate = r[reac]['rate constant'] mods = self.findmodifiers(rrate) # add modifiers for mod in mods: mdf = rr.createModifier() mdf.setSpecies(mod) rrk = rr.createKineticLaw() rrk.setFormula(rrate) # write file document.setModel(model) if ofile: libsbml.writeSBMLToFile(document, ofile + '.xml') else: libsbml.writeSBML(document, sys.stdout) else: print( 'sencillo: libSBML cannot be imported. SBML cannot be created.' )
# olevel = document.getLevel(); oversion = document.getVersion(); success = False; outputFile = os.path.join(d, modelfile.replace('l3v1', 'l2v4')) print ("Attempting to convert Level " + str(olevel) + " Version " + str(oversion) + " model to Level 2 Version 4." + "\n", file=sys.stderr); success = document.setLevelAndVersion(2, 4); errors = document.getNumErrors(); if (not success): print("Unable to perform conversion due to the following:" + "\n", file=sys.stderr); document.printErrors(); print("\n", file=sys.stderr); print("Conversion skipped. Either libSBML does not (yet)" + "\n" + "have the ability to convert this model or (automatic)" + "\n" + "conversion is not possible in this case." + "\n", file=sys.stderr); break elif (errors > 0): print("Information may have been lost in conversion; but a valid model ", file=sys.stderr); print("was produced by the conversion.\nThe following information ", file=sys.stderr); print("was provided:\n", file=sys.stderr); document.printErrors(); writeSBML(document, outputFile); else: print("Conversion completed." + "\n", file=sys.stderr); writeSBML(document, outputFile);
def createCompartent(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.createModel('RetroPath_heterologous_pathway', 'rp_model') rpsbml.createCompartment(1, 'MNXC3', 'cytoplasm', self.compXref) libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createCompartent.sbml')
def genericModel(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.genericModel('RetroPath_heterologous_pathway', 'rp_model', self.compXref) libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_genericModel.sbml')
print("Attempting to convert Level " + str(olevel) + " Version " + str(oversion) + " model to Level 2 Version 4." + "\n", file=sys.stderr) success = document.setLevelAndVersion(2, 4) errors = document.getNumErrors() if (not success): print("Unable to perform conversion due to the following:" + "\n", file=sys.stderr) document.printErrors() print("\n", file=sys.stderr) print("Conversion skipped. Either libSBML does not (yet)" + "\n" + "have the ability to convert this model or (automatic)" + "\n" + "conversion is not possible in this case." + "\n", file=sys.stderr) break elif (errors > 0): print( "Information may have been lost in conversion; but a valid model ", file=sys.stderr) print("was produced by the conversion.\nThe following information ", file=sys.stderr) print("was provided:\n", file=sys.stderr) document.printErrors() writeSBML(document, outputFile) else: print("Conversion completed." + "\n", file=sys.stderr) writeSBML(document, outputFile)
def saveAsSBML( self, filename ): aSBMLDocument = self.convertEMLToSBML() libsbml.writeSBML( aSBMLDocument, filename )
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename, sbml_level=2, sbml_version=1, print_time=False, use_fbc_package=True): """Write a cobra.Model object to an SBML XML file. cobra_model: :class:`~cobra.core.Model.Model` object sbml_filename: The file to write the SBML XML to. sbml_level: 2 is the only level supported at the moment. sbml_version: 1 is the only version supported at the moment. use_fbc_package: Boolean. Convert the model to the FBC package format to improve portability. http://sbml.org/Documents/Specifications/SBML_Level_3/Packages/Flux_Balance_Constraints_(flux) TODO: Update the NOTES to match the SBML standard and provide support for Level 2 Version 4 """ note_start_tag, note_end_tag = '<p>', '</p>' if sbml_level > 2 or (sbml_level == 2 and sbml_version == 4): note_start_tag, note_end_tag = '<html:p>', '</html:p>' sbml_doc = SBMLDocument(sbml_level, sbml_version) sbml_model = sbml_doc.createModel(cobra_model.id.split('.')[0]) #Note need to set units reaction_units = 'mmol_per_gDW_per_hr' model_units = sbml_model.createUnitDefinition() model_units.setId(reaction_units) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_MOLE) sbml_unit.setScale(-3) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_GRAM) sbml_unit.setExponent(-1) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_SECOND) sbml_unit.setMultiplier(1.0 / 60 / 60) sbml_unit.setExponent(-1) #Add in the common compartment abbreviations. If there are additional compartments #they also need to be added. if not cobra_model.compartments: cobra_model.compartments = { 'c': 'cytosol', 'p': 'periplasm', 'e': 'extracellular' } for the_key in cobra_model.compartments.keys(): sbml_comp = sbml_model.createCompartment() sbml_comp.setId(the_key) sbml_comp.setName(cobra_model.compartments[the_key]) sbml_comp.setSize(1) #Just to get rid of warnings if print_time: warn("print_time is deprecated") #Use this dict to allow for fast look up of species id #for references created in the reaction section. metabolite_dict = {} for cobra_metabolite in cobra_model.metabolites: metabolite_dict[cobra_metabolite.id] = add_sbml_species( sbml_model, cobra_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag) for the_reaction in cobra_model.reactions: #This is probably the culprit. Including cobra.Reaction #objects explicitly in cobra.Model will speed this up. sbml_reaction = sbml_model.createReaction() #Need to remove - for proper SBML. Replace with __ the_reaction_id = 'R_' + the_reaction.id.replace('-', '__') sbml_reaction.setId(the_reaction_id) # The reason we are not using the Reaction.reversibility property # is because the SBML definition of reversibility does not quite # match with the cobra definition. In cobra, reversibility implies # that both positive and negative flux values are feasible. However, # SBML requires negative-flux-only reactions to still be classified # as reversible. To quote from the SBML Level 3 Version 1 Spec: # > However, labeling a reaction as irreversible is interpreted as # > an assertion that the rate expression will not have negative # > values during a simulation. # (Page 60 lines 44-45) sbml_reaction.setReversible(the_reaction.lower_bound < 0) if the_reaction.name: sbml_reaction.setName(the_reaction.name) else: sbml_reaction.setName(the_reaction.id) #Add in the reactant/product references for the_metabolite, the_coefficient in the_reaction._metabolites.items( ): sbml_stoichiometry = the_coefficient metabolite_id = str(metabolite_dict[the_metabolite.id]) #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Deal with the case where the reaction is a boundary reaction if len(the_reaction._metabolites) == 1: the_metabolite, the_coefficient = list( the_reaction._metabolites.items())[0] metabolite_id = add_sbml_species(sbml_model, the_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag, boundary_metabolite=True) sbml_stoichiometry = -the_coefficient #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Add in the kineticLaw sbml_law = KineticLaw(sbml_level, sbml_version) if hasattr(sbml_law, 'setId'): sbml_law.setId('FLUX_VALUE') sbml_law.setFormula('FLUX_VALUE') reaction_parameter_dict = { 'LOWER_BOUND': [the_reaction.lower_bound, reaction_units], 'UPPER_BOUND': [the_reaction.upper_bound, reaction_units], 'FLUX_VALUE': [0, reaction_units], 'OBJECTIVE_COEFFICIENT': [the_reaction.objective_coefficient, 'dimensionless'] } for k, v in reaction_parameter_dict.items(): sbml_parameter = Parameter(sbml_level, sbml_version) sbml_parameter.setId(k) if hasattr(v, '__iter__'): sbml_parameter.setValue(v[0]) sbml_parameter.setUnits(v[1]) else: sbml_parameter.setValue(v) sbml_law.addParameter(sbml_parameter) sbml_reaction.setKineticLaw(sbml_law) sbml_reaction.setNotes( '<html xmlns="http://www.w3.org/1999/xhtml">%sGENE_ASSOCIATION: %s%s%sSUBSYSTEM: %s%s</html>' % (note_start_tag, the_reaction.gene_reaction_rule, note_end_tag, note_start_tag, the_reaction.subsystem, note_end_tag)) if use_fbc_package: try: from libsbml import ConversionProperties, LIBSBML_OPERATION_SUCCESS conversion_properties = ConversionProperties() conversion_properties.addOption("convert cobra", True, "Convert Cobra model") result = sbml_doc.convert(conversion_properties) if result != LIBSBML_OPERATION_SUCCESS: raise Exception("Conversion of COBRA to SBML+fbc failed") except Exception as e: error_string = 'Error saving as SBML+fbc. %s' try: #Check whether the FbcExtension is there from libsbml import FbcExtension error_string = error_string % e except ImportError: error_string = error_string%'FbcExtension not available in libsbml. ' +\ 'If use_fbc_package == True then libsbml must be compiled with ' +\ 'the fbc extension. ' from libsbml import getLibSBMLDottedVersion _sbml_version = getLibSBMLDottedVersion() _major, _minor, _patch = map(int, _sbml_version.split('.')) if _major < 5 or (_major == 5 and _minor < 8): error_string += "You've got libsbml %s installed. You need 5.8.0 or later with the fbc package" raise (Exception(error_string)) writeSBML(sbml_doc, sbml_filename)
def createUnitDefinition(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.createModel('RetroPath_heterologous_pathway', 'rp_model') unitDef = rpsbml.createUnitDefinition('mmol_per_gDW_per_hr') libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createUnitDefinition.sbml')
def enzyme_note(enzyme_list): result = '<body xmlns="http://www.w3.org/1999/xhtml"><p>GENE_ASSOCIATION: (' result += ' and '.join(enzyme_list) return result + ')</p></body>\n' if __name__ == "__main__": # read sbml sbml = libsbml.readSBML('metabolism.xml') # update metabolite names for s in sbml.model.species: s.setId(metabolite_name(s.id)) for r in sbml.model.reactions: for sr in itertools.chain(r.reactants, r.products): sr.setSpecies(metabolite_name(sr.species)) # add notes with enzyme compositions enzymes = etree.parse('enzymes.xml') enzyme_list = {} for e in enzymes.iterfind('listOfEnzymes/enzyme'): id_ = e.attrib['id'] enzyme_list[id_] = [ sr.attrib['species'] for sr in e.find('machineryComposition/listOfReactants') if not sr.attrib['species'].startswith('m_') ] for r in sbml.model.reactions: r.setNotes(enzyme_note(enzyme_list[r.id])) # write sbml libsbml.writeSBML(sbml, 'sbml.xml')
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename, sbml_level=2, sbml_version=1, print_time=False): """Write a cobra.Model object to an SBML XML file. cobra_model: A cobra.Model object sbml_filename: The file to write the SBML XML to. sbml_level: 2 is the only level supported at the moment. sbml_version: 1 is the only version supported at the moment. print_time: Boolean. Print the time requirements for different sections TODO: Update the NOTES to match the SBML standard and provide support for Level 2 Version 4 """ note_start_tag, note_end_tag = '<p>', '</p>' if sbml_level > 2 or (sbml_level == 2 and sbml_version == 4): note_start_tag, note_end_tag = '<html:p>', '</html:p>' sbml_doc = SBMLDocument(sbml_level, sbml_version) sbml_model = sbml_doc.createModel(cobra_model.description.split('.')[0]) #Note need to set units reaction_units = 'mmol_per_gDW_per_hr' model_units = sbml_model.createUnitDefinition() model_units.setId(reaction_units) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_MOLE) sbml_unit.setScale(-3) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_GRAM) sbml_unit.setExponent(-1) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_SECOND) sbml_unit.setMultiplier(1.0 / 60 / 60) sbml_unit.setExponent(-1) #Add in the common compartment abbreviations. If there are additional compartments #they also need to be added. if not cobra_model.compartments: cobra_model.compartments = { 'c': 'cytosol', 'p': 'periplasm', 'e': 'extracellular' } for the_key in cobra_model.compartments.keys(): sbml_comp = sbml_model.createCompartment() sbml_comp.setId(the_key) sbml_comp.setName(cobra_model.compartments[the_key]) sbml_comp.setSize(1) #Just to get rid of warnings if print_time: start_time = time() #Use this dict to allow for fast look up of species id #for references created in the reaction section. metabolite_dict = {} for cobra_metabolite in cobra_model.metabolites: metabolite_dict[cobra_metabolite.id] = add_sbml_species( sbml_model, cobra_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag) if print_time: print 'Adding %s took %1.2f seconds' % ('metabolites', time() - start_time) if print_time: start_time = time() for the_reaction in cobra_model.reactions: #This is probably the culprit. Including cobra.Reaction #objects explicitly in cobra.Model will speed this up. sbml_reaction = sbml_model.createReaction() #Need to remove - for proper SBML. Replace with __ the_reaction_id = 'R_' + the_reaction.id.replace('-', '__') sbml_reaction.setId(the_reaction_id) sbml_reaction.setReversible(the_reaction.reversibility) if the_reaction.name: sbml_reaction.setName(the_reaction.name) else: sbml_reaction.setName(the_reaction.id) #Add in the reactant/product references for the_metabolite, the_coefficient in the_reaction._metabolites.items( ): sbml_stoichiometry = the_coefficient metabolite_id = str(metabolite_dict[the_metabolite.id]) #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Deal with the case where the reaction is a boundary reaction if len(the_reaction._metabolites) == 1: the_metabolite, the_coefficient = the_reaction._metabolites.items( )[0] the_metabolite = the_metabolite.copy() metabolite_id = add_sbml_species(sbml_model, the_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag, boundary_metabolite=True) sbml_stoichiometry = -the_coefficient #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Add in the kineticLaw sbml_law = KineticLaw(sbml_level, sbml_version) if hasattr(sbml_law, 'setId'): sbml_law.setId('FLUX_VALUE') sbml_law.setFormula('FLUX_VALUE') reaction_parameter_dict = { 'LOWER_BOUND': [the_reaction.lower_bound, reaction_units], 'UPPER_BOUND': [the_reaction.upper_bound, reaction_units], 'FLUX_VALUE': [0, reaction_units], 'OBJECTIVE_COEFFICIENT': [the_reaction.objective_coefficient, 'dimensionless'] } for k, v in reaction_parameter_dict.items(): sbml_parameter = Parameter(sbml_level, sbml_version) sbml_parameter.setId(k) if hasattr(v, '__iter__'): sbml_parameter.setValue(v[0]) sbml_parameter.setUnits(v[1]) else: sbml_parameter.setValue(v) sbml_law.addParameter(sbml_parameter) sbml_reaction.setKineticLaw(sbml_law) sbml_reaction.setNotes( '<html xmlns="http://www.w3.org/1999/xhtml">%sGENE_ASSOCIATION: %s%s%sSUBSYSTEM: %s%s</html>' % (note_start_tag, the_reaction.gene_reaction_rule, note_end_tag, note_start_tag, the_reaction.subsystem, note_end_tag)) if print_time: print 'Adding %s took %1.2f seconds' % ('reactions', time() - start_time) writeSBML(sbml_doc, sbml_filename)
def _writeDBModelToSBML(conn, database_path, sbml_output_path, modelRow): c = conn.cursor() # check table existence c.execute('SELECT name FROM sqlite_master WHERE type="table"') db_tables = [row[0] for row in c.fetchall()] expected_tables = ['Components', 'Regulations', 'Parametrizations'] if len(set(expected_tables).difference(set(db_tables))) != 0: raise Exception("[Error] writeDBModelToSBML, {0} : Cannot find table(s) {1} in database.". format(database_path, set(expected_tables).difference(set(db_tables)))) # check model row existence rowcount = c.execute("SELECT COUNT (*) FROM Parametrizations").fetchone()[0] if modelRow > rowcount: raise Exception( "[Error] writeDBModelToSBML, {0} : Cannot select row {1} from table Parametrizations with {2} rows. Aborting model export.\n".format( database_path, modelRow, rowcount)) # Create an SBMLNamespaces object with the given SBML level, version, # package name, package version. sbmlns = libsbml.SBMLNamespaces(3, 1, "qual", 1) # Creates an SBMLDocument object document = libsbml.SBMLDocument(sbmlns) # mark qual as required document.setPackageRequired("qual", True) # create the Model model = document.createModel() # get a QualModelPlugin object plugged into the model object (enables qualSBML interface). mplugin = model.getPlugin("qual") # extract regulatory context descriptions from table Parametrizations # get the column names from table Parametrizations column_name_list = [tuple[0] for tuple in c.execute( "SELECT * FROM Parametrizations").description] # TO DO: exception for invalid/missing model # create a list of all column names which represent regulatory contexts context_name_list = [column_name for column_name in column_name_list if column_name[0:2] == 'K_'] # TO DO: index dependent = bad # create a list of "targets" (components with incoming regulations) target_list = [target for target, in c.execute('SELECT DISTINCT Target FROM Regulations ORDER BY Target').fetchall()] # create an internal list of regulatory context descriptions context_list = [] for context_name in context_name_list: # find the target component matching the context name target_match_list = [target for target in target_list if context_name[2:].find( target) != -1] # can find multiple targets: e.g. context_name="K_RafB_012" will match species Raf and RafB target = [match for match in target_match_list if len(match) == max(map(len, target_match_list))][ 0] # take the longest match, now "K_RafB_012" will only match RafB and not Raf # extract the threshold states of the regulatory context from the context name # regular expression pattern: find all digits following "K_RafB_" where RafB is the current context target pattern = r'(?<=K_{0}_)\d+'.format(target) # thresholds_name: string of threshold state digits (e.g. "012" for context_name K_RafB_012) thresholds_name = re.search(pattern, context_name).group(0) # WILL NOT WORK for components with MaxActivity > 9 threshold_list = [int(d) for d in thresholds_name] context = [context_name, target] context.extend(threshold_list) # each context = list of format ['K_Raf_031', 'Raf', 0, 3, 1] context_list.append(context) # write to qualSBML model # set a default compartment (required for all models) compartment = model.createCompartment() compartment.setId("default") compartment.setConstant(True) # set QualitativeSpecies from Components table for name, maxActivity in c.execute('SELECT Name, MaxActivity FROM Components ORDER BY Name').fetchall(): # create a qualSBML QualitativeSpecies qs = mplugin.createQualitativeSpecies() qs.setId(name) # Id is required to be unique qs.setCompartment("default") qs.setConstant(False) # components without inputs are usually set constant, however this is not required qs.setMaxLevel(maxActivity) qs.setName(name) # name is not required to be set or to be unique # set Transitions from Regulations and Parametrizations tables # qualSBML Transitions have a list for input and an output QualitativeSpecies. Usually each transition only has one output (target). # Components with identical regulation may be described using only one Transition with multiple outputs # but this is not required and this function creates a transition for each target component. for target, in c.execute('SELECT DISTINCT Target FROM Regulations ORDER BY Target').fetchall(): # create a Transition: one qualSBML Transition per TREMPPI component with >= 1 regulators t = mplugin.createTransition() # create qualSBML transition output for transition t o = t.createOutput() o.setQualitativeSpecies(target) o.setTransitionEffect( 1) # transitionEffect=1 means 'assignmentLevel'. Required for logical/multi valued models. # save a list of all regulator/input-species-names (string) for this target component source_list = [] for source, in c.execute('SELECT DISTINCT Source FROM Regulations WHERE Target=? ORDER BY Source', (target,)).fetchall(): # create qualSBML transition input for transition t i = t.createInput() i.setQualitativeSpecies(source) i.setTransitionEffect(0) # transitionEffect=0 means 'none'. Required for logical/multi valued models. # also append this input to our regulator/input-name list source_list.append(source) # setup a ASTNode representation for the qualSBML Transition.FunctionTerm.Math element from TREMPPI regulatory context information # get all regulatory contexts for this target component target_context_list = [context for context in context_list if context[1] == target] # Each regulatory context is represented in qualSBML by one Transition.FunctionTerm or by the Transition.DefaultTerm. # FunctionTerm definitions hold the (in-)equalities to define source/input states leading to a target/output value. # This function creates a FunctionTerm even for unobservable contexts as long as they are defined in table Parametrizations. # This leads to more FunctionTerm definitions than necessary but allows to recreate the whole network from the qualSBML file. for context in target_context_list: # list of regulator threshold states for this context source_tstate_list = context[2:] # parameter target value of this context param = \ c.execute('SELECT {0} FROM Parametrizations WHERE rowid={1}'.format(context[0], modelRow)).fetchall()[0][0] # If this context is the context with threshold level = 0 for all regulators, use it as Transition.DefaultTerm in qualSBML # Transitions default to this target value if none of the FunctionTerm definitions apply to a system state if sum(source_tstate_list) == 0: # create qualSBML transition DefaultTerm for transition t d = t.createDefaultTerm() d.setResultLevel(param) # ResultLevel is the qualSBML equivalent of a target value # else create a Transition.FunctionTerm term with math element else: # create qualSBML transition FunctionTerm for transition t f = t.createFunctionTerm() f.setResultLevel(param) # list of the ASTNode-tree inequality representations of each regulatory context f_ASTNode_list = [] # find lower and upper thresholds (activity interval) of each source/regulator in this context and build an ASTNode tree of the resulting inequalities # for each source index for source_index in range(0, len(source_list)): source = source_list[source_index] source_tstate = source_tstate_list[ source_index] # threshold state for this source (e.g. 0 for the first regulator of RafB in K_RafB_012) # list of thresholds for this source -> target regulation threshold_list = c.execute( 'SELECT Threshold FROM Regulations WHERE Target=? AND Source=? ORDER BY Threshold', (target, source)).fetchall() lower_t = 0 # Initialize the lower bound of the interval with 0. # If the activity interval includes 0 as lower bound, it is the leftmost (lowest) activity interval. # If it includes the highest threshold of the regulator as its lower bound, it is the rightmost (largest) activity interval. leftmost = True # initialize as leftmost rightmost = False threshold_index = 0 # index of the current regulator threshold # Traverse regulator thresholds and reset lower_t until lower_t matches the threshold state in this context # and set threshold_index to the index of the next higher threshold. while source_tstate > lower_t: lower_t = threshold_list[threshold_index][0] threshold_index += 1 leftmost = False # If lower_t is not 0, this is not the lowest activity interval. # If this is not the rightmost (highest) interval, set upper_t to the next higher threshold of this regulator. if len(threshold_list) > threshold_index: upper_t = threshold_list[threshold_index][0] # Otherwise, set upper_t to the maximum activity of the regulator. else: upper_t = c.execute('SELECT MaxActivity FROM Components WHERE Name=?', (source,)).fetchall()[0] rightmost = True # build ASTNode tree # if this is the leftmost activity interval create inequality: source < upper bound if leftmost: ast = buildASTInequality(source, 'lt', upper_t) # else if this is the rightmost activity interval create inequality: source >= lower bound elif rightmost: ast = buildASTInequality(source, 'geq', lower_t) # otherwise create inequalities: (source >= lower bound) AND (source < upper bound) else: # create AND ASTNode ast = libsbml.ASTNode(libsbml.AST_LOGICAL_AND) # create (source >= lower bound) AST subtree lower_t_ASTNode = buildASTInequality(source, 'geq', lower_t) # create (source < upper bound) AST subtree upper_t_ASTNode = buildASTInequality(source, 'lt', upper_t) # add subtries to AND node ast.addChild(lower_t_ASTNode) ast.addChild(upper_t_ASTNode) # Add the complete AST tree of this source/regulator to the list of inequality definitions for this context/FunctionTerm f_ASTNode_list.append(ast) # If this context depends on more than one source/regulator, add an additional AND node as root of the context/FunctionTerm AST tree # and add all regulator subtrees as children (MathML's AND allows more than 2 children) if (len(f_ASTNode_list) > 1): topASTNode = libsbml.ASTNode(libsbml.AST_LOGICAL_AND) for ast in f_ASTNode_list: topASTNode.addChild(ast) # otherwise make the first (and only) ASTNode in the list the root else: topASTNode = f_ASTNode_list[0] # set the complete AST tree as the Math-element of this FunctionTerm f.setMath(topASTNode) # Check document consistency document.checkInternalConsistency() if document.getNumErrors() > 0: raise Exception( "[Error] writeDBModelToSBML: Exported SBML model invalid or inconsistant, aborting model export.\n Error Log from libSBML:\n{0}".format( document.getErrorLog().toString())) # Write the document to the specified output file path libsbml.writeSBML(document, sbml_output_path)
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename, sbml_level=2, sbml_version=1, print_time=False): """Write a cobra.Model object to an SBML XML file. cobra_model: A cobra.Model object sbml_filename: The file to write the SBML XML to. sbml_level: 2 is the only level supported at the moment. sbml_version: 1 is the only version supported at the moment. print_time: Boolean. Print the time requirements for different sections TODO: Update the NOTES to match the SBML standard and provide support for Level 2 Version 4 """ #Add in the common compartment abbreviations. If there are additional compartments #they also need to be added. note_start_tag, note_end_tag = '<p>', '</p>' if sbml_level > 2 or (sbml_level == 2 and sbml_version == 4): note_start_tag, note_end_tag = '<html:p>', '</html:p>' if not hasattr(cobra_model, 'compartments'): cobra_model.compartments = {'c': 'cytosol', 'p': 'periplasm', 'e': 'extracellular'} sbml_doc = SBMLDocument(sbml_level, sbml_version) sbml_model = sbml_doc.createModel(cobra_model.description.split('.')[0]) #Note need to set units reaction_units = 'mmol_per_gDW_per_hr' model_units = sbml_model.createUnitDefinition() model_units.setId(reaction_units) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_MOLE) sbml_unit.setScale(-3) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_GRAM) sbml_unit.setExponent(-1) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_SECOND) sbml_unit.setMultiplier(1.0/60/60) sbml_unit.setExponent(-1) for the_key in cobra_model.compartments.keys(): sbml_comp = sbml_model.createCompartment() sbml_comp.setId(the_key) sbml_comp.setName(cobra_model.compartments[the_key]) sbml_comp.setSize(1) #Just to get rid of warnings if print_time: start_time = time() #Use this dict to allow for fast look up of species id #for references created in the reaction section. metabolite_dict = {} for cobra_metabolite in cobra_model.metabolites: metabolite_dict[cobra_metabolite.id] = add_sbml_species(sbml_model, cobra_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag) if print_time: print 'Adding %s took %1.2f seconds'%('metabolites', time()-start_time) if print_time: start_time = time() for the_reaction in cobra_model.reactions: #This is probably the culprit. Including cobra.Reaction #objects explicitly in cobra.Model will speed this up. sbml_reaction = sbml_model.createReaction() #Need to remove - for proper SBML. Replace with __ the_reaction_id = 'R_' + the_reaction.id.replace('-','__' ) sbml_reaction.setId(the_reaction_id) if the_reaction.reversibility == 1: sbml_reaction.setReversible(True) else: sbml_reaction.setReversible(False) if the_reaction.name: sbml_reaction.setName(the_reaction.name) else: sbml_reaction.setName(the_reaction.id) #Add in the reactant/product references for the_metabolite, the_coefficient in the_reaction._metabolites.items(): sbml_stoichiometry = the_coefficient metabolite_id = str(metabolite_dict[the_metabolite.id]) #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Deal with the case where the reaction is a boundary reaction if len(the_reaction._metabolites) == 1: the_metabolite, the_coefficient = the_reaction._metabolites.items()[0] the_metabolite = the_metabolite.copy() metabolite_id = add_sbml_species(sbml_model, the_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag, boundary_metabolite=True) the_coefficient *= -1 #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Add in the kineticLaw sbml_law = KineticLaw(sbml_level, sbml_version) sbml_law.setId('FLUX_VALUE') sbml_law.setFormula('FLUX_VALUE') reaction_parameter_dict = {'LOWER_BOUND': [the_reaction.lower_bound, reaction_units], 'UPPER_BOUND': [the_reaction.upper_bound, reaction_units], 'FLUX_VALUE': [0, reaction_units], 'OBJECTIVE_COEFFICIENT': [the_reaction.objective_coefficient, 'dimensionless']} for k, v in reaction_parameter_dict.items(): sbml_parameter = Parameter(sbml_level, sbml_version) sbml_parameter.setId(k) if hasattr(v, '__iter__'): sbml_parameter.setValue(v[0]) sbml_parameter.setUnits(v[1]) else: sbml_parameter.setValue(v) sbml_law.addParameter(sbml_parameter) sbml_reaction.setKineticLaw(sbml_law) sbml_reaction.setNotes('<html xmlns="http://www.w3.org/1999/xhtml">%sGENE_ASSOCIATION: %s%s%sSUBSYSTEM: %s%s</html>'%(note_start_tag, the_reaction.gene_reaction_rule, note_end_tag, note_start_tag, the_reaction.subsystem, note_end_tag)) if print_time: print 'Adding %s took %1.2f seconds'%('reactions', time()-start_time) writeSBML(sbml_doc, sbml_filename)
def createParameter(self): rpsbml = rpSBML.rpSBML('test', None, '../cache') rpsbml.createModel('RetroPath_heterologous_pathway', 'rp_model') upInfParam = rpsbml.createParameter('B_999999', 999999.0, 'kj_per_mol') libsbml.writeSBML(rpsbml.document, self.outputPath + 'test_createParameter.sbml')
def add_metainfo(original_file, output_file, name_of_model, is_kegg, objective_fn, gap_filling_rxns, rxn_to_ec, rxn_to_gene, rxns_of_interest, \ seq_similarity_reactions, spontaneous_reactions, user_defined_reactions, all_reaction_to_attribute, all_metabolite_to_attribute): """This function reads the information in original_file, and modifies it and outputs it to output_file. The following additional parameters need to be specified: name_of_model: the name of the model. is_kegg: True (uses KEGG reaction database) or False (uses BiGG database) objective_fn: the name of the objective function for this model. gap_filling_rxns: the list of gap-filling reactions. rxn_to_ec: mapping of reaction to EC. rxn_to_gene: mapping of reaction to gene. rxns_of_interest: high-confidence reactions + gap-filling reactions. seq_similarity_reactions: reactions that are being added based on sequence similarity (this is for models reconstructed using the BiGG database). spontaneous_reactions: reactions that are always added as they are non-enzymatic. """ # Add compartments if this is a BiGG model. compart_info = ["<listOfCompartments>"] if not is_kegg: ids = ["c", "p", "e"] names = ["cytosol", "periplasm", "extracellular space"] else: # Have only one compartment if KEGG. ids = ["c"] names = ["cytosol"] for curr_id, curr_name in zip(ids, names): #<compartment id="c" name="cytosol" size="1" constant="true"/> curr_string = '<compartment metaid="'+ curr_id + '" id="' + curr_id + '" name="' + curr_name + '" size="1" constant="true"/>' compart_info.append(curr_string) compart_info.append("</listOfCompartments>") add_information_after("<model id=", compart_info, output_file, original_file) # Set flux objective flux_obj_str_lst = ['<fbc:listOfObjectives fbc:activeObjective="obj">'] flux_obj_str_lst.append('<fbc:objective fbc:id="obj" fbc:type="maximize">') flux_obj_str_lst.append('<fbc:listOfFluxObjectives>') flux_obj_str_lst.append('<fbc:fluxObjective fbc:reaction="' + objective_fn + '" fbc:coefficient="1"/>') flux_obj_str_lst.append('</fbc:listOfFluxObjectives>') flux_obj_str_lst.append('</fbc:objective>') flux_obj_str_lst.append('</fbc:listOfObjectives>') add_information_after("</listOfReactions>", flux_obj_str_lst, output_file) # Set the FBC information on the second line. # and change the name of the model. line_num_to_new_info = {} new_name_of_model = name_of_model line_num_to_new_info[2] = '<model metaid="' + new_name_of_model + '" id="' + new_name_of_model + '" fbc:strict="true">' new_info = '<sbml xmlns="http://www.sbml.org/sbml/level3/version1/core" ' +\ 'xmlns:fbc="http://www.sbml.org/sbml/level3/version1/fbc/version2" xmlns:groups="http://www.sbml.org/sbml/level3/version1/groups/version1" ' + \ 'level="3" version="1" fbc:required="false" groups:required="false">' line_num_to_new_info[1] = new_info replace_information(line_num_to_new_info, output_file) # Add the compartment for the metabolites if model is made using KEGG. if is_kegg: change_metabolite_attribute(output_file) # Get the lower and upper bounds possible at all. bound_to_id, rxn_to_lb, rxn_to_ub = read_bounds(original_file) # Then, re-write the file while dispensing of "kineticLaw" parameters # and add the upper and lower bounds to the individual reactions. # Also add attributes for each reaction (description/name). fix_bounds(output_file, bound_to_id, rxn_to_lb, rxn_to_ub, all_reaction_to_attribute, is_kegg) # Add metaId and attributes for each compound (description/name). fix_cpd(output_file, all_metabolite_to_attribute, is_kegg) # Now, add the reaction to gene association information. add_genes_to_file(rxn_to_gene, rxns_of_interest, output_file) # Add any pathway information. Leave out global pathways, as these are generic pathways. generic_pathways = ["rn01100", "rn01110", "rn01120", "rn01200", "rn01210", "rn01212", "rn01230", "rn01240", "rn01220"] pathwayID_to_name, pathwayID_to_reaction_of_int = get_pathway_to_reaction(all_reaction_to_attribute, rxns_of_interest, is_kegg) add_pathway_information(pathwayID_to_name, pathwayID_to_reaction_of_int, generic_pathways, output_file) document = libsbml.readSBML(output_file) # Add reaction to EC information plus other dblinks i = 0 while i < len(document.model.reactions): rxn = document.model.getReaction(i) if rxn.id in rxn_to_ec: ecs = rxn_to_ec[rxn.id] add_annotation_for_rxn(rxn, ecs) if rxn.id in gap_filling_rxns: add_confidence_for_rxn(rxn, "Gap-filling") elif rxn.id in user_defined_reactions: add_confidence_for_rxn(rxn, "User-defined reaction") elif rxn.id in seq_similarity_reactions: add_confidence_for_rxn(rxn, "Non-EC associated reaction added based on sequence similarity") elif rxn.id in spontaneous_reactions: add_confidence_for_rxn(rxn, "Spontaneous reaction") else: if rxn.id in rxn_to_ec: add_confidence_for_rxn(rxn, "Added due to associated high-confidence EC prediction") # Add attributes. if is_kegg: temp_identifier = rxn.id.split("_")[0] else: temp_identifier = rxn.id if (temp_identifier[-2] == "_") and (temp_identifier[-1].isalpha()): temp_identifier = temp_identifier[:-2] if temp_identifier.startswith("R_"): temp_identifier = temp_identifier[2:] # print (temp_identifier) # input() if temp_identifier in all_reaction_to_attribute: # print (all_reaction_to_attribute[temp_identifier]) curr_dblinks = all_reaction_to_attribute[temp_identifier]["DB_LINKS"] add_elem_dblinks(rxn, curr_dblinks) i += 1 # Add metabolite attributes i = 0 while i < len(document.model.species): met = document.model.getSpecies(i) if is_kegg: temp_identifier = met.id.split("[")[0] else: temp_identifier = met.id if (temp_identifier[-2] == "_") and (temp_identifier[-1].isalpha()): temp_identifier = temp_identifier[:-2] if temp_identifier.startswith("M_"): temp_identifier = temp_identifier[2:] if temp_identifier in all_metabolite_to_attribute: curr_dblinks = all_metabolite_to_attribute[temp_identifier]["DB_LINKS"] add_elem_dblinks(met, curr_dblinks) i += 1 libsbml.writeSBML(document, output_file)
def write_cobra_model_to_sbml_file(cobra_model, sbml_filename, sbml_level=2, sbml_version=1, print_time=False, use_fbc_package=True): """Write a cobra.Model object to an SBML XML file. cobra_model: :class:`~cobra.core.Model.Model` object sbml_filename: The file to write the SBML XML to. sbml_level: 2 is the only level supported at the moment. sbml_version: 1 is the only version supported at the moment. use_fbc_package: Boolean. Convert the model to the FBC package format to improve portability. http://sbml.org/Documents/Specifications/SBML_Level_3/Packages/Flux_Balance_Constraints_(flux) TODO: Update the NOTES to match the SBML standard and provide support for Level 2 Version 4 """ note_start_tag, note_end_tag = '<p>', '</p>' if sbml_level > 2 or (sbml_level == 2 and sbml_version == 4): note_start_tag, note_end_tag = '<html:p>', '</html:p>' sbml_doc = SBMLDocument(sbml_level, sbml_version) sbml_model = sbml_doc.createModel(cobra_model.description.split('.')[0]) #Note need to set units reaction_units = 'mmol_per_gDW_per_hr' model_units = sbml_model.createUnitDefinition() model_units.setId(reaction_units) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_MOLE) sbml_unit.setScale(-3) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_GRAM) sbml_unit.setExponent(-1) sbml_unit = model_units.createUnit() sbml_unit.setKind(UNIT_KIND_SECOND) sbml_unit.setMultiplier(1.0/60/60) sbml_unit.setExponent(-1) #Add in the common compartment abbreviations. If there are additional compartments #they also need to be added. if not cobra_model.compartments: cobra_model.compartments = {'c': 'cytosol', 'p': 'periplasm', 'e': 'extracellular'} for the_key in cobra_model.compartments.keys(): sbml_comp = sbml_model.createCompartment() sbml_comp.setId(the_key) sbml_comp.setName(cobra_model.compartments[the_key]) sbml_comp.setSize(1) #Just to get rid of warnings if print_time: warn("print_time is deprecated") #Use this dict to allow for fast look up of species id #for references created in the reaction section. metabolite_dict = {} for cobra_metabolite in cobra_model.metabolites: metabolite_dict[cobra_metabolite.id] = add_sbml_species(sbml_model, cobra_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag) for the_reaction in cobra_model.reactions: #This is probably the culprit. Including cobra.Reaction #objects explicitly in cobra.Model will speed this up. sbml_reaction = sbml_model.createReaction() #Need to remove - for proper SBML. Replace with __ the_reaction_id = 'R_' + the_reaction.id.replace('-','__' ) sbml_reaction.setId(the_reaction_id) sbml_reaction.setReversible(the_reaction.reversibility) if the_reaction.name: sbml_reaction.setName(the_reaction.name) else: sbml_reaction.setName(the_reaction.id) #Add in the reactant/product references for the_metabolite, the_coefficient in the_reaction._metabolites.items(): sbml_stoichiometry = the_coefficient metabolite_id = str(metabolite_dict[the_metabolite.id]) #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Deal with the case where the reaction is a boundary reaction if len(the_reaction._metabolites) == 1: the_metabolite, the_coefficient = list(the_reaction._metabolites.items())[0] the_metabolite = the_metabolite.copy() metabolite_id = add_sbml_species(sbml_model, the_metabolite, note_start_tag=note_start_tag, note_end_tag=note_end_tag, boundary_metabolite=True) sbml_stoichiometry = -the_coefficient #Each SpeciesReference must have a unique id if sbml_stoichiometry < 0: species_reference = sbml_reaction.createReactant() else: species_reference = sbml_reaction.createProduct() species_reference.setId(metabolite_id + '_' + the_reaction_id) species_reference.setSpecies(metabolite_id) species_reference.setStoichiometry(abs(sbml_stoichiometry)) #Add in the kineticLaw sbml_law = KineticLaw(sbml_level, sbml_version) if hasattr(sbml_law, 'setId'): sbml_law.setId('FLUX_VALUE') sbml_law.setFormula('FLUX_VALUE') reaction_parameter_dict = {'LOWER_BOUND': [the_reaction.lower_bound, reaction_units], 'UPPER_BOUND': [the_reaction.upper_bound, reaction_units], 'FLUX_VALUE': [0, reaction_units], 'OBJECTIVE_COEFFICIENT': [the_reaction.objective_coefficient, 'dimensionless']} for k, v in reaction_parameter_dict.items(): sbml_parameter = Parameter(sbml_level, sbml_version) sbml_parameter.setId(k) if hasattr(v, '__iter__'): sbml_parameter.setValue(v[0]) sbml_parameter.setUnits(v[1]) else: sbml_parameter.setValue(v) sbml_law.addParameter(sbml_parameter) sbml_reaction.setKineticLaw(sbml_law) sbml_reaction.setNotes('<html xmlns="http://www.w3.org/1999/xhtml">%sGENE_ASSOCIATION: %s%s%sSUBSYSTEM: %s%s</html>'%(note_start_tag, the_reaction.gene_reaction_rule, note_end_tag, note_start_tag, the_reaction.subsystem, note_end_tag)) if use_fbc_package: try: from libsbml import ConversionProperties, LIBSBML_OPERATION_SUCCESS conversion_properties = ConversionProperties() conversion_properties.addOption("convert cobra", True, "Convert Cobra model") result = sbml_doc.convert(conversion_properties) if result != LIBSBML_OPERATION_SUCCESS: raise Exception("Conversion of COBRA to SBML+fbc failed") except Exception as e: error_string = 'Error saving as SBML+fbc. %s' try: #Check whether the FbcExtension is there from libsbml import FbcExtension error_string = error_string%e except ImportError: error_string = error_string%'FbcExtension not available in libsbml. ' +\ 'If use_fbc_package == True then libsbml must be compiled with ' +\ 'the fbc extension. ' from libsbml import getLibSBMLDottedVersion _sbml_version = getLibSBMLDottedVersion() _major, _minor, _patch = map(int, _sbml_version.split('.')) if _major < 5 or (_major == 5 and _minor < 8): error_string += "You've got libsbml %s installed. You need 5.8.0 or later with the fbc package" raise(Exception(error_string)) writeSBML(sbml_doc, sbml_filename)