def reactionBounds(self,model,reactionName,objDir = -1.0):
     solver = LPSolver()
     posObjective = {reactionName:objDir}
     negObjective = {reactionName:1.0*objDir}
     
     posPrediction = solver.run(model,posObjective)
     posValue = posPrediction[reactionName]
     
     negPrediction = solver.run(model,negObjective)
     negValue = negPrediction[reactionName]
     
     return (negValue,posValue)
def findBoundaryProduction(originalModel, bounds, combiLimits, objectiveName, productionName):
    model = LinearModel()
    model.extend(originalModel)
    if combiLimits != None:
        for (targetValues,limit) in combiLimits:
            model = addCombinationLimit(model, targetValues,limit)
    #objectiveMap = {objectiveName:-1.0}
    objectiveMap = {productionName:1.0}
    model.addColumnLimits(bounds)
    lp = LPSolver()
    fluxMap = lp.run(model,objectiveMap)
    objectiveValue = fluxMap[objectiveName]
    productionValue = fluxMap[productionName]
    return (fluxMap,objectiveValue,productionValue)
 def exportMetabolite(self,model,metaboliteName,max=1e3):
     solver= LPSolver()
     exportTag = "EX_test_export"
     reaction = {metaboliteName:-1.0}
     objective = {exportTag:-1.0}
     
     model.addColumn(exportTag,reaction)
     model.addColumnLimit(exportTag,(0.0,max))        
     prediction = solver.run(model,objective)
     exportValue = prediction[exportTag]
     
     model.removeColumn(exportTag)
     
     return exportValue
def simpleTestOpt(con,originalModel,controlTargets,naturalObjectiveName,syntheticObjectiveName,verbose = False,naturalCoefficient=-0.05):
    '''
    Optimiztaion Tester for depdenency anlaysis
    Construciton object contains union of all libraries which are used by target sets.
    
    '''
    gRMap = con.getGeneTargetMap()
    regulationLibrary = con.regulationLibrary
    objective = {}
    
    for (lib,prefix,target) in controlTargets:
        if gRMap != None:
            if target in gRMap.keys():
                targets = gRMap[target]
            else:
                print "target %s not found in gene map" % (target)
                targets = [target]
        else:
            targets = [target]
        for target in targets:
            if lib in regulationLibrary.keys():
                if target in con.regulationLibrary[lib].keys():
                    controlValue = con.regulationLibrary[lib][target]
                    objective[target] = -1.0 * controlValue
    
    iObjective = dict(objective)
    objective[naturalObjectiveName] = naturalCoefficient
            
    lp = LPSolver()
    prediction = lp.run(originalModel, objective= objective)

    rObjective = iObjective
    if verbose: print "Current objective[%s]: %s" % (str(len(iObjective)),iObjective)
    (iGeneObjective,iOtherObjective) = (None,None)
    if originalModel.controlMap != None:
        (iGeneObjective,iOtherObjective) = originalModel.printGeneObjective(iObjective)
        if verbose: print "Current Genetic objective[%s]: %s" % (str(len(iGeneObjective)),iGeneObjective)
        if verbose: print "Current Other objective: %s" % (iOtherObjective)
        rObjective = iGeneObjective
        
    lp.clear()
    del lp
    
    return (prediction,rObjective)
 def checkSolverScip(self,modelMatrix,predVal,delta=1e-3):
     lp = LPSolver()
     lp.setModel(modelMatrix)
     lp.runIntOpt()
     scipPredVal = lp.getMipPredictionMap()
     (testRows,badRows) = self.checkValues(modelMatrix.data,scipPredVal,modelMatrix.getRowLimits())
     if self.verbose: print "--Debug: number of failed rows %s" % (len(badRows))
     lp.clear()
     solverDiff = self.debugCompareFluxes(predVal,scipPredVal)
     if self.verbose: print "--Debug: difference in glpk / scip %s" % (len(solverDiff))
     
     return (testRows,badRows,solverDiff)
