def parallel_ko_worker(comm, model, solver, wtVec, fbaParams, koGroups=None, weights=None, numIter=1, useMoma=When.AUTO, lethalityCutoff=_CUTOFF_LETHAL): """ compute process (worker) for parallel knockout analysis Keyword arguments: comm -- MPI communicator model -- the MetabolicModel solver -- name of QP/NLP solver (or "default") wtVec -- FBA solution for wildtype fbaParams -- parameters for FBA (incl. linear equality and inequality constraints) koGroups -- list of pairs (group name, list of reactions) weights -- weight vector for weighted MOMA (None -> perform regular MOMA, else: weight flux i with weights[i]) numIter -- number of NLP runs (if NLP solver is used) for MOMA useMoma -- selector of optimization strategy, enum values (class When): NEVER - always perform FBA (LP) AUTO - perform FBA first, followed by MOMA if not lethal ALWAYS - always perform MOMA (QP) lethalityCutoff -- threshold for biomass flux signifying lethality """ if not koGroups: koGroups = _makeDefaultKoGroups(model) # print "worker: %d reactions, %d knockout groups" % (len(model), # len(koGroups)) wtSolution = MetabolicFlux(model, wtVec) nanVec = array([nan] * len(wtVec)) infVec = array([inf] * len(wtVec)) moma = MomaAnalyzer(solver) # index of reaction group to be knocked out (as 0-dimensional numpy array) i = array(0, 'i') comm.Recv(i) while i >= 0: group, reaList = koGroups[i] # Restrict flux through all reactions in group to zero tmp_lb = {} # {index in model : LB value} tmp_ub = {} # { - '' - : UB '' } for rea in reaList: try: rIndex = model.reactionDict[rea] except KeyError: # Skip any blocked reactions (knockout has no effect) continue tmp_lb[rIndex] = model.reactions[rIndex].lb tmp_ub[rIndex] = model.reactions[rIndex].ub model.reactions[rIndex].lb = model.reactions[rIndex].ub = 0. if not tmp_lb: print " - skipped group '%s' (only blocked reactions)" % group comm.Send(wtVec) comm.Recv(i) continue obj_val = lethalityCutoff + 1. # Perform FBA first to check for lethality if useMoma != When.ALWAYS: fba = FbAnalyzer(fbaParams.solver) # Note: Model is already reduced obj_val, solutionFlux = fba.runOnModel(model, fbaParams, rmDeadEnds=False)[:2] status = SolverStatus.PREPARED if not solutionFlux: obj_val = 0. # Perform MOMA if knockout not already predicted by FBA to be lethal if useMoma != When.NEVER and abs(obj_val) > lethalityCutoff: solutionFlux, status = moma.runOnModel(model, wtSolution, fbaParams.linConstraints, numIter, weights)[1:3] # Send result to dispatcher if status == SolverStatus.UNKNOWN: # If status is 'unknown, not converged', send vector with only 'nan' # entries comm.Send(nanVec) elif status in (SolverStatus.PRIM_INFEAS, SolverStatus.DUAL_INFEAS): # If status is 'infeasible', send vector with only 'inf' entries comm.Send(infVec) elif len(solutionFlux) == 0: if status == SolverStatus.PREPARED: # FBA infeasible comm.Send(infVec) else: comm.Send(nanVec) else: solutionVec = array(solutionFlux.getVecOrderedByModel(model)) comm.Send(solutionVec) # Restore original constraints for rea in reaList: try: rIndex = model.reactionDict[rea] except KeyError: continue model.reactions[rIndex].lb = tmp_lb[rIndex] model.reactions[rIndex].ub = tmp_ub[rIndex] # Get next index comm.Recv(i)
def serial_knockout(model, solver, objective, wtSolution, fbaParams, koGroups=None, filePrefix=None, wtObjVal=None, weights=None, numIter=1, useMoma=When.AUTO, lethalityCutoff=_CUTOFF_LETHAL): """ perform knockout analysis in serial fashion (single process) Keyword arguments: model -- the MetabolicModel solver -- name of QP/NLP solver (or "default") objective -- coefficient vector of linear objective function of FBA wtSolution -- FBA solution for wildtype fbaParams -- parameters for FBA (incl. linear equality and inequality constraints) koGroups -- list of pairs (group name, list of reactions) filePrefix -- if given, write MOMA/FBA solutions to files starting with this prefix; if not given, solutions are discarded wtObjVal -- objective function value for wildtype solution (optional) weights -- weight vector for weighted MOMA (None -> perform regular MOMA, else: weight flux i with weights[i]) numIter -- number of NLP runs (if NLP solver is used) for MOMA useMoma -- selector of optimization strategy, enum values (class When): NEVER - always perform FBA (LP) AUTO - perform FBA first, followed by MOMA if not lethal ALWAYS - always perform MOMA (QP) lethalityCutoff -- threshold for biomass flux signifying lethality Returns list of (distance, diff, obj_val) tuples, indexed like koGroups, distance -- value of actual MOMA/FBA objective function at solution diff -- summed absolute difference between mutant and wildtype solutions obj_val -- value of FBA objective function at MOMA/FBA solution for mutant """ if not koGroups: koGroups = _makeDefaultKoGroups(model) # print "serial: %d reactions, %d knockout groups" % (len(model), # len(koGroups)) wtVec = wtSolution.getVecOrderedByModel(model) if wtObjVal is None: wtObjVal = dot(objective, wtVec) moma = MomaAnalyzer(solver) result = [] for group, reaList in koGroups: print group # Restrict flux through all reactions in group to zero tmp_lb = {} # {index in model : LB value} tmp_ub = {} # { - '' - : UB '' } for rea in reaList: try: rIndex = model.reactionDict[rea] except KeyError: # Skip any blocked reactions (knockout has no effect) continue tmp_lb[rIndex] = model.reactions[rIndex].lb tmp_ub[rIndex] = model.reactions[rIndex].ub model.reactions[rIndex].lb = model.reactions[rIndex].ub = 0. if not tmp_lb: print " -> skipped (only blocked reactions)" result.append((0., 0., wtObjVal)) if filePrefix: wtSolution.writeToFile(filePrefix + group + _FILE_SUFFIX) continue obj_val = lethalityCutoff + 1. # Perform FBA first to check for lethality if useMoma != When.ALWAYS: fba = FbAnalyzer(fbaParams.solver) # Note: Model is already reduced obj_val, solutionFlux = fba.runOnModel(model, fbaParams, rmDeadEnds=False)[:2] status = SolverStatus.PREPARED dist = None if not solutionFlux: obj_val = 0. # Perform MOMA if knockout not already predicted by FBA to be lethal if useMoma != When.NEVER and abs(obj_val) > lethalityCutoff: dist, solutionFlux, status = moma.runOnModel( model, wtSolution, fbaParams.linConstraints, numIter, weights)[:3] if status == SolverStatus.UNKNOWN: result.append((nan, nan, 0.)) elif status in (SolverStatus.PRIM_INFEAS, SolverStatus.DUAL_INFEAS): result.append((inf, inf, 0.)) elif len(solutionFlux) == 0: if status == SolverStatus.PREPARED: # FBA infeasible result.append((inf, inf, 0.)) else: result.append((nan, nan, 0.)) else: diff = sum(solutionFlux.absDiff(wtSolution).fluxDict.values()) if dist is None: dist = moma.evalObjFunc( wtVec, solutionFlux.getVecOrderedByModel(model), weights) else: obj_val = max( 0., dot(objective, solutionFlux.getVecOrderedByModel(model))) result.append((dist, diff, obj_val)) if filePrefix: solutionFlux.writeToFile(filePrefix + group + _FILE_SUFFIX) # Restore original constraints for rea in reaList: try: rIndex = model.reactionDict[rea] except KeyError: continue model.reactions[rIndex].lb = tmp_lb[rIndex] model.reactions[rIndex].ub = tmp_ub[rIndex] return result
def run(self, fbaParams, syntaxOk=True, printExcepted=False): """ check assertions against results of FBA, FVA, & split-ratio analysis This function performs FBA, split-ratio analysis, and FVA and evaluates the assertions. It enumerates all assertions that do not hold. Keyword arguments: fbaParams -- objective function and solver for FBA syntaxOk -- if False, previously performed syntax check has failed printExcepted -- if False, syntax errors in assertions are not reported """ # 1. Perform flux balance analysis on the metabolic network fba = FbAnalyzer(fbaParams.solver) self.flux = fba.runOnModel(self.model, fbaParams)[1] if len(self.flux) == 0: print( "No FBA solution was obtained. The optimization problem is " "either unbounded or infeasible.") return # 2. Compute metabolite fluxes and split ratios splitRatios = self.flux.computeAllSplitRatios(self.model) self.metFlux, self.outRatios, self.inRatios = {}, {}, {} for met in splitRatios: outRatios, inRatios = splitRatios[met] self.metFlux[met] = sum(inRatios[rea][1] for rea in inRatios) self.outRatios[met] = dict( (rea, outRatios[rea][0]) for rea in outRatios) self.inRatios[met] = dict( (rea, inRatios[rea][0]) for rea in inRatios) # 3. Perform flux variability analysis on the model fva = FvAnalyzer("default") # always use GLPK (=> fastFVA) minmax = fva.runOnModel(self.model, fbaParams, self.fvaTolerance, self.flux)[0] self.minFlux, self.maxFlux = {}, {} for i in range(len(self.model)): self.minFlux[self.model.reactions[i].name], self.maxFlux[ self.model.reactions[i].name] = minmax[i] # 4. Check assertions failed = [] excepted = [] for i in range(len(self.assertions)): try: if not eval(self.assertions[i]): failed.append(repr(self.assertions_orig[i])) except (SyntaxError, NameError): excepted.append(repr(self.assertions_orig[i])) if printExcepted and excepted: print( "The following assertions could not be evaluated due to " "errors:\n " + "\n ".join(excepted)) if failed: print "The following assertions failed:\n " + "\n ".join(failed) else: if not syntaxOk or (printExcepted and excepted): print "All other assertions hold." else: print "All assertions hold."
print( "Error in file %s: FBA solution and model must have the " "same reactions." % os.path.basename(options.wtSolution)) _mpi_exit(comm, 1) # Build coefficient vector of linear objective function objective = array( ParamParser.convertObjFuncToLinVec(objStr, model.reactionDict)) wt_obj_value = dot(objective, wtSolution.getVecOrderedByModel(model)) # 7.b If FBA solution is not given, perform FBA else: # Compute wildtype solution via FBA fba = FbAnalyzer(fbaSolver) wt_obj_value, wtSolution, ndim = fba.runOnModel( model, fbaParams, rmDeadEnds=not options.useFullMatrix) if not options.useFullMatrix: print( "Info: The reduced network for FBA has %u reactions and " "%u metabolites." % ndim[1::-1]) if len(wtSolution) == 0: print "Model is infeasible or unbounded. Nothing to do." _mpi_exit(comm) solver = options.solver if not solver: solver = "default" numIter = options.numIter
"Error: Only one transporter type can have factors.\n" "Found factors with types %s and %s" % (main_type, typ)) exit() index += 1 for i in range(len(transpByType)): if transpByType[i][0][0] == main_type: main_index = i break # 7. Perform flux balance analysis for all combinations of transporters if solver == "": solver = "default" fba = FbAnalyzer(solver) resultList = [] checkRecursive(resultList, transpByType[main_index], transpByType[:main_index] + transpByType[main_index + 1:], fba, matrix, reactions, model.getReactionNames(), lb, ub, fbaParams) # For debugging: Output lb/ub to console if debugFlag: keys = resultList[0].keys() keys.remove("solution") keys.remove("bounds") keys.sort() for result in resultList: print "***",
def checkRecursive(resultList, currentList, otherLists, fba, matrix, reactions, reaction_names, lb, ub, fbaParams, partialResult=[]): """ recursively enumerate all meaningful combinations of transporters and launch FBA on each such combination Keyword arguments: resultList -- list for storage of results on innermost recursion level currentList -- list of importers of the same type (perform FBA if empty) otherLists -- list of lists of importers of other types (may be empty) fba -- FbAnalyzer to be used for FBA matrix -- the stoichiometric matrix of the metabolic network reactions -- dictionary of all reactions { name : matrix column } reaction_names -- list of reaction names (column index -> name) lb -- list of lower bounds (indexed like matrix columns) ub -- list of upper bounds (indexed like matrix columns) fbaParams -- ParamParser object for getting nonlinear constraints partialResult -- growing result dictionary Returns: nothing, appends results to resultList resultList is list of dictionaries containing keys <type>, <type>_co, <type>_flux, <type>_co_flux for every importer and co-importer and key "solution" for the FBA solution """ if currentList == []: # Recursion anchor: We have picked transporters of every type -> run FBA matrixSplit, reactionsSplit, lbSplit, ubSplit = \ FbAnalyzer.splitFluxes(matrix, reaction_names, lb, ub) solutionSplit = fba.run(reactionsSplit, matrixSplit, lbSplit, ubSplit, fbaParams)[1] keys = partialResult.keys() if solutionSplit == []: solution = [] for key in keys: rea = partialResult[key] partialResult[key + "_flux"] = None else: solution = array( FbAnalyzer.rejoinFluxes(solutionSplit, reactionsSplit, reactions)) for key in keys: rea = partialResult[key] if rea in reactions: partialResult[key + "_flux"] = solution[reactions[rea]] else: partialResult[key + "_flux"] = None partialResult["solution"] = solution # for debugging: store LB/UB as dictionary if debugFlag: lbub = {} for rea in reactions: rea_index = reactions[rea] lbub[rea] = (lb[rea_index], ub[rea_index]) partialResult["bounds"] = lbub resultList.append(partialResult) else: # It's sufficient to query the first element as all members of # currentList[i] have the same type. typ = currentList[0][0] # Set next currentList for recursion (head of otherLists if not empty) if otherLists == []: nextList = [] else: nextList = otherLists[0] for (_, trans_name, factor, cotrans) in currentList: # Make a copy of partialResult and extend by keys for current type tmpResult = dict(partialResult) tmpResult[typ] = trans_name tmpResult[typ + "_co"] = None if factor is not None: # Set flux through transporter to fix value index = reactions[trans_name] tmp_lb_trans = lb[index] tmp_ub_trans = ub[index] lb[index] = ub[index] = factor if cotrans is not None: # make another copy of partial result tmpResBak = dict(tmpResult) # First perform FBA without cotransporter checkRecursive(resultList, nextList, otherLists[1:], fba, matrix, reactions, reaction_names, lb, ub, fbaParams, tmpResult) # Now set flux through cotransporter to appropriate value # (factor) if cotrans is not None: # get copy of partial result tmpResult = tmpResBak tmpResult[typ + "_co"] = cotrans # Find factor cotrans_fac in currentList for (_, cotrans_name, cotrans_fac, _) in currentList: if cotrans_name == cotrans: break co_index = reactions[cotrans] tmp_lb_cotrans = lb[co_index] tmp_ub_cotrans = ub[co_index] lb[co_index] = ub[co_index] = cotrans_fac checkRecursive(resultList, nextList, otherLists[1:], fba, matrix, reactions, reaction_names, lb, ub, fbaParams, tmpResult) lb[co_index] = tmp_lb_cotrans ub[co_index] = tmp_ub_cotrans lb[index] = tmp_lb_trans ub[index] = tmp_ub_trans else: # Allow arbitrary flux through transporter index = reactions[trans_name] tmp_lb_trans = lb[index] tmp_ub_trans = ub[index] lb[index] = -inf ub[index] = inf # First perform FBA without cotransporter checkRecursive(resultList, nextList, otherLists[1:], fba, matrix, reactions, reaction_names, lb, ub, fbaParams, tmpResult) # Now also allow arbitrary flux through cotransporter if cotrans is not None: # make another copy of partial result tmpResult = dict(tmpResult) tmpResult[typ + "_co"] = cotrans co_index = reactions[cotrans] tmp_lb_cotrans = lb[co_index] tmp_ub_cotrans = ub[co_index] lb[co_index] = -inf ub[co_index] = inf checkRecursive(resultList, nextList, otherLists[1:], fba, matrix, reactions, reaction_names, lb, ub, fbaParams, tmpResult) lb[co_index] = tmp_lb_cotrans ub[co_index] = tmp_ub_cotrans lb[index] = tmp_lb_trans ub[index] = tmp_ub_trans
def run(self, objective, matrix, lb, ub, threshold=1.0, eqs=[], ineqs=[]): """ successively formulate and solve linear problems for each metabolite flux with inequality constraint 'objective value <= threshold' Arguments refer to split fluxes (i.e. non-negative flux variables). Keyword arguments: objective -- coefficient vector for linear objective function matrix -- stoichiometric matrix of the metabolic network lb -- list of lower bounds (indexed like matrix columns) ub -- list of upper bounds (indexed like matrix columns) threshold -- objective function threshold eqs -- list of (coefficient vector, right-hand side) pairs for additional equality constraints ineqs -- list of - '' - for additional inequality constraints Returns: list of minimum values, indexed like metabolites """ matrix = array(matrix) nMetabolites, nCols = matrix.shape if nMetabolites == 0: return [] # Nothing to do # Construct matrices of original equality and inequality constraints Aeq, beq, Aineq, bineq = FbAnalyzer.makeConstraintMatrices( matrix, eqs, ineqs) # Combine original inequality constraints and # 'objective function <= threshold' if Aineq is None: Aineq = [objective] bineq = [threshold] else: Aineq = vstack((Aineq, [objective])) bineq = append(bineq, threshold) result = [] ubVec = [] for i in range(nCols): # Impose artificial upper bounds so that all LPs are bounded if isinf(ub[i]): ubVec.append(LARGE_NUM) else: ubVec.append(ub[i]) psSplit = LinearProblem(Aeq, beq, Aineq, bineq, array(lb), array(ubVec), self.solver) # Compute coefficient vectors of producing metabolite fluxes # - pick only positive coefficients from stoichiometric matrix posMatrix = matrix.copy() for i in range(nMetabolites): for j in range(nCols): if posMatrix[i, j] < 0.: posMatrix[i, j] = 0. # Successively minimize each flux for index in range(nMetabolites): try: psSplit.setObjective(map(float, posMatrix[index, :])) except Exception: # Skip all-zero rows result.append(0.) continue minval, s = psSplit.minimize() psSplit.resetObjective() if len(s) == 0: result.append(nan) else: result.append(minval) return result
def runOnModel(self, model, fbaParams, threshp=.95, objFuncVal=None, rmDeadEnds=True): """ perform metabolite flux minimization on the given model with objective value <= threshp * maximum Keyword arguments: model -- the MetabolicModel fbaParams -- FBA parameters threshp -- threshold percentage (objective_value <= thresp*maximum) objFuncVal -- FBA optimum for objective function (optional) rmDeadEnds -- if True, remove all reactions with dead ends before analysis (faster and gives an optimal solution, as well) Returns: minVec, dimReduced minVec -- list of minimum values, indexed like metabolites dimReduced -- pair (nRows, nColumns) with dimensions of reduced matrix """ if rmDeadEnds: deadReactions = model.findDeadEnds(True)[1] modelRed = model.getSubModelByExcludeList(deadReactions) cbz = model.canBeZero(deadReactions) nonZeroDeadEnds = [ deadReactions[i] for i in range(len(deadReactions)) if not cbz[i] ] if nonZeroDeadEnds: print( "The following blocked reactions are constrained to a " "non-zero flux:\n " + "\n ".join(nonZeroDeadEnds) + "\nThe problem is infeasible.") return [], array(modelRed.getStoichiometricMatrix()).shape else: modelRed = model matrix = array(modelRed.getStoichiometricMatrix()) dimReduced = matrix.shape lb, ub = modelRed.getBounds() # Split fluxes into non-negative components matrixSplit, reactionsSplit, lbSplit, ubSplit = \ FbAnalyzer.splitFluxes(matrix, modelRed.getReactionNames(), lb, ub) # Build (negative) objective function vector for split fluxes objective = ParamParser.convertObjFuncToLinVec(fbaParams.objStr, reactionsSplit, len(lbSplit), fbaParams.maxmin) maxmin_factor = -1. if fbaParams.maxmin else 1. # If the optimum of the objective function is not given, perform FBA if objFuncVal is None: fba = FbAnalyzer(self.solver) objFuncVal, sFlux = fba.run(reactionsSplit, matrixSplit, lbSplit, ubSplit, fbaParams) if len(sFlux) == 0: return [], dimReduced # Use negative threshold (objective value >= threshold is equivalent to # -objective value <= -threshold, and objective already has coefficient # -1 due to maximization) threshold = maxmin_factor * objFuncVal * threshp print "obj func. opt:", objFuncVal print "Threshold: ", threshold try: eqs, ineqs = ParamParser.linConstraintsToVectors( fbaParams.linConstraints, modelRed.reactionDict, len(lbSplit)) except ValueError, e: # If any linear constraint is contradictory, report error print "Optimization not possible due to contradictory constraints:" print " " + e exit()
def run(self, matrix, lb, ub, wtSolution, eqs=[], ineqs=[], numIter=1, weights=None): """ construct and solve the quadratic optimization problem Keyword arguments: matrix -- the stoichiometric matrix of the metabolic network lb -- list of lower bounds (indexed like matrix columns) ub -- list of upper bounds (indexed like matrix columns) wtSolution -- FBA solution for the wildtype (list indexed like matrix columns) eqs -- list of (coefficient vector, right-hand side) pairs for additional equality constraints ineqs -- list of - '' - for additional inequality constraints numIter -- number of iterations of NLP to perform weights -- weight vector for weighted MOMA (None -> perform regular MOMA, else: weight flux i with weights[i]) Returns: distance, solution, status distance -- minimum possible distance from wtSolution with the given matrix & constraints solution -- a flux vector with minimal distance to wtSolution (list indexed like matrix columns) status -- SolverStatus after optimization """ wtVec = array(wtSolution) # Construct matrices of original equality and inequality constraints Aeq, beq, Aineq, bineq = FbAnalyzer.makeConstraintMatrices( matrix, eqs, ineqs) try: if MomaProblem.isCvxQpSolver(self.solver): ps = MomaProblem(Aeq, beq, Aineq, bineq, lb, ub, self.solver, wtVec, weights) else: ps = NonLinearProblem(Aeq, beq, Aineq, bineq, lb, ub, self.solver) if weights is None: ps.setObjective(lambda x: dot(x - wtVec, x - wtVec)) ps.setObjGrad(lambda x: 2 * (x - wtVec)) else: if not isinstance(weights, ndarray): weights = array(weights) ps.setObjective(lambda x: dot(x - wtVec, (x - wtVec) * weights)) ps.setObjGrad(lambda x: 2 * sqrt(weights) * (x - wtVec)) spIter = StartPointIterator(len(lb), numIter) spIter.setRange(-1., 1.) ps.setStartPointIterator(spIter) except ValueError, strerror: print strerror exit()
def run(self, objective, matrix, lb, ub, threshold=.95, eqs=[], ineqs=[]): """ successively formulate and solve linear problems for each flux with inequality constraint 'objective value <= threshold' Keyword arguments: objective -- coefficient vector for linear objective function matrix -- stoichiometric matrix lb -- list of lower bounds, indexed like reactions ub -- list of upper bounds, indexed like reactions threshold -- objective function threshold eqs -- list of (coefficient vector, right-hand side) pairs for additional equality constraints ineqs -- list of - '' - for additional inequality constraints Returns: list of pairs (minimum, maximum), indexed like reactions """ # Construct matrices of original equality and inequality constraints Aeq, beq, Aineq, bineq = FbAnalyzer.makeConstraintMatrices( matrix, eqs, ineqs) #lb = [-1000]*939 #ub = [1000]*939 # Combine original inequality constraints and # 'objective function <= threshold' if Aineq is None: Aineq = [objective] bineq = [threshold] else: Aineq = vstack((Aineq, [objective])) bineq = append(bineq, threshold) nReactions = len(lb) lbVec, ubVec = [], [] for i in range(nReactions): if isinf(lb[i]): lbVec.append(-LARGE_NUM) else: lbVec.append(lb[i]) if isinf(ub[i]): ubVec.append(LARGE_NUM) else: ubVec.append(ub[i]) ps = LinearProblem(Aeq, beq, Aineq, bineq, lbVec, ubVec, self.solver) minmax = [None] * nReactions # First maximize each flux for index in range(nReactions): ps.setObjective([0.] * index + [-1.] + [0.] * (nReactions - index - 1)) s = ps.minimize()[1] ps.resetObjective() # catch random infeasible solution that resolves if the solver is recreated if len(s) == 0: ps = LinearProblem(Aeq, beq, Aineq, bineq, lbVec, ubVec, self.solver) ps.setObjective([0.] * index + [-1.] + [0.] * (nReactions - index - 1)) s = ps.minimize()[1] ps.resetObjective() if len(s) != 0: maxval = s[index] else: maxval = nan s = None minmax[index] = maxval # Now minimize each flux for index in range(nReactions): ps.setObjective([0.] * index + [1.] + [0.] * (nReactions - index - 1)) s = ps.minimize()[1] ps.resetObjective() # catch random infeasible solution that resolves if the solver is recreated if len(s) == 0: ps = LinearProblem(Aeq, beq, Aineq, bineq, lbVec, ubVec, self.solver) ps.setObjective([0.] * index + [-1.] + [0.] * (nReactions - index - 1)) s = ps.minimize()[1] ps.resetObjective() if len(s) != 0: minval = s[index] else: minval = nan s = None minmax[index] = minval, minmax[index] return minmax
if not sFlux.hasSameReactions(model): print "Error: Solution and model must have the same reactions." exit() # Sort solution like matrix columns sFlux = sFlux.getVecOrderedByModel(modelRed) # Evaluate the objective function at solution obj_value = maxmin_factor * dot(objective, sFlux) # Case 3. Perform flux balance analysis on the metabolic network # (only if no solution file is given) else: fba = FbAnalyzer(self.solver) if splitFluxes: # Split flux variables for FBA matrixSplit, reactionsSplit, lbSplit, ubSplit = \ FbAnalyzer.splitFluxes(matrix, modelRed.getReactionNames(), lb, ub) obj_value, sFlux = fba.run(reactionsSplit, matrixSplit, lbSplit, ubSplit, fbaParams) # Get joined solution (for output) sFlux = array( FbAnalyzer.rejoinFluxes(sFlux, reactionsSplit, modelRed.reactionDict)) else: obj_value, sFlux = fba.run(modelRed.getReactionNames(), matrix, lb, ub, fbaParams)