def gxFBA(cobramodel_1,cobramodel_2,gene_expressions,GPRlist,maxflux = 500, exprType = 2, verbose = True,FVAcondition = 2, wait = False,treshold = 0.5,objectiveweights = 'log',dumpmodel = False): if verbose: print 'Performing gxFBA. Verbose = True.' print 'Provided gene expression ratios:' print gene_expressions if exprType == 1: print 'Input gene expression ratios handled as absolute ratios.' else: print 'Input gene expression ratios handled as log ratios.' if exprType == 1: logvals = {gene:log(gene_expressions[gene],2) for gene in gene_expressions} ratios = gene_expressions if verbose: print 'Calculated log ratios:' print logvals else: logvals = gene_expressions ratios = {gene:2**gene_expressions[gene] for gene in gene_expressions} #Local variables: eps2 = 0.00001 ##1) Generate the wild-type flux distribution v_i_wt for the starting condition: cobramodel_1.optimize(solver='gurobi') wildtype = cobramodel_1.solution.x_dict if verbose: print 'generated wild-type flux distribution.' #print cobramodel_1.solution.x_dict for key,value in sorted(cobramodel_1.solution.x_dict.items()): print key,value if wait: hold() ###2) Perform FVA with nutritional constraints for condition 1 or 2 (Default: condition 2) and minimum biomass flux = 0 to calculate the upper and lower fluxes each ### reaction can carry. if FVAcondition == 1: FVA_result = cobra.flux_analysis.variability.flux_variability_analysis(cobramodel_1,fraction_of_optimum = 0) else: FVA_result = cobra.flux_analysis.variability.flux_variability_analysis(cobramodel_2,fraction_of_optimum = 0) if verbose: print 'Performed FVA for condition',FVAcondition for key,value in sorted(FVA_result.items()): print key,value #print FVA_result #Reset the objective function for condition 2: for reaction in cobramodel_2.reactions: reaction.objective_coefficient = 0 ### Calculate mean possible flux value for each reaction under condition 2, and the flux average for all active reactions under condition 1 wt_avg = {key:np.mean([FVA_result[key]['minimum'],FVA_result[key]['maximum']]) for key in FVA_result} active_fluxes = [fluxvalue for fluxvalue in wildtype.values() if fluxvalue > eps2] wildtype_averageflux = np.mean(active_fluxes) #average wildtype flux if verbose: print 'FVA average fluxes:' #print wt_avg for key,value in wt_avg.items(): print key,value print 'Total number of reactions in wildtype model:',len(wildtype.values()) print 'Number of active reactions in wildtype FBA solution:',len(active_fluxes) print 'Average wildtype flux (Average of flux value for all fluxes in wildtype FBA solution):',wildtype_averageflux genemap = defaultdict(list) for gene in gene_expressions: if gene in GPRlist: for rx in GPRlist[gene]: genemap[rx].append(gene) if verbose: print 'Gene map:' print genemap if wait: hold() T = [] ##3) Identify the set of reactions (called T) for which an mRNA expression value can be associated. if verbose: print 'Identifying reactions eligible for gx-regulation.' for reaction in cobramodel_2.reactions: #Skip reactions for which gene expression data is unavailable if reaction.id not in genemap: if verbose: print reaction.id,'not in genemap. Skipping reaction.' continue #Skip reactions for which the maximal up/down-regulation is below the set treshold: expressionratios = [ratios[gene] for gene in genemap[reaction.id] ] if max([abs(ratio-1) for ratio in expressionratios]) < treshold: if verbose: print reaction.id,': Level of regulation below treshold. Skipping reaction.' continue #Do not include the reaction if the average flux is too high: if wt_avg[reaction.id] >= maxflux: if verbose: print reaction.id,': FVA average flux too high. Skipping reaction.' continue #Do not include the reaction if it cannot carry any flux (as per FVA): if abs(wt_avg[reaction.id]) < eps2: if verbose: print reaction.id,': Reaction always inactive under specified conditions. Skipping reaction.' continue #Do not include the reaction if it is not irreversible under the given constraints: bounds = FVA_result[reaction.id].values() irreversible = not min(bounds) < 0 < max(bounds) if not irreversible: if verbose: print reaction.id,': Reaction may carry flux in both directions under specified conditions. Skipping reaction.' continue #Do not include the reaction if gene expression data is inconsistent (both up- and down-regulation): exprvalues = [logvals[gene] for gene in genemap[reaction.id] ] signs = [cmp(logvalue,0) for logvalue in exprvalues] if not (signs[1:] == signs[:-1]): #If all the signs are not the same value. Alternative: if not (signs.count(signs[0]) == signs(x)) if verbose: print 'Gene expression information for reaction indicates mixed regulation (up/down). Skipping reaction.' continue #If none of the above checks failed, add the reaction to the list: if verbose: print 'Adding reaction',reaction.id,'to T.' T.append(reaction) ##4) For each reaction in T; define a new upper bound UB = Ci_mRNA * v_i_wt if up-regulated or a new lower bound LB = ## Ci_mRNA * v_i_wt if downregulated, where Ci_mRNA is the mRNA expression ratio. if verbose: print 'Calculating new bounds and objective function coefficients:' def reactionInfo(reaction_id): print 'Ci_mRNA:',Ci_mRNA print 'Wild-type flux:',wildtype[reaction.id] print 'Original reaction bounds:' print 'Lower:',cobramodel_1.reactions.get_by_id(reaction.id).lower_bound,'Upper:',cobramodel_1.reactions.get_by_id(reaction.id).upper_bound print 'New reaction bounds:' print 'Lower:',reaction.lower_bound,'Upper:',reaction.upper_bound print 'Objective coefficient:',reaction.objective_coefficient for reaction in T: if wait: hold() logvalues = [logvals[gene] for gene in genemap[reaction.id] ] expressionratios = [ratios[gene] for gene in genemap[reaction.id] ] sign = cmp(logvalues[0],0) if verbose: print 'Processing reaction:',reaction.id print 'Logvalues:',logvalues print 'Ratios:',expressionratios if sign > 0: Ci_mRNA = 2**max(logvalues) ## For reactions dependent on several genes (several mRNA values), use the maximal up/down-regulation value. if wildtype[reaction.id] == 0: reaction.upper_bound = Ci_mRNA * wildtype_averageflux else: reaction.upper_bound = Ci_mRNA * wildtype[reaction.id] #Set the objective function coefficient: Ci = log(Ci_mRNA) / (v_i average): if objectiveweights == 'log': reaction.objective_coefficient = max(logvalues) / wt_avg[reaction.id] elif objectiveweights =='logabs': reaction.objective_coefficient = max(logvalues) / wt_avg[reaction.id] elif objectiveweights == 'ratios': reaction.objective_coefficient = Ci_mRNA / wt_avg[reaction.id] elif objectiveweights == 'pureratios': reaction.objective_coefficient = Ci_mRNA elif sign < 0: Ci_mRNA = 2**min(logvalues) ## For reactions dependent on several genes (several mRNA values), use the maximal up/down-regulation value. if wildtype[reaction.id] == 0: pass else: reaction.lower_bound = Ci_mRNA * wildtype[reaction.id] #Set the new objective function coefficient: Ci = log(Ci_mRNA) / (v_i average): if objectiveweights == 'log': reaction.objective_coefficient = min(logvalues) / wt_avg[reaction.id] elif objectiveweights =='logabs': reaction.objective_coefficient = abs(min(logvalues)) / wt_avg[reaction.id] elif objectiveweights =='ratios': reaction.objective_coefficient = Ci_mRNA / wt_avg[reaction.id] elif objectiveweights == 'pureratios': reaction.objective_coefficient = Ci_mRNA if verbose: reactionInfo(reaction.id) cobramodel_2.reactions.get_by_id('R5_akgdh').lower_bound = 0.65 cobramodel_2.reactions.get_by_id('R5_akgdh').upper_bound = 1.3 cobramodel_2.reactions.get_by_id('R2_lowergly').lower_bound = 0.8 cobramodel_2.reactions.get_by_id('R2_lowergly').upper_bound = 3.42857 cobramodel_2.reactions.get_by_id('R2_lowergly').objective_coefficient = 1.5 cobramodel_2.reactions.get_by_id('R5_akgdh').objective_coefficient = 0.5 cobramodel_2.reactions.get_by_id('R1_uppergly').objective_coefficient = 1.5 cobramodel_2.reactions.get_by_id('R3_citsyn').objective_coefficient = 0.5 if verbose: print 'New objective function:' #print {reaction.id:reaction.objective_coefficient for reaction in T} print {reaction.id:reaction.objective_coefficient for reaction in cobramodel_2.reactions} print 'New lower bounds:',[reaction.lower_bound for reaction in cobramodel_2.reactions] print 'New upper bounds:',[reaction.upper_bound for reaction in cobramodel_2.reactions] print 'Performing gx-FBA.' #Solve the gx-FBA problem: cobramodel_2.optimize(solver='gurobi') if verbose: print 'Flux solution:' print cobramodel_2.solution.x_dict print 'Objective value:',cobramodel_2.solution #Using Gurobi manually: gurobisolution = QPmindist.gurobiFBA(cobramodel_2) gurobisolutiondict = QPmindist.getgurobisolutiondict(gurobisolution) print 'gurobi solution:' print gurobisolutiondict print 'Objective value:',gurobisolution.Objval #Check that mass conservation is preserved: print 'Total metabolite fluxes:' for metabolite in cobramodel_2.metabolites: print metabolite.id,metabolitefluxsum(metabolite.id,cobramodel_2),metabolitefluxsum(metabolite.id,cobramodel_2, abs = True) #print 'ATP fluxes:',metabolitefluxes('atp_c',cobramodel_2) #print '' print 'Solution:' print cobramodel_2.solution.x vectorToText(cobramodel_2.solution.x,'flux.txt') print 'Flux solution dumped to flux.txt' #vectorToText([reaction.objective_coefficient for reaction in cobramodel_2.reactions],'objective.txt') vectorToText([reaction.objective_coefficient for reaction in cobramodel_2.reactions],'objective.txt', decimal = ',') vectorToText([reaction.lower_bound for reaction in cobramodel_1.reactions],'FBA-lb.txt') vectorToText([reaction.upper_bound for reaction in cobramodel_1.reactions],'FBA-ub.txt') vectorToText([reaction.lower_bound for reaction in cobramodel_2.reactions],'gxFBA-lb.txt') vectorToText([reaction.upper_bound for reaction in cobramodel_2.reactions],'gxFBA-ub.txt') vectorToText([reaction.objective_coefficient for reaction in cobramodel_2.reactions],'A.txt', decimal = ',', linestart = 'C:') #vectorToText([reaction.lower_bound for reaction in cobramodel_1.reactions],'A.txt',append = True, linestart = 'LB:') #vectorToText([reaction.upper_bound for reaction in cobramodel_1.reactions],'A.txt', append = True,linestart = 'UB:') vectorToText([reaction.lower_bound for reaction in cobramodel_2.reactions],'A.txt', append = True, linestart = 'LB:') vectorToText([reaction.upper_bound for reaction in cobramodel_2.reactions],'A.txt.', append = True, linestart = 'UB:') vectorToText(cobramodel_2.solution.x,'A.txt.', append = True, linestart = 'V:') if dumpmodel: write_cobra_model_to_sbml_file(cobramodel_2,'dumpedmodel.xml') return cobramodel_2
if __name__ == "__main__": #If the module is executed as a program, run a test. from cobra.io.sbml import create_cobra_model_from_sbml_file cobramodel = create_cobra_model_from_sbml_file('../SBML/SCHUETZR.xml') import loadData as load fluxvalues = load.ExpFluxesfromXML('expdata.xml','Perrenoud','Batch','aerobe') rmap = load.ReactionMapfromXML('reactionmaps.xml','Perrenoud','SCHUETZR') optreq = 1.0 import QPmindist as qp gurobimodel = qp.QPmindist(cobramodel,fluxvalues,rmap,optreq) QPsolutiondict = qp.getgurobisolutiondict(gurobimodel) import extractflux2 as extract extractfluxdict = extract.extractfluxdict(QPsolutiondict,rmap) dictdist = compdistdict(extractfluxdict) print('dist:',dictdist) simple1 = {"A":1,"B":2,"C":3} simple2 = {"A":1,"B":2,"C":4} simpledist = compdistdict(simple1, expdata = simple2)
return dist if __name__ == "__main__": #If the module is executed as a program, run a test. from cobra.io.sbml import read_sbml_model cobramodel = read_sbml_model('../SBML/SCHUETZR.xml') import loadData as load fluxvalues = load.ExpFluxesfromXML('expdata.xml', 'Perrenoud', 'Batch', 'aerobe') rmap = load.ReactionMapfromXML('reactionmaps.xml', 'Perrenoud', 'SCHUETZR') optreq = 1.0 import QPmindist as qp gurobimodel = qp.QPmindist(cobramodel, fluxvalues, rmap, optreq) QPsolutiondict = qp.getgurobisolutiondict(gurobimodel) import extractflux2 as extract extractfluxdict = extract.extractfluxdict(QPsolutiondict, rmap) dictdist = compdistdict(extractfluxdict) print('dist:', dictdist) simple1 = {"A": 1, "B": 2, "C": 3} simple2 = {"A": 1, "B": 2, "C": 4} simpledist = compdistdict(simple1, expdata=simple2)
def optreqanalysis(modeldicts, objectives, experiments, steps=10, makeplots=True, expfluxdict="Default", plotter="easyviz"): '''Function for evaluating how the minimally achievable distance between a flux solution and a set of experimental fluxes changes when varying the required relative FBA objective-optimality of the flux solution. syntax: optreqanalysis(modeldicts,objectives,experiments,steps = 10,makeplots = True,expfluxdict) arguments: modeldicts: An array of python dictionaries with the following fields: modelobject: A CobraPy model object for the model in question. reactionmap: A reaction map array mapping between model reactions and experimental reactions for the model and experiment in question. objectives: A list of objectives to be used in the analysis. experiments: A list of experiments to be used in the analysis steps: The granularity of the analysis and produced plots. makeplots: Whether plots should be produced or not expfluxdict: A python dictionary with experiment-ids as keys and the corresponding flux value arrays as values. ''' for objective in objectives: pass #Placeholder for experiment in experiments: pass #Placeholder if expfluxdict == "Default": #This section should be rewritten to use an "expflux" dict. expdata = scipy.io.loadmat('expdata.mat') #load experimentaldata perrenoud = expdata['expdata']['perrenoud'] fluxvalarray = perrenoud[0][0][0][0][0][0][0][0][0][0][0][0][0][0] fluxvalues = [row[0] for row in fluxvalarray ] #expdata.perrenoud.abs.batch.aerobe.fluxvalues expfluxdict = load.ExpFluxesfromXML('expdata.xml', 'Perrenoud', 'Batch', 'aerobe') resultlist = [] for modeldict in modeldicts: cobramodel = modeldict['modelobject'] #print 'modeldict:',modeldict reactionmap = modeldict['reactionmap'] #print 'cobramodel:',cobramodel #print type(cobramodel) optreqs = [] for i in range(steps + 1): optreqs.append(float(i) / steps) results = [] #print 'opreqs:',optreqs #q = raw_input('Continue?') for optreq in optreqs: optimizedmodel = QPmindist(cobramodel, fluxvalues, reactionmap, optreq) results.append(math.sqrt(optimizedmodel.ObjVal)) resultlist.append(results) #Using easyviz #ev.plot(optreqs,results) #ev.hold() #Using prettyplotlib #fig, ax = plt.subplots(1) #ppl.scatter(ax, x, y) #ppl.plot(optreqs,results) return resultlist