def main_function():

    parser = OptionParser()

    parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="set verbose mode")

    parser.add_option(
        "--config",
        type="string",
        metavar="FILE",
        dest="config",
        default="redirector.config",
        help="Master configuration file that provides most setting for the Flux Balanace Analysis. Extra variable settings will be ingnored.  Hence the same config can be used for multiple analysis functions",
    )

    parser.add_option(
        "-c",
        "--modelConfig",
        type="string",
        metavar="FILE",
        dest="configFileName",
        default="model_config.txt",
        help="Configuration file which sets model files",
    )

    parser.add_option(
        "-n",
        "--configNames",
        type="string",
        metavar="String",
        dest="configNames",
        default="Default",
        help="A comma separated list of the names of configurations to use, as set out in the configuration file",
    )

    parser.add_option(
        "-m",
        "--modelname",
        type="string",
        metavar="String",
        dest="modelName",
        default="",
        help="Name of model(s) from the modelconfiguration file",
    )

    parser.add_option(
        "-b",
        "--bioObjective",
        type="string",
        dest="bioObj",
        default="Biomass",
        help="Name / ID of biological objective reaction",
        metavar="String",
    )

    parser.add_option(
        "-o",
        "--outputfile",
        dest="outputFileName",
        default=None,
        help="Name of report file to be generated",
        metavar="FILE",
    )

    parser.add_option(
        "-r",
        "--result_directory",
        type="string",
        metavar="directory",
        dest="resultDirectory",
        default="../../results/",
        help="Directory where results are stored",
    )

    parser.add_option(
        "--targets",
        type="string",
        metavar="String",
        dest="targets",
        default="",
        help="List of valid reaction target, if left blank will be automatically filled in from metabolic network file",
    )

    parser.add_option(
        "--report",
        action="store_true",
        dest="isReport",
        default=False,
        help="When this tag is used a report will be generated when the analysis is finished",
        metavar="boolean",
    )

    parser.add_option("--debug", action="store_true", dest="debug", default=False, help="turn on debug mode")

    parser.add_option("--gm", "--GeneMap", action="store_true", dest="useGeneMap", default=False, help="Use Gene Map")

    parser.add_option(
        "--section",
        type="string",
        metavar="String",
        dest="subSections",
        default="",
        help="Comma separated list of sections of the model files to use",
    )

    # -------------------------------
    # Parse options
    # -------------------------------

    (options, args) = parser.parse_args()
    config = ReflectionConfig()
    config.readfp(open("Redirector.config"))

    # ---------------------------
    # configure preset analysis
    # ---------------------------

    configNames = options.configNames.split(",")
    configNames.insert(0, "Redirector Model")
    for name in configNames:
        config.merge(name, "Redirector", append=True)

    # ----------------------------------------
    # reflect options from configuration
    # ----------------------------------------

    config.reflect("Redirector", options)
    config.load("Redirector", options.__dict__, override=False)

    # -----------------------------------------
    # Check and Build Storage Directories
    # -----------------------------------------

    dataDirectory = config.getValue("Redirector", "dataDirectory", classType="".__class__)
    resultsDirectory = config.getValue("Redirector", "resultDirectory", classType="".__class__)
    analysisDirectory = config.getValue("Redirector", "analysisDirectory", classType="".__class__)

    if not os.path.exists(dataDirectory):
        raise IOError("unable to find required data directory" % dataDirectory)
    if not os.path.exists(resultsDirectory):
        os.makedirs(resultsDirectory)
    if not os.path.exists(analysisDirectory):
        os.makedirs(analysisDirectory)

    # ----------------------------
    # Parse Inputs
    # ----------------------------

    verbose = options.verbose
    modelName = options.modelName
    objectiveName = options.bioObj
    outputFileName = options.outputFileName

    """
    #----------------------------------------------------
    # Initialize and set values for tools and factories
    #----------------------------------------------------
    """

    naturalObjective = {objectiveName: -1.0}

    if verbose:
        print "Flux Balanace Analysis Version 1.6"
    if verbose:
        print "Model names: [%s]" % (modelName)
    if verbose:
        print "Parsing data files for [%s]" % (modelName)

    """
    I. Parse data files and configuration settings
    """

    if verbose:
        print "----------------Loading Metabolic Models---------------"
    modelNames = modelName.split(",")
    modelFactory = ModelFactory()
    config.reflect("Redirector", modelFactory)
    (fluxModel, modelMatrix, reducer, geneReduction) = modelFactory.loadModel(modelNames)

    model = modelMatrix
    if verbose:
        print "removing objectives from target set"
    targets = modelMatrix.targets
    if verbose:
        print "Targets List Size [%s]" % len(targets)

    lps = LPSolver()
    predictions = lps.run(model, naturalObjective)
    objectiveValue = predictions[objectiveName]
    lps.clear()

    if verbose:
        print "Optimized Objective [%s] Value [%s]" % (objectiveName, objectiveValue)

    report = fluxModel.getReport()
    report.addColumnHash("Flux", predictions)

    if outputFileName == None or outputFileName == "":
        outputFileName = resultsDirectory + "FBA_%s_%s.txt" % (modelName, strftime("%Y%m%dT%H%M%S"))

    writer = ReportWriter()
    writer.setFile(outputFileName)
    writer.write(report)
    writer.closeFile()

    if verbose:
        print "Report Written [%s]" % (outputFileName)
