
"""
Run from command line to get help with input
phenix.python cctbx_sources\Develop\phaser\phaser\BLASTrunner.py
"""
import BLASTnMRfunc
import sys
import traceback
import subprocess
import logging
import os
import time

argn = 1
argc = len(sys.argv)


# prompt user for value if it's not on the commandline
def Inputarg(varname):
    global argn
    global argc
    if argc > 1 and argn < argc:
       myvar = sys.argv[argn]
       argn = argn + 1
    else:
       myvar = raw_input(varname)

    return myvar


def GetFullPathExe(exefname):
    whichcmd = "which"
    osdepbool = True
    if os.sys.platform == "win32":
        whichcmd = "where"
    #
    (stdoutstr, stderrstr) = subprocess.Popen("%s %s" %(whichcmd,exefname),
      shell=osdepbool, stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()
    #
    if len(stdoutstr) > 0:
        fullpathexe = stdoutstr.splitlines()[0]
    else:
        fullpathexe = ""
    #
    return fullpathexe





if __name__ == "__main__":
    if argc > 1:
      for arg in sys.argv:
          print arg

    print """You can either \n
a) Do a BLAST homology search for a particular pdb id to set up folders and
   input files to be used in subsequent MR calculations.
b) Do MR calculations on an existing set of folders and input files.
c) Combine (a) and (b).
d) Gather results from folders with finished MR calculations.
e) Generate an empty database only containing the table and column layout.
f) Use an existing BLAST output to set up folders and input files to be used
   in subsequent MR calculations.
    """
    answer = Inputarg("What do you want to do? (a,b,c,d,e,f): ")

    sshexe = "notused"
    scpexe = "notused"
    userid = "notused"
    mtzfolder = "notused"
    phaserexe = "notused"
    clustalwexe = "notused"
    superposeexe = "notused"
    passwd = ""
    noRNP = False
    targetpdbid = ""
    calclabel = ""
    winoptssh = None

    targetpdbid = Inputarg("Enter the target pdbid: ").upper()

    if answer=="a" or answer=="c" or answer=="f":
        maxseqid = float(Inputarg("Enter maximum allowed value of sequence identity: "))
        minseqid = float(Inputarg("Enter minimum allowed value of sequence identity: "))
        maxpdbs = float(Inputarg("Enter permitted number of pdb ids to be returned: "))

        print "Using ulysses and zeus for BLAST homology searches and your PC for MR runs."
        usepasswd = Inputarg("Do you have passwordless authentication to ulysses and zeus through ssh? (Y/N): ")
        if usepasswd != "Y":
            passwd = Inputarg("OK, so what is your password?: ")
# Get program filenames if they are in the system path
# Also get rid of \r\n that where on windows append with .strip()
        sshexe = GetFullPathExe("ssh")
        if len(sshexe)==0:
            sshexe = GetFullPathExe("plink")
        if len(sshexe)==0:
            print "Enter fully qualified file paths for the ssh client:"
            sshexe = Inputarg("ssh: ")
        else:
            if os.sys.platform == "win32":
                winoptssh = "-ssh" # necessary option for plink.exe

        scpexe = GetFullPathExe("scp")
        if len(scpexe)==0:
            scpexe = GetFullPathExe("pscp")
        if len(scpexe)==0:
            print "Enter fully qualified file paths for the scp program:"
            scpexe = Inputarg("scp: ")

        mtzfolder = Inputarg("Enter path for the mtz files: ")
        userid = Inputarg("Enter your userid for ulysses and zeus: ")

    if answer=="a":
        print "Do you only want to collect the homolouges without doing subsequent RNP jobs?"
        if str(Inputarg("yes/no: ")).lower().find("y") > -1:
            noRNP = True

    if answer=="a" or answer=="b" or answer=="c" or answer=="f":
        phaserexe = GetFullPathExe("phenix.phaser")
        if len(phaserexe)==0:
            print "Enter fully qualified file path for the phaser program:"
            phaserexe = Inputarg("phaser: ")

    if answer=="a" or answer=="c" or answer=="f":
        clustalwexe = GetFullPathExe("clustalw")
        if len(clustalwexe)==0:
            clustalwexe = GetFullPathExe("clustalw2")
        if len(clustalwexe)==0:
            print "Enter fully qualified file path for the clustalw program:"
            clustalwexe = Inputarg("clustalw: ")

        myinc = Inputarg("Specify the smallest difference in sequence identities between different models from the BLAST search to be permitted?: ")

        superposeexe = GetFullPathExe("superpose")
        if len(superposeexe)==0:
            print "Enter the fully qualified file path for the superpose program:"
            superposeexe = Inputarg("superpose: ")

    if answer =="b" or answer =="c" or answer=="f":
        njobs = int(Inputarg("Enter the number of Phaser MR jobs to run concurrently: "))
        nmaxsols = int(Inputarg("Enter maximum number of solutions for each MR calculation : "))
        fmaxhours = float(Inputarg("Enter maximum duration of hours for each MR calculation : "))

    if answer=="a" or answer=="b" or answer=="c" or answer=="f":
        print "Paths for ssh, scp, phaser, clustalw, superpose are:\n%s\n%s\n%s\n%s\n%s"\
          %(sshexe,scpexe,phaserexe, clustalwexe, superposeexe)

    calclabel = Inputarg("Enter a name tag for the calculations: ")

    errorcode = [0]

    myobj = BLASTnMRfunc.BLASTrunner(targetpdbid, sshexe, scpexe, userid,
      mtzfolder, phaserexe, clustalwexe, superposeexe, calclabel, passwd,
      winoptssh, errorcode)

    if answer=="f":
        myobj.writeBLASTxml = False

    if answer =="b" or answer =="c" or answer=="f":
        myobj.fmaxhours = fmaxhours
        myobj.nmaxsols = nmaxsols

    if answer!="d" and answer!="b" :
        s = Inputarg("Use a protocol other than default for sculpting models (y/n) ")
        if s.lower().find("y") > -1:
            myobj.sculptprotocol = Inputarg("Which protocol should be used for sculpting the models? ")

    if answer =="a" or answer =="b" or answer =="c" or answer=="f":
        s = Inputarg("Seed multicomponent calculations on components a,b,c with refined template solution of a,b (y/n) ")
        if s.lower().find("y") > -1:
            myobj.busecurrenttmpl = True

    if answer =="a" or answer =="c" or answer=="f":
        s = Inputarg("Use intensities instead of amplitudes in the mtz file? (y/n) ")
        if s.lower().find("y") > -1:
            myobj.buseIntensities = True

    try:
        myobj.pretext = "\nRun started on " + time.asctime( time.localtime(time.time()))
        if answer=="a" or answer=="f" :
            myobj.BLASTnSetupMRruns(maxseqid, minseqid, maxpdbs, float(myinc), noRNP)

        if answer =="b":
            myobj.RunMRautoFromlistFile(njobs)

        if answer =="c":
            myobj.BLASTnMRrun(maxseqid, minseqid, maxpdbs, njobs, float(myinc))

        if answer =="d" or answer =="e":
            TaggedPDBfileliststr = ""
            OnlyDBLayout = False

            if answer =="d":
                DBfname = Inputarg("Enter the database file name that will hold all the results: ")

            if answer =="e":
                DBfname = Inputarg("Enter name of the empty database file that will only contain table and column layout: ")
                OnlyDBLayout = True

            s = Inputarg("Do you supply a list of filenames and label names for PDB codes to label? (Y/N): ")
            if s.lower().find("y") > -1:
                TaggedPDBfileliststr = Inputarg("Enter filenames with PDB codes of special PDBs and a corresponding name to label each MR model matching those PDB codes: ")

            othersols = [["",""]]
            s = Inputarg("Do you have additional solution files with common prefixes? (Y/N): ")
            if s.lower().find("y") > -1:
                N = int(Inputarg("How many? "))
                if N > 0:
                    for i in range(N):
                        suffix = Inputarg("Enter database column suffix for the %d. solution: " %(i+1))
                        solname = Inputarg("Enter filename prefix for the %d. solution: " %(i+1))
                        othersols.append([suffix, solname])

            myobj.CollateMRautoResultsFromlistFile(DBfname, TaggedPDBfileliststr, OnlyDBLayout, othersols)

        myobj.logger.log(logging.INFO,"\nRun finished on " + \
         time.asctime( time.localtime(time.time())) + \
         " with return value of %d\n" %errorcode[0])

    except Exception, m:
        errorcode[0] += 1
        myobj.logger.log(logging.ERROR, str(m) + "\n" + traceback.format_exc() + \
         "\nRun finished on " + time.asctime( time.localtime(time.time())) + \
         " with return value of %d\n" %errorcode[0])
        myobj.logger.handlers[0].close()
        myobj.logger.handlers[1].close()

    exit(errorcode[0])

