#
#  findMotifs.py
#  ENRAGE
#
try:
    import psyco
    psyco.full()
except:
    pass

import sys
import os
import optparse
from cistematic.experiments.fasta import Fasta
from cistematic.programs.meme import Meme
from cistematic.programs.cisGreedy import CisGreedy
from commoncode import getConfigParser, getConfigOption, getConfigIntOption, getConfigFloatOption, getConfigBoolOption
#TODO: cisSampler is not supported yet!
#from cistematic.programs.cisSampler import CisSampler

print "findMotifs: version 3.5"

def main(argv=None):
    if not argv:
        argv = sys.argv

    usage = "usage: python %prog explabel regions.fsa [options]"

    parser = getParser(usage)
    (options, args) = parser.parse_args(argv[1:])

    if len(args) < 2:
        print usage
        print "\n\twhere at least one of the motif finders (meme or cisGreedy) must be specified\n"
        sys.exit(1)

    expbase = args[0]
    fsafile = args[1]

    doCisSampler = False
    if "--cisSampler" in sys.argv:
        print "cisSampler is not supported yet! avoid using it for now"
        doCisSampler = True

    findMotifs(expbase, fsafile, options.doMeme, options.doCisGreedy, options.saveLogo,
               options.threshold, options.numMotifs, options.maxWidth, options.maskLower,
               doCisSampler)


def getParser(usage):
    parser = optparse.OptionParser(usage=usage)
    parser.add_option("--meme", action="store_true", dest="doMeme")
    parser.add_option("--cisGreedy", action="store_true", dest="doCisGreedy")
    parser.add_option("--logo", action="store_true", dest="saveLogo")
    parser.add_option("--threshold", type="float", dest="threshold")
    parser.add_option("--prefix", dest="motifPrefix")
    parser.add_option("--numMotifs", dest="numMotifs")
    parser.add_option("--maxWidth", type="int", dest="maxWidth")
    parser.add_option("--maskLower", action="store_true", dest="maskLower")

    configParser = getConfigParser()
    section = "findMotifs"
    doMeme = getConfigBoolOption(configParser, section, "doMeme", False)
    doCisGreedy = getConfigBoolOption(configParser, section, "doCisGreedy", False)
    saveLogo = getConfigBoolOption(configParser, section, "saveLogo", False)
    threshold = getConfigFloatOption(configParser, section, "threshold", 75.)
    numMotifs = getConfigOption(configParser, section, "numMotifs", "10")
    maxWidth = getConfigIntOption(configParser, section, "maxWidth", 28)
    maskLower = getConfigBoolOption(configParser, section, "maskLower", False)


    parser.set_defaults(doMeme=doMeme, doCisGreedy=doCisGreedy, saveLogo=saveLogo,
                        threshold=threshold, numMotifs=numMotifs, maxWidth=maxWidth, maskLower=maskLower)

    return parser


def findMotifs(expbase, fsafile, doMeme=False, doCisGreedy=False, saveLogo=False, threshold=75.,
               numMotifs="10", maxWidth=28, maskLower=False, doCisSampler=False):

    motifPrefix = expbase

    #TODO: cisSampler is not supported yet!
    #if doMeme or doCisGreedy or doCisSampler:
    if not (doMeme or doCisGreedy):
        print "error: must specify at least one motif finder - exiting"
        sys.exit(1)

    exp = Fasta(expbase, "%s.db" % expbase)

    exp.initialize()
    if maskLower:
        exp.setMaskLowerCase(True)

    if doMeme:
        prog4 = Meme()
        prog4.setMaxWidth(maxWidth)
        prog4.setNumMotifs(numMotifs)
        prog4.setModel("zoops")
        exp.appendProgram(prog4)

    if doCisGreedy:
        prog5 = CisGreedy()
        prog5.setGenExpOptions([])
        prog5.setMaxWidth(maxWidth)
        prog5.setNumMotifs(numMotifs)
        exp.appendProgram(prog5)

    #TODO: cisSampler is not supported yet!
    #if doCisSampler:
    #    prog6 = CisSampler()
    #    prog6.setGenExpOptions([])
    #    prog6.setMaxWidth(maxWidth)
    #    prog6.setNumMotifs(numMotifs)
    #    exp.appendProgram(prog6)

    exp.run(fsafile)
    exp.createAnalysis()
    exp.loadAnalysis()
    exp.mapMotifs(threshold, verbose=False)
    exp.exportMotifs(prefix = motifPrefix)
    if saveLogo:
        exp.exportLogos(prefix = motifPrefix)

    exp.draw("%s.png" % expbase, maxOccurences=4000)
    print "deleting database..."
    del exp
    os.remove("%s.db" % expbase)


if __name__ == "__main__":
    main(sys.argv)