def productionLevels(originalModel,options,minBio=0.20,verbose=False):
    naturalObjectiveName  = options.bioObj
    syntheticObjectiveName = options.synthObj
    
    cellularObjective = {naturalObjectiveName:-1.0}
    syntheticObjective = {syntheticObjectiveName:-1.0}
    
    lo = LPSolver()
    lo.setModel(originalModel)
    oPredVal = lo.run(objective = cellularObjective)
    oBioVal = oPredVal[naturalObjectiveName]
    oSynthVal = oPredVal[syntheticObjectiveName]

    if verbose: print "Max cellular: Biological [%s] Synthetic: [%s]" % (oBioVal, oSynthVal)
    
    #---------------------------------------
    # Values for Max Synthetic Objective
    #---------------------------------------
    
    sPredVal = lo.run(objective = syntheticObjective)
    sBioVal = sPredVal[naturalObjectiveName]
    sSynthVal = sPredVal[syntheticObjectiveName]
    lo.clear()
    
    if verbose: print "Max synthetic: Biological [%s] Synthetic: [%s]" % (sBioVal, sSynthVal)

    #-----------------------------------
    # Values for minimum Natural objective
    #-----------------------------------
    
    minObjVal = oBioVal*0.20
    originalModel.addColumnLimit(naturalObjectiveName,(minObjVal,None))
    lo = LPSolver()
    s2PredVal = lo.run(model=originalModel,objective = syntheticObjective)
    s2BioVal = s2PredVal[naturalObjectiveName]
    s2SynthVal = s2PredVal[syntheticObjectiveName]
    
    lo.clear()
    
    return (oPredVal,sPredVal,s2PredVal)
def findControlDependencies(con,originalModel,controls,exclusion,options,searchSize=0,targetPrecent = 0.40,verbose = False,usePersist=False):
    name = "".join(originalModel.modelName)
    naturalObjectiveName  = options.bioObj
    syntheticObjectiveName = options.synthObj
    controlTag = options.control
    
    persistTag = "Dependency_persist_%s_%s_%s_%s_%s_%s" % (controlTag,name,naturalObjectiveName,syntheticObjectiveName,str(searchSize),str(targetPercent))
    delta = 1e-4
    iter = 0
    iterSave = 100
    
    completed = set()
    controlSet = set()
    controlMap = []
    report = Report()
    
    persistValue = None
    if usePersist:
        persistValue = loadPersist(persistTag)
        if persistValue != None:
            print "loading persisted dependency search"
            (completed,controlMap,controlSet,report) = persistValue 
    
    controlSubSets = combinations(controls,searchSize)
    xcontrolSubSets = set(controlSubSets)
    xcontrolSubSets = xcontrolSubSets.difference(completed)
    
    print "Control dependency depth [%s] search sets [%s]" % (searchSize,len(xcontrolSubSets))
            
    lo = LPSolver()
    sObjective = {syntheticObjectiveName:-1.0}
    iPred = lo.run(model= originalModel, objective = sObjective)
    synthVal = iPred[syntheticObjectiveName]
    targetSVal = synthVal * targetPrecent
        
    #print "Synthetic Target [%s] = %s * %s" % (targetSVal,synthVal,targetPercent)
        
    controlMin = con.controlMin
    controlMax = con.controlMax
        
    con.controlMin = 0
    con.controlMax = 0
        
    targets = []
    gRMap = con.getGeneTargetMap()
        
    for (lib,prefix,target) in controls:
        if gRMap != None:
            if target in gRMap.keys():
                rTargets = gRMap[target]
                targets.extend(rTargets)
        else:
            targets.append(target)        
        
    #-----------------------------
    # Run optimization
    #-----------------------------
    iter = 0
    for controlSub in xcontrolSubSets:
        iter += 1
        completed.add(controlSub)
        
        #Analysis of control
        (prediction,objective) = simpleTestOpt(con, originalModel, controlSub, naturalObjectiveName,syntheticObjectiveName,verbose=False,naturalCoefficient=-0.5)
                
        #Save results        
        syntheticFlux = prediction[syntheticObjectiveName]
        #if verbose: print "Objective [%s]" % (objective)
        #if verbose: print "Flux [%s]" % (prediction)
            
        if syntheticFlux > targetSVal:    
            controlThresholds = controlThreshold([controlSub], exclusion)
            if controlSub in controlThresholds.keys():
                if syntheticFlux <= controlThresholds[controlSub] + delta:
                    #if verbose: print "no improvement"
                    continue
                
            if verbose: print "Synthetic Production [%s]" % (syntheticFlux)    
            
            controlResultMap = originalModel.annotateGenes(objective,annotationName = "bnumber", regex="[a-zA-Z0-9\(\)]+")
            controlTag = str(controlResultMap.keys())                
            
            controlSV = (controlSub,syntheticFlux)
            controlSet.add(controlSV)
            controlSV = (controlResultMap,syntheticFlux)
            controlMap.append(controlSV)
            
            #if verbose: print "Control Set [%s]" % (controlSub)
            if verbose: print "Control Map [%s]" % (controlResultMap)
                
            report.add(controlTag, "control values", controlResultMap)
            report.add(controlTag, "production", syntheticFlux)
                
        if iter % iterSave == 0:
            print "persisting iteration %s" % (iter)
            persistValue = (completed, controlSet,controlMap, report)
            persist(persistTag, persistValue)
                     
    con.controlMin = controlMin
    con.controlMax = controlMax
        
    #Persist dependency search
    if usePersist:
        persistValue = (completed, controlSet,controlMap, report)
        persist(persistTag, persistValue)

    return (controlMap,controlSet,report)
