def save_sbml_model(model, filename, flavor=None): """ Save a model to an SBML file. Arguments: model (Model): model filename (str): file path flavor (str): adapt to different modeling conventions (optional, currently available: 'cobra', 'fbc2') """ document = SBMLDocument(DEFAULT_SBML_LEVEL, DEFAULT_SBML_VERSION) sbml_model = document.createModel(model.id) if flavor in {Flavor.BIGG, Flavor.FBC2}: document.enablePackage(FbcExtension.getXmlnsL3V1V2(), 'fbc', True) fbc_model = sbml_model.getPlugin('fbc') fbc_model.setStrict(True) document.setPackageRequired('fbc', False) _save_compartments(model, sbml_model) _save_metabolites(model, sbml_model, flavor) _save_reactions(model, sbml_model) if isinstance(model, CBModel): _save_cb_parameters(model, sbml_model, flavor) _save_gpr_associations(model, sbml_model, flavor) if isinstance(model, ODEModel): _save_concentrations(model, sbml_model) _save_global_parameters(model, sbml_model) _save_kineticlaws(model, sbml_model) _save_assignment_rules(model, sbml_model) _save_metadata(model, sbml_model) writer = SBMLWriter() writer.writeSBML(document, filename)
def toXMLString(self, enzmldoc): ''' Converts EnzymeMLDocument to XML string. Args: EnzymeMLDocument enzmldoc: Previously created instance of an EnzymeML document ''' doc = SBMLDocument() doc.setLevelAndVersion(enzmldoc.getLevel(), enzmldoc.getVersion()) model = doc.createModel() model.setName(enzmldoc.getName()) model.setId(enzmldoc.getName()) # Add references self.__addRefs(model, enzmldoc) # Add units self.__addUnits(model, enzmldoc) # Add Vessel self.__addVessel(model, enzmldoc) # Add protein self.__addProteins(model, enzmldoc) # Add reactants self.__addReactants(model, enzmldoc) # Add reactions self.__addReactions(model, enzmldoc, csv=False) # Write to EnzymeML writer = SBMLWriter() return writer.writeToString(doc)
def toSBML(self, enzmldoc): ''' Returns libSBML model. Args: EnzymeMLDocument enzmldoc: Previously created instance of an EnzymeML document ''' doc = SBMLDocument() doc.setLevelAndVersion(enzmldoc.getLevel(), enzmldoc.getVersion()) model = doc.createModel() model.setName(enzmldoc.getName()) model.setId(enzmldoc.getName()) # Add references self.__addRefs(model, enzmldoc) # Add units self.__addUnits(model, enzmldoc) # Add Vessel self.__addVessel(model, enzmldoc) # Add protein self.__addProteins(model, enzmldoc) # Add reactants self.__addReactants(model, enzmldoc) # Add reactions self.__addReactions(model, enzmldoc, csv=False) return doc
def toFile(self, enzmldoc, path): ''' Writes EnzymeMLDocument object to an .omex container Args: EnzymeMLDocument enzmldoc: Previously created instance of an EnzymeML document String path: EnzymeML file is written to this destination ''' self.path = path + '/' + enzmldoc.getName() try: os.makedirs(self.path + '/data') except FileExistsError: pass doc = SBMLDocument() doc.setLevelAndVersion(enzmldoc.getLevel(), enzmldoc.getVersion()) model = doc.createModel() model.setName(enzmldoc.getName()) model.setId(enzmldoc.getName()) # Add references self.__addRefs(model, enzmldoc) # Add units self.__addUnits(model, enzmldoc) # Add Vessel self.__addVessel(model, enzmldoc) # Add protein self.__addProteins(model, enzmldoc) # Add reactants self.__addReactants(model, enzmldoc) # Add reactions self.__addReactions(model, enzmldoc) # Write to EnzymeML writer = SBMLWriter() writer.writeSBMLToFile(doc, self.path + '/experiment.xml') # Write to OMEX self.__createArchive(enzmldoc, doc) os.remove(self.path + '/experiment.xml') os.remove(self.path + '/data/data.csv') os.rmdir(self.path + '/data')
def save_sbml_model(model, filename): """ Save a model to an SBML file. Arguments: model : StoichiometricModel (or any subclass) -- Stoichiometric model (or subclass) filename : String -- SBML file path """ document = SBMLDocument(DEFAULT_SBML_LEVEL, DEFAULT_SBML_VERSION) sbml_model = document.createModel(model.id) _save_compartments(model, sbml_model) _save_metabolites(model, sbml_model) _save_reactions(model, sbml_model) _save_stoichiometry(model, sbml_model) if isinstance(model, ConstraintBasedModel): _save_cb_parameters(model, sbml_model) if isinstance(model, GPRConstrainedModel): _save_gpr(model, sbml_model) writer = SBMLWriter() writer.writeSBML(document, filename)
def save_sbml(model, filename): """docstring for save_model""" sbml_document = SBMLDocument(2, 1) sbml_model = sbml_document.createModel(model.id) sbml_model.getNamespaces().add("http://www.w3.org/1999/xhtml", "html") if model.name: sbml_model.setName(model.name) for compartment in model.compartments(): sbml_compartment = sbml_model.createCompartment() sbml_compartment.setId(compartment.id) sbml_compartment.setName(compartment.name) for unit_definition in model.unit_definitions(): sbml_unitDefinition = sbml_model.createUnitDefinition() sbml_unitDefinition.setId(unit_definition.id) for unit in unit_definition.units: sbml_unit = sbml_unitDefinition.createUnit() sbml_unit.setKind(UnitKind_forName(unit.kind)) sbml_unit.setMultiplier(unit.multiplier) sbml_unit.setOffset(unit.offset) sbml_unit.setExponent(unit.exponent) sbml_unit.setScale(unit.scale) for metabolite in model.metabolites(): species = sbml_model.createSpecies() species.setId(metabolite.id) species.setName(metabolite.name) if metabolite.charge: species.setCharge(metabolite.charge) species.setCompartment(metabolite.compartment) species.setBoundaryCondition(metabolite.boundaryCondition) if metabolite.notes: for (key, value) in metabolite.notes.items(): species.appendNotes('\n<html:p>%s: %s</html:p>' % (key, value)) species.appendNotes('\n') for reaction in model.reactions(): sbml_reaction = sbml_model.createReaction() sbml_reaction.setId(reaction.id) sbml_reaction.setName(reaction.name) sbml_reaction.setReversible(reaction.reversible) for (key, value) in reaction.notes.items(): sbml_reaction.appendNotes('\n<html:p>%s: %s</html:p>' % (key, value)) sbml_reaction.appendNotes('\n') kineticLaw = sbml_reaction.createKineticLaw() kineticLaw.setFormula('FLUX_VALUE') sbml_lower = kineticLaw.createParameter() sbml_lower.setId('LOWER_BOUND') sbml_lower.setValue(reaction.lower_bound) sbml_upper = kineticLaw.createParameter() sbml_upper.setId('UPPER_BOUND') sbml_upper.setValue(reaction.upper_bound) sbml_upper = kineticLaw.createParameter() sbml_upper.setId('OBJECTIVE_COEFFICIENT') sbml_upper.setValue(reaction.objective_coefficient) if reaction.flux_value: sbml_upper = kineticLaw.createParameter() sbml_upper.setId('FLUX_VALUE') sbml_upper.setValue(reaction.flux_value) for (metabolite, coefficient) in reaction.participants.items(): if coefficient < 0: speciesReference = sbml_reaction.createReactant() coefficient = abs(coefficient) else: speciesReference = sbml_reaction.createProduct() speciesReference.setSpecies(metabolite.id) speciesReference.setStoichiometry(float(coefficient)) writer = SBMLWriter() writer.writeSBML(sbml_document, filename)
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)
class TissueModel(object): """ The SBML model is created from the tissue information and the single cell models. """ _keys = ['main_units', 'units', 'names', 'pars', 'external', 'assignments', 'rules'] def __init__(self, Nc, Nf, version, tissue_dict, cell_model, sim_id='core', events=None): """ Initialize with the tissue information dictionary and the respective cell model used for creation. """ self.Nc = Nc self.Nf = Nf self.version = version self.simId = sim_id self.cellModel = cell_model # print self.cellModel.info() # tissue information fields for key, value in tissue_dict.items(): setattr(self, key, value) self.events = events # sbmlutils self.id = self.createId() self.doc = SBMLDocument(SBML_LEVEL, SBML_VERSION) self.model = self.doc.createModel() check(self.model.setId(self.id), 'set id') check(self.model.setName(self.id), 'set name') # add dynamical parameters self.pars.extend( [('Nc', self.Nc, '-', True), ('Nf', self.Nf, '-', True), ] ) print '\n', '*' * 40, '\n', self.id, '\n', '*' * 40 @staticmethod def createTissueDict(module_names): """ Creates one information dictionary from various modules by combining the information. Information in earlier modules if overwritten by information in later modules. """ import copy cdict = dict() for name in module_names: mdict = TissueModel._createDict(name) for key, value in mdict.items(): if type(value) is list: # create new list if not cdict.has_key(key): cdict[key] = [] # now add the elements by copy cdict[key].extend(copy.deepcopy(value)) elif type(value) is dict: # create new dict if not cdict.has_key(key): cdict[key] = dict() # now add the elements by copy old_value = cdict.get(key) for k, v in value.items(): old_value[k] = copy.deepcopy(v) return cdict @staticmethod def _createDict(module_name): """ A module which encodes a cell model is given and used to create the instance of the CellModel from the given global variables of the module. TODO: some quality control of the model structure. """ # dynamically import module # tissue_module = __import__(module_name) import importlib module = importlib.import_module(module_name) # get attributes from the class print '\n***', module_name, '***' print module print dir(module) mdict = dict() for key in TissueModel._keys: if hasattr(module, key): # print 'set:', key mdict[key] = getattr(module, key) else: print 'missing:', key return mdict def createId(self): if self.simId: mid = '{}_v{}_Nc{}_{}'.format(self.cellModel.mid, self.version, self.Nc, self.simId) else: mid = '{}_v{}_Nc{}'.format(self.cellModel.mid, self.version, self.Nc) return mid def cell_range(self): return range(1, self.Nc + 1) def comp_range(self): return range(1, self.Nc * self.Nf + 1) def info(self): for key in TissueModel._keys: print key, ' : ', getattr(self, key) def createModel(self): # sinusoidal unit model self.createUnits() self.createExternalParameters() self.createInitialAssignments() self.createExternalCompartments() self.createExternalSpecies() self.createAssignmentRules() self.createTransportReactions() self.createBoundaryConditions() # cell model self.createCellCompartments() self.createCellSpecies() self.createCellParameters() self.createCellInitialAssignments() self.createCellAssignmentRules() self.createCellReactions() # events self.createCellEvents() self.createSimulationEvents() ######################################################################### # External Compartments ########################################################################## # id, name, spatialDimension, unit, constant, assignment/value def createExternalCompartmentsDict(self): comps = dict() # periportal comps[getPPId()] = (getPPName(), 3, 'm3', False, 'Vol_pp') # sinusoid for k in self.comp_range(): comps[getSinusoidId(k)] = (getSinusoidName(k), 3, 'm3', False, 'Vol_sin') # disse for k in self.comp_range(): comps[getDisseId(k)] = (getDisseName(k), 3, 'm3', False, 'Vol_dis') # perivenious comps[getPVId()] = (getPVName(), 3, 'm3', False, 'Vol_pv') return comps ########################################################################## # Cell compartments ########################################################################## def createCellCompartmentsDict(self): comps = dict() # hepatocyte compartments for k in self.cell_range(): comps[getHepatocyteId(k)] = (getHepatocyteName(k), 3, 'm3', False, 'Vol_cell') comps[getCytosolId(k)] = (getCytosolName(k), 3, 'm3', False, 'Vol_cyto') return comps ########################################################################## # Species ########################################################################## def createExternalSpeciesDict(self): """ All species which are defined external are generated in all external compartments, i.e. PP, PV, sinusoid and disse space. """ sdict = dict() for data in self.external: (sid, init, units, boundaryCondition) = self.getItemsFromSpeciesData(data) name = self.names[sid] # PP sdict[getPPSpeciesId(sid)] = (getPPSpeciesName(name), init, units, getPPId(), boundaryCondition) for k in self.comp_range(): sdict[getSinusoidSpeciesId(sid, k)] = ( getSinusoidSpeciesName(name, k), init, units, getSinusoidId(k), boundaryCondition) sdict[getDisseSpeciesId(sid, k)] = ( getDisseSpeciesName(name, k), init, units, getDisseId(k), boundaryCondition) # PV sdict[getPVSpeciesId(sid)] = (getPVSpeciesName(name), init, units, getPVId(), boundaryCondition) return sdict def createCellSpeciesDict(self): sdict = dict() for data in self.cellModel.species: (full_id, init, units, boundaryCondition) = self.getItemsFromSpeciesData(data) tokens = full_id.split('__') sid = tokens[1] name = self.names[sid] for k in self.cell_range(): # TODO: only covers species in cytosol (has to work with arbitrary number of compartments) # necessary to have a mapping of the compartments to the functions which generate id and names if full_id.startswith('h__'): sdict[getHepatocyteSpeciesId(sid, k)] = (getHepatocyteSpeciesName(name, k), init, units, getHepatocyteId(k), boundaryCondition) if full_id.startswith('c__'): sdict[getCytosolSpeciesId(sid, k)] = (getCytosolSpeciesName(name, k), init, units, getCytosolId(k), boundaryCondition) return sdict def getItemsFromSpeciesData(self, data): sid, init, units = data[0], data[1], data[2] # handle the constant species if len(data) == 4: boundaryCondition = data[3] else: boundaryCondition = False return sid, init, units, boundaryCondition ########################################################################## # Diffusion ########################################################################## def createDiffusionAssignments(self): """ Create the geometrical diffusion constants based on the external substances. For the diffusion between sinusoid and space of Disse, diffusion through fenestrations is handled via pore theory. """ # get the fenestration radius r_fen = None for p in self.pars: if p[0] == 'r_fen': r_fen = p[1] break if not r_fen: raise TissueModelException('Fenestration radius not defined.') diffusion_assignments = [] for data in self.external: sid = data[0] # id, assignment, unit diffusion_assignments.extend([ ('Dx_sin_{}'.format(sid), 'D{}/x_sin * A_sin'.format(sid), "m3_per_s"), ('Dx_dis_{}'.format(sid), 'D{}/x_sin * A_dis'.format(sid), "m3_per_s"), # ('Dy_sindis_{}'.format(sid), 'D{}/y_dis * f_fen * A_sindis'.format(sid), "m3_per_s") # check the pore size ]) # test if substance larger than fenestration radius r_sid = None for p in self.pars: if p[0] == 'r_{}'.format(sid): r_sid = p[1] break if r_sid > r_fen: diffusion_assignments.extend([('Dy_sindis_{}'.format(sid), '0 m3_per_s', "m3_per_s")]) else: diffusion_assignments.extend([('Dy_sindis_{}'.format(sid), 'D{}/y_dis * f_fen * A_sindis * (1 dimensionless - r_{}/r_fen)^2 * (1 dimensionless - 2.104 dimensionless*r_{}/r_fen + 2.09 dimensionless *(r_{}/r_fen)^3 - 0.95 dimensionless *(r_{}/r_fen)^5)'.format( sid, sid, sid, sid, sid), "m3_per_s")]) return diffusion_assignments def createDiffusionRules(self): return self.createDiffusionAssignments() # Parameters def createParametersDict(self, pars): pdict = dict() for pdata in pars: pid = pdata[0] # id, name, value, unit, constant pdict[pid] = [pid, self.names.get(pid, None), pdata[1], pdata[2], pdata[3]] return pdict # Units def createUnits(self): # creates all the individual unit definitions for key, value in self.units.iteritems(): createUnitDefinition(self.model, key, value) # sets the main units of model setMainUnits(self.model, self.main_units) # Compartments def createExternalCompartments(self): comps = self.createExternalCompartmentsDict() createCompartments(self.model, comps) def createCellCompartments(self): comps = self.createCellCompartmentsDict() createCompartments(self.model, comps) # Species def createExternalSpecies(self): species = self.createExternalSpeciesDict() createSpecies(self.model, species) def createCellSpecies(self): species = self.createCellSpeciesDict() createSpecies(self.model, species) # Parameters def createExternalParameters(self): parameters = self.createParametersDict(self.pars) createParameters(self.model, parameters) def createCellParameters(self): parameters = self.createParametersDict(self.cellModel.pars) createParameters(self.model, parameters) # InitialAssignments def createInitialAssignments(self): createInitialAssignments(self.model, self.assignments, self.names) # diffusion # dif_assignments = self.createDiffusionAssignments() # createInitialAssignments(self.model, dif_assignments, self.names) def createCellInitialAssignments(self): createInitialAssignments(self.model, self.cellModel.assignments, self.names) # Assignment Rules def createAssignmentRules(self): createAssignmentRules(self.model, self.rules, self.names) # diffusion dif_rules = self.createDiffusionRules() createAssignmentRules(self.model, dif_rules, self.names) def createCellAssignmentRules(self): rules = [] rep_dicts = self.createCellExtReplacementDicts() for rule in self.cellModel.rules: for d in rep_dicts: r_new = [initString(rpart, d) for rpart in rule] rules.append(r_new) createAssignmentRules(self.model, rules, self.names) def createCellReplacementDicts(self): """ Definition of replacement information for initialization of the cell ids. Creates all possible combinations. """ init_data = [] for k in self.cell_range(): d = dict() d['h__'] = '{}__'.format(getHepatocyteId(k)) d['c__'] = '{}__'.format(getCytosolId(k)) init_data.append(d) return init_data def createCellExtReplacementDicts(self): """ Definition of replacement information for initialization of the cell ids. Creates all possible combinations. """ init_data = [] for k in self.cell_range(): for i in range((k - 1) * self.Nf + 1, k * self.Nf + 1): d = dict() d['h__'] = '{}__'.format(getHepatocyteId(k)) d['c__'] = '{}__'.format(getCytosolId(k)) d['e__'] = '{}__'.format(getDisseId(i)) init_data.append(d) return init_data # Boundary Conditions def createBoundaryConditions(self): ''' Set constant in periportal. ''' sdict = self.createExternalSpeciesDict() for key in sdict.keys(): if isPPSpeciesId(key): s = self.model.getSpecies(key) s.setBoundaryCondition(True) # Reactions def createCellReactions(self): """ Initializes the generic compartments with the actual list of compartments for the given geometry. """ # set the model for the template reaction.model = self.model rep_dicts = self.createCellReplacementDicts() for r in self.cellModel.reactions: # Get the right replacement dictionaries for the reactions if ('c__' in r.compartments) and not ('e__' in r.compartments): rep_dicts = self.createCellReplacementDicts() if ('c__' in r.compartments) and ('e__' in r.compartments): rep_dicts = self.createCellExtReplacementDicts() r.createReactions(self.model, rep_dicts) def createTransportReactions(self): self.createFlowRules() self.createFlowReactions() self.createFlowPoreReactions() self.createDiffusionReactions() def createFlowRules(self): """ Creates the rules for positions Si_x, pressures Si_P, capillary flow Si_Q and pore flow Si_q. These parameters are used afterwards to calculate the actual flow values. """ rules = [ (getPositionId(getPPId()), '0 m', 'm'), (getPositionId(getPVId()), 'L', 'm'), ] # position midpoint hepatocyte for k in range(1, self.Nc * self.Nf + 1): r = (getPositionId(getSinusoidId(k)), '({} dimensionless-0.5 dimensionless)*x_sin'.format(k), 'm') rules.append(r) # position in between hepatocytes for k in range(1, self.Nc * self.Nf): r = (getPositionId(getSinusoidId(k), getSinusoidId(k + 1)), '{} dimensionless*x_sin'.format(k), 'm') rules.append(r) # pressures P_formula = '(-(Pb-P0) + (Pa-P0)*exp(-L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp( {}/lambda)\ + ( (Pb-P0) - (Pa-P0)*exp( L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp(-{}/lambda) + P0' # PP, PV for vid in [getPPId(), getPVId()]: x_str = getPositionId(vid) P_str = getPressureId(vid) rules.append((P_str, P_formula.format(x_str, x_str), 'Pa')) # midpoint for k in self.comp_range(): x_str = getPositionId(getSinusoidId(k)) P_str = getPressureId(getSinusoidId(k)) rules.append((P_str, P_formula.format(x_str, x_str), 'Pa')) # capillary flow Q_formula = '-1 dimensionless/sqrt(W*w) * ( (-(Pb-P0) + (Pa-P0)*exp(-L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp( {}/lambda)\ - ( (Pb-P0) - (Pa-P0)*exp( L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp(-{}/lambda) )' # PP, PV for vid in [getPPId(), getPVId()]: x_str = getPositionId(vid) Q_str = getQFlowId(vid) rules.append((Q_str, Q_formula.format(x_str, x_str), 'm3_per_s')) # between locations for k in range(1, self.Nc * self.Nf): x_str = '{}{}_x'.format(getSinusoidId(k), getSinusoidId(k + 1)) Q_str = '{}{}_Q'.format(getSinusoidId(k), getSinusoidId(k + 1)) rules.append((Q_str, Q_formula.format(x_str, x_str), 'm3_per_s')) # pore flow (only along sinusoid, not in PP and PV) q_formula = '1 dimensionless/w * ( (-(Pb-P0) + (Pa-P0)*exp(-L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp( {}/lambda) \ + ( (Pb-P0) - (Pa-P0)*exp( L/lambda))/(exp(-L/lambda)-exp(L/lambda))*exp(-{}/lambda) )' # midpoint for k in self.comp_range(): x_str = '{}_x'.format(getSinusoidId(k)) q_str = '{}_q'.format(getSinusoidId(k)) rules.append((q_str, q_formula.format(x_str, x_str), 'm2_per_s')) createAssignmentRules(self.model, rules, {}) def createFlowReactions(self): """ Creates the local flow reactions based on the local volume flows. The amount of substance transported via the volume flow is calculated. """ # flow = 'flow_sin * A_sin' # [m3/s] global volume flow (converts to local volume flow in pressure model) for data in self.external: sid = data[0] # flow PP -> S01 Q_str = getQFlowId(getPPId()) # [m3/s] local volume flow createFlowReaction(self.model, sid, c_from=getPPId(), c_to=getSinusoidId(1), flow=Q_str) # [m3/s] local volume flow # flow S[k] -> S[k+1] for k in range(1, self.Nc * self.Nf): Q_str = getQFlowId(getSinusoidId(k), getSinusoidId(k + 1)) createFlowReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getSinusoidId(k + 1), flow=Q_str) # flow S[Nc*Nf] -> PV Q_str = getQFlowId(getPVId()) createFlowReaction(self.model, sid, c_from=getSinusoidId(self.Nc * self.Nf), c_to=getPVId(), flow=Q_str) # flow PV -> createFlowReaction(self.model, sid, c_from=getPVId(), c_to=NONE_ID, flow=Q_str); def createFlowPoreReactions(self): """ Filtration and reabsorption reactions through pores. """ for data in self.external: sid = data[0] if sid in ["rbcM"]: continue # only create for substances fitting through pores # flow S[k] -> D[k] for k in self.comp_range(): Q_str = getqFlowId(getSinusoidId(k)) + ' * {}'.format('x_sin') # [m2/s] * [m] (area flow) createFlowReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getDisseId(k), flow=Q_str) def createDiffusionReactions(self): for data in self.external: sid = data[0] # [1] sinusoid diffusion Dx_sin = 'Dx_sin_{}'.format(sid) createDiffusionReaction(self.model, sid, c_from=getPPId(), c_to=getSinusoidId(1), D=Dx_sin) for k in range(1, self.Nc * self.Nf): createDiffusionReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getSinusoidId(k + 1), D=Dx_sin) createDiffusionReaction(self.model, sid, c_from=getSinusoidId(self.Nc * self.Nf), c_to=getPVId(), D=Dx_sin) # [2] disse diffusion Dx_dis = 'Dx_dis_{}'.format(sid) for k in range(1, self.Nc * self.Nf): createDiffusionReaction(self.model, sid, c_from=getDisseId(k), c_to=getDisseId(k + 1), D=Dx_dis) # [3] sinusoid - disse diffusion Dy_sindis = 'Dy_sindis_{}'.format(sid) for k in self.comp_range(): createDiffusionReaction(self.model, sid, c_from=getSinusoidId(k), c_to=getDisseId(k), D=Dy_sindis) # Events def createCellEvents(self): """ Creates the additional events defined in the cell model. These can be metabolic deficiencies, or other defined parameter changes. TODO: make this cleaner and more general. """ ddict = self.cellModel.deficiencies dunits = self.cellModel.deficiencies_units for deficiency, data in ddict.iteritems(): e = createDeficiencyEvent(self.model, deficiency) # create all the event assignments for the event for key, value in data.iteritems(): p = self.model.getParameter(key) p.setConstant(False) formula = '{} {}'.format(value, dunits[key]) astnode = libsbml.parseL3FormulaWithModel(formula, self.model) ea = e.createEventAssignment() ea.setVariable(key) ea.setMath(astnode) def createSimulationEvents(self): """ Create the simulation timecourse events based on the event data. """ if self.events: createSimulationEvents(self.model, self.events) def writeSBML(self, filepath=None, validate=True): if not filepath: filepath = self.sbml_default_path() print 'Write : {}\n'.format(self.id, filepath) writer = SBMLWriter() writer.writeSBMLToFile(self.doc, filepath) # validate the model with units (only for small models) if validate: validator = SBMLValidator(ucheck=(self.Nc < 4)) validator.validate(filepath) return filepath def sbml_default_path(self): import os from multiscale import multiscale_settings return os.path.join(multiscale_settings.SBML_DIR, '{}.xml'.format(self.id))
def export_en_sbml(self, file_path, gemtractor, model_id, model_name=None, filter_species=None, filter_reactions=None, filter_genes=None, filter_gene_complexes=None, remove_reaction_enzymes_removed=True, remove_ghost_species=False, discard_fake_enzymes=False, remove_reaction_missing_species=False, removing_enzyme_removes_complex=True): """ export the enzyme-centric network in SBML format will attach the trimming-settings as SBML note writes the document using the `libsbml:SBMLWriter <http://sbml.org/Special/Software/libSBML/docs/python-api/class_s_b_m_l_writer.html>` -- returns the result of `libsbml:SBMLWriter.writeSBML <http://sbml.org/Special/Software/libSBML/docs/python-api/class_s_b_m_l_writer.html#a02d1998aee7656d7b9c3ac69d62bb66f>`_ :param file_path: where to store the exported format? :param model_id: the model's identifier, will be postfixed with a greeting from us :param model_name: the model's name, will be prefixed with a greeting from us :param filter_species: species identifiers to get rid of :param filter_reactions: reaction identifiers to get rid of :param filter_genes: enzyme identifiers to get rid of :param filter_gene_complexes: enzyme-complex identifiers to get rid of, every list-item should be of format: 'A + B + gene42' :param remove_reaction_enzymes_removed: should we remove a reaction if all it's genes were removed? :param remove_ghost_species: should species be removed, that do not participate in any reaction anymore - even though they might be required in other entities? :param discard_fake_enzymes: should fake enzymes (implicitly assumes enzymes, if no enzymes are annotated to a reaction) be removed? :param remove_reaction_missing_species: remove a reaction if one of the participating genes was removed? :param removing_enzyme_removes_complex: if an enzyme is removed, should also all enzyme complexes be removed in which it participates? :type file_path: str :type model_id: str :type model_name: str :type filter_species: list of str :type filter_reactions: list of str :type filter_genes: list of str :type filter_gene_complexes: list of str :type remove_reaction_enzymes_removed: bool :type remove_ghost_species: bool :type discard_fake_enzymes: bool :type remove_reaction_missing_species: bool :type removing_enzyme_removes_complex: bool :return: true on success, otherwise false :rtype: bool """ if not self.have_gene_net: self.calc_genenet() sbml = SBMLDocument() model = sbml.createModel() #TODO dc modified? if model is None: self.__logger.error("could not create model...") return False model.setId(model_id + "_GEMtracted_EnzymeNetwork") if model_name is None: model_name = model_id model.setName("GEMtracted EnzymeNetwork of " + model_name) # print ("adding note to en sbml") Utils.add_model_note(model, filter_species, filter_reactions, filter_genes, filter_gene_complexes, remove_reaction_enzymes_removed, remove_ghost_species, discard_fake_enzymes, remove_reaction_missing_species, removing_enzyme_removes_complex) nodemap = {} compartment = model.createCompartment() compartment.setId('compartment') compartment.setConstant(True) num = 0 for gene in self.genes: num += 1 nodemap[gene] = self.__create_sbml_gene(model, 'g' + str(num), gene, compartment, gemtractor) # TODO: add other information if available for gene in self.gene_complexes: num += 1 nodemap[gene] = self.__create_sbml_gene_complex( model, 'gc' + str(num), gene, compartment, gemtractor, self.gene_complexes[gene].genes, nodemap) # TODO: add other information if available num = 0 for gene in self.genes: for associated in self.genes[gene].links["g"]: num += 1 Network.create_sbml_reaction(model, 'r' + str(num), nodemap[gene], nodemap[associated.identifier]) for associated in self.genes[gene].links["gc"]: num += 1 Network.create_sbml_reaction(model, 'r' + str(num), nodemap[gene], nodemap[associated.identifier]) for gene in self.gene_complexes: for associated in self.gene_complexes[gene].links["g"]: num += 1 Network.create_sbml_reaction(model, 'r' + str(num), nodemap[gene], nodemap[associated.identifier]) for associated in self.gene_complexes[gene].links["gc"]: num += 1 Network.create_sbml_reaction(model, 'r' + str(num), nodemap[gene], nodemap[associated.identifier]) return SBMLWriter().writeSBML(sbml, file_path)