def generateTSsearchDynamo(compFile):
    jobGraph = nx.DiGraph()
    currentDir = getcwd()
    data = parseFDynamoCompileScript(compFile)

    newNode = FDynamoNode(data["inputFile"], currentDir)
    newNode.coordsIn = data["coordsIn"]
    newNode.coordsOut = data["coordsOut"]
    newNode.verification = ["Opt", "Freq"]
    newNode.slurmFile = None
    newNode.autorestart = False
    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.forceField = data["forceField"]
    newNode.flexiblePart = data["flexiblePart"]
    newNode.sequence = data["sequence"]
    newNode.qmSele = data["qmSele"]
    newNode.fDynamoPath = data["fDynamoPath"]
    newNode.charge = data["charge"]
    newNode.method = data["method"]
    newNode.additionalKeywords = {"ts_search": "true"}

    jobGraph.add_node(currentDir, data=newNode)
    # newNode.compileInput()

    return buildTSsearchGraphDynamo(jobGraph, currentDir)
Beispiel #2
0
def addTSsearch(jobGraph, rootDir, currentDir, baseData, initialGeom, index,
                method, basis, gaussianFelxSele):
    newNode = FDynamoNode("tsSearch.f90", currentDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = {"ts_search": "true"}
    newNode.coordsIn = "coordsIn.crd"

    gaussianTime = "72:00:00"

    if not isdir(currentDir):
        makedirs(currentDir)
    saveCrdFromDCD(join(currentDir, "coordsIn.crd"), initialGeom)

    newNode.coordsOut = "coordsDone.crd"
    newNode.getCoordsFromParent = False

    newNode.fDynamoPath = baseData["fDynamoPath"]
    newNode.charge = baseData["charge"]
    newNode.method = baseData["method"]
    newNode.forceField = data["forceField"]
    copyfile(join(baseData["filesDir"], baseData["forceField"]),
             join(currentDir, newNode.forceField))
    newNode.flexiblePart = data["flexiblePart"]
    copyfile(join(baseData["filesDir"], baseData["flexiblePart"]),
             join(currentDir, newNode.flexiblePart))
    newNode.sequence = data["sequence"]
    copyfile(join(baseData["filesDir"], baseData["sequence"]),
             join(currentDir, newNode.sequence))
    newNode.qmSele = data["qmSele"]

    jobGraph.add_node(currentDir, data=newNode)
    jobGraph.add_edge(rootDir, currentDir)

    am1Dir = currentDir

    ########################################################
    currentDir = join(currentDir, "ts_gaussian")
    if not isdir(currentDir):
        makedirs(currentDir)

    newNode = FDynamoNode("tsSearch", currentDir)

    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.templateKey = "QMMM_opt_gaussian"
    newNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
    newNode.additionalKeywords = {
        "ts_search": "true",
        "method": method,
        "basis": basis,
        "multiplicity": 1,
        "otherOptions": ""
    }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    newNode.flexiblePart = basename(gaussianFelxSele)
    copyfile(gaussianFelxSele, join(currentDir, newNode.flexiblePart))
    newNode.processors = 24
    newNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"
    newNode.partition = "plgrid"
    newNode.time = gaussianTime

    jobGraph.add_node(currentDir, data=newNode)
    jobGraph.add_edge(am1Dir, currentDir)

    ########################################################

    newDir = join(am1Dir, "irc_reverse")
    newNode = FDynamoNode("irc_reverse.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = {"IRC_dir": "-1"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    jobGraph.add_node(newDir, data=newNode)
    jobGraph.add_edge(am1Dir, newDir)

    ########################################################
    optDir = join(newDir, "opt")

    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = {
        "ts_search": "false",
        "definedAtoms": baseData["definedAtoms"]
    }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone" + str(index) + ".crd"
    newNode.measureRCinOutput = True

    jobGraph.add_node(optDir, data=newNode)
    jobGraph.add_edge(newDir, optDir)

    ########################################################

    optDirGaussian = join(newDir, "optGaussian")

    if not isdir(optDirGaussian):
        makedirs(optDirGaussian)

    newNode = FDynamoNode("opt.f90", optDirGaussian)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_gaussian"
    newNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
    newNode.additionalKeywords = {
        "ts_search": "false",
        "definedAtoms": baseData["definedAtoms"],
        "method": method,
        "basis": basis,
        "multiplicity": 1,
        "otherOptions": ""
    }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone" + str(index) + ".crd"
    newNode.flexiblePart = basename(gaussianFelxSele)
    copyfile(gaussianFelxSele, join(optDirGaussian, newNode.flexiblePart))
    newNode.measureRCinOutput = True
    newNode.processors = 24
    newNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"
    newNode.partition = "plgrid"
    newNode.time = gaussianTime

    jobGraph.add_node(optDirGaussian, data=newNode)
    jobGraph.add_edge(optDir, optDirGaussian)

    ########################################################

    newDir = join(am1Dir, "irc_forward")
    newNode = FDynamoNode("irc_forward.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = {"IRC_dir": "1"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    jobGraph.add_node(newDir, data=newNode)
    jobGraph.add_edge(am1Dir, newDir)

    ########################################################

    optDir = join(newDir, "opt")

    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = {
        "ts_search": "false",
        "definedAtoms": baseData["definedAtoms"]
    }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone" + str(index) + ".crd"
    newNode.measureRCinOutput = True

    jobGraph.add_node(optDir, data=newNode)
    jobGraph.add_edge(newDir, optDir)

    ########################################################

    optDirGaussian = join(optDir, "optGaussian")

    if not isdir(optDirGaussian):
        makedirs(optDirGaussian)

    newNode = FDynamoNode("opt.f90", optDirGaussian)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_gaussian"
    newNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
    newNode.additionalKeywords = {
        "ts_search": "false",
        "definedAtoms": baseData["definedAtoms"],
        "method": method,
        "basis": basis,
        "multiplicity": 1,
        "otherOptions": ""
    }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone" + str(index) + ".crd"
    newNode.measureRCinOutput = True
    newNode.processors = 24
    newNode.flexiblePart = basename(gaussianFelxSele)
    copyfile(gaussianFelxSele, join(optDirGaussian, newNode.flexiblePart))
    newNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"
    newNode.partition = "plgrid"
    newNode.time = gaussianTime

    jobGraph.add_node(optDirGaussian, data=newNode)
    jobGraph.add_edge(optDir, optDirGaussian)
Beispiel #3
0
def generateTSsearchDynamoPMF(compFile):
    jobGraph = nx.DiGraph()
    currentDir = getcwd()
    rootDir = currentDir
    data = parseFDynamoCompileScript(compFile)

    scanLen = "73"

    ########## INITIAL SCAN ###########################
    definedAtoms = data["definedAtoms"]
    constraints = data["constraints"]
    newNode = FDynamoNode(data["inputFile"], currentDir)
    newNode.coordsIn = data["coordsIn"]
    newNode.coordsOut = "seed.+"+scanLen
    newNode.verification = [ "SP" ]
    newNode.slurmFile = None
    newNode.autorestart = False
    newNode.readInitialScanCoord = True
#    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.forceField = data["forceField"]
    newNode.flexiblePart = data["flexiblePart"]
    newNode.sequence = data["sequence"]
    newNode.qmSele = data["qmSele"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.fDynamoPath = data["fDynamoPath"]
    newNode.charge = data["charge"]
    newNode.method = data["method"]
    newNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" , "gradientTolerance" : "1.0",
         "iterNo" : scanLen, "definedAtoms" : definedAtoms, "constraints" : constraints }
    
    jobGraph.add_node( currentDir , data = newNode )
    newNode.generateInput()
        # newNode.compileInput()
    
    iterNo = 7
    forwardScan = currentDir

    for i in range(iterNo):
        #opt i

        iOptDir = join(rootDir, "optI_"+str(i))

        newNode = FDynamoNode("optStep.f90", iOptDir)
        newNode.verification = ["Opt"]
        newNode.partition = "plgrid-short"
        newNode.time = "1:00:00"
        newNode.templateKey = "QMMM_opt_mopac_no_hess"
        newNode.coordsIn = "coordsIn.crd"
        newNode.coordsOut = "coordsOut.crd"
        newNode.additionalKeywords = { "gradientTolerance" : "0.1"}
        
        jobGraph.add_node(iOptDir, data = newNode)
        jobGraph.add_edge( forwardScan, iOptDir)


        #scan back

        reverseScan = join(rootDir, "reverseScan_"+str(i))
        
        newNode = FDynamoNode("scan.f90", reverseScan)
        newNode.verification = ["SP"]
        newNode.templateKey = "QMMM_scan1D_mopac"
        newNode.readInitialScanCoord = True
        newNode.additionalKeywords = { "scanDir" : "-", "coordScanStart" : "" , "gradientTolerance" : "1.0",
             "iterNo" : scanLen, "definedAtoms" : definedAtoms,  "constraints" : constraints}
        newNode.coordsIn = "coordsStart.crd"
        newNode.coordsOut = "seed.-"+scanLen
        
        jobGraph.add_node(reverseScan, data = newNode)
        jobGraph.add_edge( iOptDir, reverseScan)

        #opt s

        sOptDir = join(rootDir, "optS_"+str(i))

        newNode = FDynamoNode("optStep.f90", sOptDir)
        newNode.verification = ["Opt"]
        newNode.partition = "plgrid-short"
        newNode.time = "1:00:00"
        newNode.templateKey = "QMMM_opt_mopac_no_hess"
        newNode.coordsIn = "coordsIn.crd"
        newNode.coordsOut = "coordsOut.crd"
        newNode.additionalKeywords = { "gradientTolerance" : "0.1"}
        
        jobGraph.add_node(sOptDir, data = newNode)
        jobGraph.add_edge( reverseScan, sOptDir)

        if i == iterNo -1:
            break
        #scan to I

        forwardScan = join(rootDir, "forwardScan_"+str(i))
        
        newNode = FDynamoNode("scan.f90", forwardScan)
        newNode.verification = ["SP"]
        newNode.templateKey = "QMMM_scan1D_mopac"
        newNode.readInitialScanCoord = True
        newNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" , "gradientTolerance" : "1.0",
             "iterNo" : scanLen, "definedAtoms" : definedAtoms,  "constraints" : constraints}
        newNode.coordsIn = "coordsStart.crd"
        newNode.coordsOut = "seed.+"+scanLen
        
        jobGraph.add_node(forwardScan, data = newNode)
        jobGraph.add_edge( sOptDir, forwardScan)

    
    
    return jobGraph
Beispiel #4
0
def generateGraph(topologyFile, forcefield, compileScript, coordinates):
    jobGraph = nx.DiGraph()
    rootDir = getcwd()
    
    notSolventNo = getNumberOfNotSolventRes(topologyFile)

    data = parseFDynamoCompileScript(compileScript)

    newNode = JobNode(None, rootDir)
    newNode.status = "finished"
    jobGraph.add_node(rootDir, data = newNode)

    for crd in coordinates:
        coolDirName = join( rootDir, basename(crd).replace(".", "_") )
        makedirs(coolDirName)

        copyfile( join( rootDir, basename(topologyFile) ), join(coolDirName, basename(topologyFile)) )
        move( join( rootDir, basename(crd) ), join(coolDirName, basename(crd)) )

        coolNode = AmberNode("amber.slurm", coolDirName, coolDirName, basename(topologyFile), basename(crd))
        coolNode.runType = "standardCooling"
        coolNode.time = "1:00:00"
        coolNode.partition = "plgrid-short"
        coolNode.processors = 8
        jobGraph.add_node( coolDirName, data = coolNode )
        jobGraph.add_edge(rootDir, coolDirName)

        optimDir = join( coolDirName, "MM_opt")
        optimNode = AmberNode("amber.slurm", optimDir, optimDir, topologyFile)
        optimNode.NoSolventResidues = notSolventNo
        optimNode.runType = "standardOptimization"
        optimNode.time = "1:00:00"
        optimNode.partition = "plgrid-short"
        jobGraph.add_node( optimDir, data = optimNode )
        jobGraph.add_edge( coolDirName, optimDir)

        qmmmSetupDirName = join( coolDirName, "QMMM_setup")
        qmmmSetupNode = QMMMsetupNode("qmmmSetup.slurm", qmmmSetupDirName, basename(topologyFile), "cooled.nc")
        jobGraph.add_node( qmmmSetupDirName, data = qmmmSetupNode )
        jobGraph.add_edge( optimDir, qmmmSetupDirName)

        qmmmOptDir = join(qmmmSetupDirName, "opt")
        makedirs(qmmmOptDir)
        copyfile( join( rootDir, basename(forcefield) ), join(qmmmOptDir, basename(forcefield)) )

        definedAtoms = data["definedAtoms"]
        constraints = data["constraints"]
        qmmmOptNode = FDynamoNode(data["inputFile"], qmmmOptDir)
        qmmmOptNode.coordsIn = "coordsIn.crd"
        qmmmOptNode.coordsOut = "coordsOut.crd"
        qmmmOptNode.verification = [ "Opt" ]
        qmmmOptNode.slurmFile = None
        qmmmOptNode.autorestart = False
        qmmmOptNode.forceField = data["forceField"]
        qmmmOptNode.flexiblePart = data["flexiblePart"]
        qmmmOptNode.sequence = data["sequence"]
        qmmmOptNode.qmSele = data["qmSele"]
        qmmmOptNode.templateKey = "QMMM_opt_mopac_no_hess"
        qmmmOptNode.fDynamoPath = data["fDynamoPath"]
        qmmmOptNode.charge = data["charge"]
        qmmmOptNode.method = data["method"]

        jobGraph.add_node( qmmmOptDir, data = qmmmOptNode )
        jobGraph.add_edge( qmmmSetupDirName, qmmmOptDir)

        qmmmScanDir = join(qmmmSetupDirName, "scan")
        qmmmScanNode = FDynamoNode("scan.f90", qmmmScanDir)
        qmmmScanNode.verification = [ "scan1D" ]
        qmmmScanNode.readInitialScanCoord = True
        qmmmScanNode.templateKey = "QMMM_scan1D_mopac"
        qmmmScanNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" ,
        	"iterNo" : "80", "definedAtoms" : definedAtoms, "constraints" : constraints }

        jobGraph.add_node( qmmmScanDir, data = qmmmScanNode )
        jobGraph.add_edge( qmmmOptDir, qmmmScanDir)

        qmmmTSoptDir = join(qmmmSetupDirName, "ts_search")
        qmmmTSoptNode = FDynamoNode("tsSearch.f90", qmmmTSoptDir)
        qmmmTSoptNode.verification = ["Opt" , "Freq"]
        qmmmTSoptNode.noOfExcpectedImaginaryFrequetions = 1
        qmmmTSoptNode.templateKey = "QMMM_opt_mopac"
        qmmmTSoptNode.additionalKeywords = { "ts_search" : "true" }
        qmmmTSoptNode.coordsIn = "coordsStart.crd"
        qmmmTSoptNode.coordsOut = "coordsDone.crd"

        jobGraph.add_node( qmmmTSoptDir, data = qmmmTSoptNode )
        jobGraph.add_edge( qmmmScanDir, qmmmTSoptDir)

    return jobGraph
def buildGraph(whamLog, compileScript, method, basis, structures, sourceDir, graphDir, dftTime, minRC, maxRC):
    jobGraph = nx.DiGraph()
#    currentDir = getcwd()
    data = parseFDynamoCompileScript(compileScript)
    definedAtoms = data["definedAtoms"]
    gaussianFlexibleSele = rewriteFlexibleSeleFile(  join(sourceDir, data["flexiblePart"]) )

    ########## ROOT NODE ###########################
    rootNode = FDynamoNode(None, graphDir)
    rootNode.status = "finished"

    if not isdir(graphDir):
        makedirs(graphDir)
    
    rootNode.fDynamoPath = data["fDynamoPath"]
    rootNode.charge = data["charge"]
    rootNode.method = data["method"]
    rootNode.forceField = data["forceField"]
    copyfile( join(sourceDir, data["forceField"]), join(graphDir, rootNode.forceField) )
    rootNode.flexiblePart = data["flexiblePart"]
    copyfile( join(sourceDir, data["flexiblePart"]), join(graphDir, rootNode.flexiblePart) )
    rootNode.sequence = data["sequence"]
    copyfile( join(sourceDir, data["sequence"]), join(graphDir, rootNode.sequence) )
    rootNode.qmSele = data["qmSele"]

    rootNode.additionalKeywords["definedAtoms"] = definedAtoms
    
    jobGraph.add_node(graphDir, data = rootNode)
    
    ########### SPLINE NODE ####################
    splineDir = join( graphDir, "spline" )
    splineNode = SplineNode(None, splineDir, whamLog )
    jobGraph.add_node( splineDir, data= splineNode )
    
    
    ################## SP DFT + SP SEMIEMPIRICAL #####################################
    RCstructList = []
    for struct in structures:
        
        RC = rootNode.measureRC(struct)
        print(struct, RC)
        if RC < minRC or RC > maxRC:
            continue

        RCstructList.append( (RC, struct) )

    RCstructList.sort()

    for i, rcStruct in enumerate(RCstructList):
        struct = rcStruct[1]

        dirNo = str(i)
        dirname = join( graphDir,  dirNo )
        
        dftDir = join(dirname, method)
        semiEmpDir = join(dirname, data["method"])
        
        if not isdir(dftDir):
            makedirs(dftDir)

        if not isdir(semiEmpDir):
            makedirs(semiEmpDir)
        
        dftNode = FDynamoNode("DFT-SP-"+dirNo, dftDir)
        dftNode.verification = ["SP"]
        dftNode.templateKey = "QMMM_sp_gaussian"
        dftNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
        # if structNo >= 35:
            # dftNode.additionalKeywords =  {  "method" : method, "basis" : basis , "multiplicity" : 1 , "definedAtoms" : data["definedAtoms"] , "otherOptions" : "SCF=(QC,direct,conver=6)" }
        # else:
        dftNode.additionalKeywords =  {  "method" : method, "basis" : basis , "multiplicity" : 1 , "definedAtoms" : data["definedAtoms"] , "otherOptions" : "SCF=(direct)" }
        # dftNode.additionalKeywords =  {  "method" : method, "basis" : basis , "multiplicity" : 1 , "definedAtoms" : data["definedAtoms"] , "otherOptions" : "SCF=direct" }

        dftNode.coordsIn = "coordsStart.crd"
        copyfile(struct, join( dftNode.path, dftNode.coordsIn ))
        dftNode.coordsOut = "coordsDone.crd"
        dftNode.flexiblePart = basename(gaussianFlexibleSele)
        copyfile( gaussianFlexibleSele, join(dftDir, dftNode.flexiblePart) )
        dftNode.processors = 24
        dftNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"
        dftNode.partition = "plgrid"
        dftNode.time = dftTime
        dftNode.getCoordsFromParent = False
        jobGraph.add_node(dftDir, data = dftNode)
        jobGraph.add_edge(graphDir, dftDir)
        
        semiNode = FDynamoNode("SemiEmp-SP-"+dirNo, semiEmpDir)
        semiNode.verification = ["SP"]
        semiNode.templateKey = "QMMM_sp"
        semiNode.coordsIn = "coordsStart.crd"
        semiNode.coordsOut = "coordsDone.crd"
        copyfile(struct, join( semiNode.path, semiNode.coordsIn ))
        semiNode.partition = "plgrid-short"
        semiNode.time = "0:10:00"
        semiNode.getCoordsFromParent = False
        jobGraph.add_node(semiEmpDir, data = semiNode)
        jobGraph.add_edge( graphDir, semiEmpDir )
        
        splineDiff = SplineDiffNode("diff", dirname)
        jobGraph.add_node(dirname, data = splineDiff)
        
        jobGraph.add_edge( dftDir, dirname )
        jobGraph.add_edge( semiEmpDir, dirname )

        jobGraph.add_edge( dirname, splineDir )
    
    return jobGraph
def generateTSsearchDynamoPMF(compFile):
    jobGraph = nx.DiGraph()
    currentDir = getcwd()
    rootDir = currentDir
    data = parseFDynamoCompileScript(compFile)

    ########## INITIAL SCAN ###########################
    definedAtoms = data["definedAtoms"]
    constraints = data["constraints"]
    newNode = FDynamoNode(data["inputFile"], currentDir)
    newNode.coordsIn = data["coordsIn"]
    newNode.verification = [ "scan1D" ]
    newNode.slurmFile = None
    newNode.autorestart = False
    newNode.readInitialScanCoord = True
#    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.forceField = data["forceField"]
    newNode.flexiblePart = data["flexiblePart"]
    newNode.sequence = data["sequence"]
    newNode.qmSele = data["qmSele"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.fDynamoPath = data["fDynamoPath"]
    newNode.charge = data["charge"]
    newNode.method = data["method"]
    newNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" , "gradientTolerance" : "1.0",
         "iterNo" : "80", "definedAtoms" : definedAtoms, "constraints" : constraints }
    
    jobGraph.add_node( currentDir , data = newNode )
    newNode.generateInput()
        # newNode.compileInput()
    
    ################## TS SEARCH #####################################
    startDir, currentDir = currentDir, join(currentDir, "ts_search")
    newNode = FDynamoNode("tsSearch.f90", currentDir)
    newNode.verification = ["Opt" , "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = { "ts_search" : "true" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    
    jobGraph.add_node(currentDir, data = newNode)
    jobGraph.add_edge(startDir, currentDir)
    
    tsFoundDir = currentDir

    stepOptDir = join(currentDir, "tsTightOpt")

    newNode = FDynamoNode("optStep.f90", stepOptDir)
    newNode.verification = ["Opt"]
    newNode.partition = "plgrid-short"
    newNode.time = "1:00:00"
    newNode.templateKey = "QMMM_opt_mopac_no_hess_restr"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = {  "coordScanStart" : "" , "definedAtoms" : definedAtoms,  "constraints" : constraints, "gradientTolerance" : "0.1"}

    jobGraph.add_node(stepOptDir, data = newNode)
    jobGraph.add_edge( tsFoundDir, stepOptDir)

    
    newDir = join(currentDir, "irc_reverse")
    newNode = FDynamoNode("irc_reverse.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = { "IRC_dir" : "-1" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    
    jobGraph.add_node(newDir, data = newNode)
    jobGraph.add_edge(currentDir, newDir)
    
    optDir = join(newDir, "opt")
    
    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = { "ts_search" : "false" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    
    jobGraph.add_node(optDir, data = newNode)
    jobGraph.add_edge( newDir, optDir)


    
    newDir = join(currentDir, "irc_forward")
    newNode = FDynamoNode("irc_forward.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = { "IRC_dir" : "1" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    
    jobGraph.add_node(newDir, data = newNode)
    jobGraph.add_edge(currentDir, newDir)
    
    optDir = join(newDir, "opt")
    
    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = { "ts_search" : "false" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    
    jobGraph.add_node(optDir, data = newNode)
    jobGraph.add_edge( newDir, optDir)

    
    ####################### SCAN FROM TS #########################

    reverseScan = join(startDir, "TS1reverseScan1")
    
    newNode = FDynamoNode("scan.f90", reverseScan)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = { "scanDir" : "-", "coordScanStart" : "" , "gradientTolerance" : "0.1",
         "iterNo" : str(15), "definedAtoms" : definedAtoms,  "constraints" : constraints}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "seed.-15"
    
    jobGraph.add_node(reverseScan, data = newNode)
    jobGraph.add_edge( stepOptDir, reverseScan)
    
    reverseScan2 = join(startDir, "TS1reverseScan2")
    
    newNode = FDynamoNode("scan.f90", reverseScan2)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = { "scanDir" : "-", "coordScanStart" : "" , "gradientTolerance" : "0.1",
         "iterNo" : str(16), "definedAtoms" : definedAtoms,  "constraints" : constraints}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "seed.-16"
    
    jobGraph.add_node(reverseScan2, data = newNode)
    jobGraph.add_edge( reverseScan, reverseScan2)

    reverseScan3 = join(startDir, "TS1reverseScan3")
    
    newNode = FDynamoNode("scan.f90", reverseScan3)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = { "scanDir" : "-", "coordScanStart" : "" , "gradientTolerance" : "0.1",
         "iterNo" : str(11), "definedAtoms" : definedAtoms,  "constraints" : constraints}
    newNode.coordsIn = "coordsStart.crd"
    
    jobGraph.add_node(reverseScan3, data = newNode)
    jobGraph.add_edge( reverseScan2, reverseScan3)

        
    forwardScan = join(startDir, "TS1forwardScan1")
    
    newNode = FDynamoNode("scan.f90", forwardScan)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" , "gradientTolerance" : "0.1",
         "iterNo" : str(15), "definedAtoms" : definedAtoms,  "constraints" : constraints}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "seed.+15"
    
    jobGraph.add_node(forwardScan, data = newNode)
    jobGraph.add_edge( stepOptDir, forwardScan)
    
    forwardScan2 = join(startDir, "TS1forwardScan2")
    
    newNode = FDynamoNode("scan.f90", forwardScan2)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" , "gradientTolerance" : "0.1",
         "iterNo" : str(16), "definedAtoms" : definedAtoms,  "constraints" : constraints}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "seed.+16"
    
    jobGraph.add_node(forwardScan2, data = newNode)
    jobGraph.add_edge( forwardScan, forwardScan2)

    forwardScan3 = join(startDir, "TS1forwardScan3")
    
    newNode = FDynamoNode("scan.f90", forwardScan3)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = { "scanDir" : "+", "coordScanStart" : "" , "gradientTolerance" : "0.1",
         "iterNo" : str(11), "definedAtoms" : definedAtoms,  "constraints" : constraints}
    newNode.coordsIn = "coordsStart.crd"
    
    jobGraph.add_node(forwardScan3, data = newNode)
    jobGraph.add_edge( forwardScan2, forwardScan3)
    
    
    return jobGraph
def generateTSsearchDynamoPMF(compFile, onlyPrepare, onlyRun, runDFT):
    jobGraph = nx.DiGraph()
    currentDir = getcwd()
    rootDir = currentDir
    data = parseFDynamoCompileScript(compFile)

    ########## INITIAL SCAN ###########################
    definedAtoms = data["definedAtoms"]
    constraints = data["constraints"]
    newNode = FDynamoNode(data["inputFile"], currentDir)
    newNode.coordsIn = data["coordsIn"]
    newNode.verification = ["scan1D"]
    newNode.slurmFile = None
    newNode.autorestart = False
    newNode.readInitialScanCoord = True
    #    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.forceField = data["forceField"]
    newNode.flexiblePart = data["flexiblePart"]
    newNode.sequence = data["sequence"]
    newNode.qmSele = data["qmSele"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.fDynamoPath = data["fDynamoPath"]
    newNode.charge = data["charge"]
    newNode.method = data["method"]
    newNode.additionalKeywords = {
        "scanDir": "+",
        "coordScanStart": "",
        "iterNo": "80",
        "definedAtoms": definedAtoms,
        "constraints": constraints
    }

    if not onlyRun:
        jobGraph.add_node(currentDir, data=newNode)
        newNode.generateInput()
        # newNode.compileInput()

    ################## TS SEARCH #####################################
    startDir, currentDir = currentDir, join(currentDir, "ts_search")
    newNode = FDynamoNode("tsSearch.f90", currentDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = {"ts_search": "true"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    if not onlyRun:
        jobGraph.add_node(currentDir, data=newNode)
        jobGraph.add_edge(startDir, currentDir)

    tsFoundDir = currentDir

    if runDFT:
        gaussianFlexibleSele = rewriteFlexibleSeleFile(
            join(rootDir, data["flexiblePart"]))
        tsGaussianDir = join(tsFoundDir, "b3lyp")

        if not isdir(tsGaussianDir):
            makedirs(tsGaussianDir)

        newNode = FDynamoNode("tsSearch", tsGaussianDir)
        newNode.verification = ["Opt", "Freq"]
        newNode.noOfExcpectedImaginaryFrequetions = 1
        newNode.templateKey = "QMMM_opt_gaussian"
        newNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
        newNode.additionalKeywords = {
            "ts_search": "true",
            "method": "B3LYP",
            "basis": "6-31G(d,p)",
            "multiplicity": 1,
            "otherOptions": ""
        }
        newNode.coordsIn = "coordsStart.crd"
        newNode.coordsOut = "coordsDone.crd"
        newNode.flexiblePart = basename(gaussianFlexibleSele)
        newNode.partition = "plgrid-gpu\n#SBATCH --gres=gpu:1\n#SBATCH -A plgksdhphdgpu"
        copyfile(gaussianFlexibleSele, join(tsGaussianDir,
                                            newNode.flexiblePart))
        newNode.processors = 24
        newNode.time = "30:00:00"
        newNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"

        jobGraph.add_node(tsGaussianDir, data=newNode)
        jobGraph.add_edge(tsFoundDir, tsGaussianDir)

        spDir = join(tsGaussianDir, "SP")
        dftNode = FDynamoNode("DFT-SP-", spDir)
        dftNode.verification = ["SP"]
        dftNode.templateKey = "QMMM_sp_gaussian"
        dftNode.additionalKeywords = {
            "method": "B3LYP",
            "basis": "6-311++G(2d,2p)",
            "multiplicity": 1,
            "otherOptions": ""
        }
        dftNode.coordsIn = "coordsStart.crd"
        dftNode.coordsOut = "coordsDone.crd"
        dftNode.flexiblePart = basename(gaussianFlexibleSele)
        dftNode.processors = 24
        dftNode.time = "30:00:00"
        dftNode.partition = "plgrid-gpu\n#SBATCH --gres=gpu:1\n#SBATCH -A plgksdhphdgpu"
        dftNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"

        jobGraph.add_node(spDir, data=dftNode)
        jobGraph.add_edge(tsGaussianDir, spDir)

    newDir = join(currentDir, "irc_reverse")
    newNode = FDynamoNode("irc_reverse.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = {"IRC_dir": "-1"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    if not onlyRun:
        jobGraph.add_node(newDir, data=newNode)
        jobGraph.add_edge(currentDir, newDir)

    optDir = join(newDir, "opt")

    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = {"ts_search": "false"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    if not onlyRun:
        jobGraph.add_node(optDir, data=newNode)
        jobGraph.add_edge(newDir, optDir)

    if runDFT:
        tsGaussianDir = join(optDir, "b3lyp")

        if not isdir(tsGaussianDir):
            makedirs(tsGaussianDir)

        newNode = FDynamoNode("opt", tsGaussianDir)
        newNode.verification = ["Opt", "Freq"]
        newNode.noOfExcpectedImaginaryFrequetions = 0
        newNode.templateKey = "QMMM_opt_gaussian"
        newNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
        newNode.additionalKeywords = {
            "ts_search": "false",
            "method": "B3LYP",
            "basis": "6-31G(d,p)",
            "multiplicity": 1,
            "otherOptions": ""
        }
        newNode.coordsIn = "coordsStart.crd"
        newNode.coordsOut = "coordsDone.crd"
        newNode.flexiblePart = basename(gaussianFlexibleSele)
        copyfile(gaussianFlexibleSele, join(tsGaussianDir,
                                            newNode.flexiblePart))
        newNode.processors = 24
        newNode.time = "30:00:00"
        newNode.partition = "plgrid-gpu\n#SBATCH --gres=gpu:1\n#SBATCH -A plgksdhphdgpu"
        newNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"

        jobGraph.add_node(tsGaussianDir, data=newNode)
        jobGraph.add_edge(optDir, tsGaussianDir)

        spDir = join(tsGaussianDir, "SP")
        dftNode = FDynamoNode("DFT-SP-", spDir)
        dftNode.verification = ["SP"]
        dftNode.templateKey = "QMMM_sp_gaussian"
        dftNode.additionalKeywords = {
            "method": "B3LYP",
            "basis": "6-311++G(2d,2p)",
            "multiplicity": 1,
            "otherOptions": ""
        }
        dftNode.coordsIn = "coordsStart.crd"
        dftNode.coordsOut = "coordsDone.crd"
        dftNode.flexiblePart = basename(gaussianFlexibleSele)
        dftNode.processors = 24
        dftNode.time = "30:00:00"
        dftNode.partition = "plgrid-gpu\n#SBATCH --gres=gpu:1\n#SBATCH -A plgksdhphdgpu"
        dftNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"

        jobGraph.add_node(spDir, data=dftNode)
        jobGraph.add_edge(tsGaussianDir, spDir)

    newDir = join(currentDir, "irc_forward")
    newNode = FDynamoNode("irc_forward.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = {"IRC_dir": "1"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    if not onlyRun:
        jobGraph.add_node(newDir, data=newNode)
        jobGraph.add_edge(currentDir, newDir)

    optDir = join(newDir, "opt")

    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = {"ts_search": "false"}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"

    if not onlyRun:
        jobGraph.add_node(optDir, data=newNode)
        jobGraph.add_edge(newDir, optDir)

    if runDFT:
        tsGaussianDir = join(optDir, "b3lyp")

        if not isdir(tsGaussianDir):
            makedirs(tsGaussianDir)

        newNode = FDynamoNode("opt", tsGaussianDir)
        newNode.verification = ["Opt", "Freq"]
        newNode.noOfExcpectedImaginaryFrequetions = 0
        newNode.templateKey = "QMMM_opt_gaussian"
        newNode.fDynamoPath = "/net/people/plgglanow/fortranPackages/AMBER-g09/AMBER-dynamo/makefile"
        newNode.additionalKeywords = {
            "ts_search": "false",
            "method": "B3LYP",
            "basis": "6-31G(d,p)",
            "multiplicity": 1,
            "otherOptions": ""
        }
        newNode.coordsIn = "coordsStart.crd"
        newNode.coordsOut = "coordsDone.crd"
        newNode.flexiblePart = basename(gaussianFlexibleSele)
        copyfile(gaussianFlexibleSele, join(tsGaussianDir,
                                            newNode.flexiblePart))
        newNode.processors = 24
        newNode.time = "30:00:00"
        newNode.partition = "plgrid-gpu\n#SBATCH --gres=gpu:1\n#SBATCH -A plgksdhphdgpu"
        newNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"

        jobGraph.add_node(tsGaussianDir, data=newNode)
        jobGraph.add_edge(optDir, tsGaussianDir)

        spDir = join(tsGaussianDir, "SP")
        dftNode = FDynamoNode("DFT-SP-", spDir)
        dftNode.verification = ["SP"]
        dftNode.templateKey = "QMMM_sp_gaussian"
        dftNode.additionalKeywords = {
            "method": "B3LYP",
            "basis": "6-311++G(2d,2p)",
            "multiplicity": 1,
            "otherOptions": ""
        }
        dftNode.coordsIn = "coordsStart.crd"
        dftNode.coordsOut = "coordsDone.crd"
        dftNode.flexiblePart = basename(gaussianFlexibleSele)
        dftNode.processors = 24
        dftNode.time = "30:00:00"
        dftNode.partition = "plgrid-gpu\n#SBATCH --gres=gpu:1\n#SBATCH -A plgksdhphdgpu"
        dftNode.moduleAddLines = "module add plgrid/apps/gaussian/g16.B.01"

        jobGraph.add_node(spDir, data=dftNode)
        jobGraph.add_edge(tsGaussianDir, spDir)

    ####################### SCAN FROM TS #########################

    scanSteps = 40

    reverseScan = join(startDir, "TS1reverseScan")

    newNode = FDynamoNode("scan.f90", reverseScan)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = {
        "scanDir": "-",
        "coordScanStart": "",
        "iterNo": str(scanSteps),
        "definedAtoms": definedAtoms,
        "constraints": constraints
    }
    newNode.coordsIn = "coordsStart.crd"

    jobGraph.add_node(reverseScan, data=newNode)
    if onlyRun:
        newNode.forceField = data["forceField"]
        newNode.flexiblePart = data["flexiblePart"]
        newNode.sequence = data["sequence"]
        newNode.qmSele = data["qmSele"]
        newNode.templateKey = "QMMM_scan1D_mopac"
        newNode.fDynamoPath = data["fDynamoPath"]
        newNode.charge = data["charge"]
        newNode.method = data["method"]

        newNode.status = "examined"
    else:
        jobGraph.add_edge(tsFoundDir, reverseScan)

    if not onlyPrepare:
        pmfDir = join(startDir, "PMF")
        for i in range(scanSteps + 1):
            stepDir = join(pmfDir, "pmfRev" + str(i))

            newNode = FDynamoNode("pmfStep.f90", stepDir)
            newNode.verification = ["SP"]
            newNode.partition = "plgrid"
            newNode.time = "72:00:00"
            newNode.templateKey = "QMMM_pmf"
            newNode.readInitialScanCoord = True
            newNode.additionalKeywords = {
                "coordScanStart": "",
                "definedAtoms": definedAtoms,
                "constraints": constraints
            }
            newNode.coordsIn = "seed.-" + str(i)
            newNode.anotherCoordsSource = "seed.-" + str(i)

            jobGraph.add_node(stepDir, data=newNode)
            jobGraph.add_edge(reverseScan, stepDir)

    forwardScan = join(startDir, "TS1forwardScan")

    newNode = FDynamoNode("scan.f90", forwardScan)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_scan1D_mopac"
    newNode.readInitialScanCoord = True
    newNode.additionalKeywords = {
        "scanDir": "+",
        "coordScanStart": "",
        "iterNo": str(scanSteps),
        "definedAtoms": definedAtoms,
        "constraints": constraints
    }
    newNode.coordsIn = "coordsStart.crd"

    jobGraph.add_node(forwardScan, data=newNode)

    if onlyRun:
        newNode.forceField = data["forceField"]
        newNode.flexiblePart = data["flexiblePart"]
        newNode.sequence = data["sequence"]
        newNode.qmSele = data["qmSele"]
        newNode.templateKey = "QMMM_scan1D_mopac"
        newNode.fDynamoPath = data["fDynamoPath"]
        newNode.charge = data["charge"]
        newNode.method = data["method"]

        newNode.status = "examined"
    else:
        jobGraph.add_edge(tsFoundDir, forwardScan)

    if not onlyPrepare:
        for i in range(1, scanSteps + 1):
            stepDir = join(pmfDir, "pmfForw" + str(i))

            newNode = FDynamoNode("pmfStep.f90", stepDir)
            newNode.verification = ["SP"]
            newNode.partition = "plgrid"
            newNode.time = "72:00:00"
            newNode.templateKey = "QMMM_pmf"
            newNode.readInitialScanCoord = True
            newNode.anotherCoordsSource = "seed.+" + str(i)
            newNode.additionalKeywords = {
                "coordScanStart": "",
                "definedAtoms": definedAtoms,
                "constraints": constraints
            }
            newNode.coordsIn = "seed.+" + str(i)

            jobGraph.add_node(stepDir, data=newNode)
            jobGraph.add_edge(forwardScan, stepDir)

    return jobGraph
def addTSsearch (jobGraph, rootDir, currentDir, baseData, initialGeom, index):
    newNode = FDynamoNode("tsSearch.f90", currentDir)
    newNode.verification = ["Opt" , "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 1
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = { "ts_search" : "true" }
    newNode.coordsIn = "coordsIn.crd"
    
    makedirs(currentDir)
    saveCrdFromDCD( join(currentDir, "coordsIn.crd"), initialGeom )
    
    newNode.coordsOut = "coordsDone.crd"
    newNode.getCoordsFromParent = False
    
    newNode.fDynamoPath = baseData["fDynamoPath"]
    newNode.charge = baseData["charge"]
    newNode.method = baseData["method"]
    newNode.forceField = data["forceField"]
    copyfile( join(baseData["filesDir"], baseData["forceField"]), join(currentDir, newNode.forceField) )
    newNode.flexiblePart = data["flexiblePart"]
    copyfile( join(baseData["filesDir"], baseData["flexiblePart"]), join(currentDir, newNode.flexiblePart) )
    newNode.sequence = data["sequence"]
    copyfile( join(baseData["filesDir"], baseData["sequence"]), join(currentDir, newNode.sequence) )
    newNode.qmSele = data["qmSele"]
    
    jobGraph.add_node(currentDir, data = newNode)
    jobGraph.add_edge(rootDir, currentDir)
    
    newDir = join(currentDir, "irc_reverse")
    newNode = FDynamoNode("irc_reverse.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = { "IRC_dir" : "-1" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    

    jobGraph.add_node(newDir, data = newNode)
    jobGraph.add_edge(currentDir, newDir)
    
    optDir = join(newDir, "opt")
    
    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = { "ts_search" : "false" , "definedAtoms" : baseData["definedAtoms"]}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone"+str(index)+".crd"
    newNode.measureRCinOutput = True
    

    jobGraph.add_node(optDir, data = newNode)
    jobGraph.add_edge( newDir, optDir)
    
    newDir = join(currentDir, "irc_forward")
    newNode = FDynamoNode("irc_forward.f90", newDir)
    newNode.verification = ["SP"]
    newNode.templateKey = "QMMM_irc_mopac"
    newNode.additionalKeywords = { "IRC_dir" : "1" }
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone.crd"
    
    jobGraph.add_node(newDir, data = newNode)
    jobGraph.add_edge(currentDir, newDir)
    
    optDir = join(newDir, "opt")
    
    newNode = FDynamoNode("opt.f90", optDir)
    newNode.verification = ["Opt", "Freq"]
    newNode.noOfExcpectedImaginaryFrequetions = 0
    newNode.templateKey = "QMMM_opt_mopac"
    newNode.additionalKeywords = { "ts_search" : "false" , "definedAtoms" : baseData["definedAtoms"]}
    newNode.coordsIn = "coordsStart.crd"
    newNode.coordsOut = "coordsDone"+str(index)+".crd"
    newNode.measureRCinOutput = True
    
    jobGraph.add_node(optDir, data = newNode)
    jobGraph.add_edge( newDir, optDir)
    

    if len(sys.argv) < 4:
        print("Usage: graphTSsearchWHAM wham.log/RC compileScanScript.sh numberOfTS2find addName")
    else:
        whamLog = sys.argv[1]
        compileScript = sys.argv[2]
        TSno = int(sys.argv[3])
        
        addName = ""
        if len(sys.argv) > 4:
            addName = sys.argv[4]

        if isfile(whamLog):
            tsReactionCoord = getTScoords(whamLog)
        else:
            tsReactionCoord = float(whamLog)
        print("Found reaction coordinate: ", tsReactionCoord)
        data = parseFDynamoCompileScript(compileScript)
        definedAtoms = data["definedAtoms"]
        atoms = atomsFromAtomSelection( definedAtoms)

        currentDir = abspath(dirname(compileScript))

        graphDir = join( getcwd(), "multiTSsearch"+addName )

        sm = GraphManager()
        graph = sm.isGraphHere(graphDir)
        if not graph:
            newGraph = jobGraph = buildGraph(tsReactionCoord, atoms, graphDir, data, currentDir, TSno)
    
            
            result = sm.addGraph(newGraph, graphDir)
            if result:
                sm.buildGraphDirectories(newGraph)
                sm.saveGraphs()
            print("Created new graph")
        else:
            print("Cannot create more than one graph in the same directory")