def LinearModelVariableBoundarys(originalModel, objectiveName, targets=None, pickleFileName=None, strict=False, minObjectivePercent=None,searchSize=1):
    '''
    Find min and max boundaries for the dependent variables of a linear model. 
    Uses limitMap as constraints on model.
     
    Add cumulative boundary persistence as pickle file function.
    
    @param linearModel: linear model to be analyzed
    @type linearModel: LinearModel
    @param limitMap: map of variable names and lower and upper limits
    @type limitMap: {variableName, (float, float)  
    @param targets: list of variables to perform analysis on
    @type targets: list
    @return: dictionary of lower and upper limits for each variable
    @rtype: {variableName: (lowerlimit, upperlimit)}
    '''
    
    linearModel = LinearModel()
    linearModel.extend(originalModel)
    
    if pickleFileName != None:
        if os.path.isfile(pickleFileName):
            print "loading saved flux boundaries"
            pFile = open(pickleFileName)
            result = pickle.load(pFile)
            pFile.close()
            return result
    
    originalLimits = linearModel.getColumnLimits()
    originalObjectiveLimit = originalLimits[objectiveName]
    objectiveVector = {objectiveName:-1.0}
    
    solver = LPSolver()
    originalValues = solver.run(model=linearModel, objective=objectiveVector)
    originalObjectiveValue = originalValues[objectiveName]
        
    if minObjectivePercent != None:
        minObjectiveValue = originalObjectiveValue * minObjectivePercent
        linearModel.addColumnLimit(objectiveName,(minObjectiveValue,None))
    
    if targets == None:
        targets = linearModel.getColumnNames()
    targets.add(objectiveName)

    print "Searching flux boundaries for %s > %s" % (objectiveName, minObjectiveValue)
    result = {}
    targetValues = targetValueCombinations(targets, [-1.0,1.0])
    controlSubSets = combinations(targetValues,searchSize)
    xcontrolSubSets = set(controlSubSets)
    
    for name in targets:
        nameTag = name
    #   if name not in linearModel.getColumnNames():
    #       print "target %s not found in model"
    #       print "boundary discovery not possible"
    #       continue
        
    #for iTargetValues in xcontrolSubSets:
    #    name = "testControlValue"
    #    nameTag = iTargetValues
    #    linearModel = combinationLimitBuilder(linearModel, iTargetValues, name)
        
        result[name] = (None,None)
        negObjective = {name:1.0}
        posObjective = {name:-1.0}
        
        solver.clearObjective()
        negValues = solver.run(linearModel, objective=negObjective)
        negValue = negValues[name]
        
        solver.clearObjective()
        posValues = solver.run(linearModel, objective=posObjective)
        posValue = posValues[name]
        
        delta = 1e-4
        if posValue != 0 or negValue !=0:
            pass
        
        if False:
            originalValue = originalValues[name]
            originalLimit = originalLimits[name]
        
            if not (negValue - delta <= originalValue <= posValue + delta):
                print "original value not in boundary"
                print "objective value [%s] (%s) %s <= %s <= %s (%s)" % (name, originalLimit[0], negValue, originalValue, posValue, originalLimit[1])
                #print "value neg code %s pos code %s" % (nscode, pscode)
                (negValue,posValue) = (originalLimit[0],originalLimit[1])
            else:
                #print "objective value [%s] (%s) %s <= %s <= %s (%s)" % (name, originalLimit[0], negValue, originalValue, posValue, originalLimit[1])
                pass
                
            if negValue == None or negValue == float("-inf"):
                continue
    
            if posValue == None or posValue == float("-inf"):
                continue
        
        result[nameTag] = (negValue,posValue)
        print "%s < [%s] < %s " % (negValue,nameTag,posValue)
    
    if pickleFileName != None:
        pFile = open(pickleFileName,'w')
        pickle.dump(result, pFile)
        pFile.close()
        
    solver.clear()
    del solver
    
    linearModel.addColumnLimit(objectiveName,originalObjectiveLimit)
    #targets.remove(objectiveName)
        
    return result