Ejemplo n.º 1
0
def add_ions(neutral=True, conc=0, pname='NA', nname='CL'):
    if (not neutral) and (conc == 0):
        utils.update("add_ions", "no ions will be added...")
        return

    if neutral:
        utils.update("add_ions", "will add ions ({}/{}) to neutralize the system...".format(pname, nname))

    if conc > 0:
        utils.update("add_ions", "will add ions ({}/{}) for target concentration = {} mmol/ml...".format(pname, nname, conc))

    # Generate IONS.mdp (just a dummy required).
    os.system('touch IONS.mdp')

    # Add ion topology to topol.top.
    topol.add_mol("{0}.ff/ions.itp".format(universe.get('d_modelFF')), "Include ion topology")

    # Run gmx grompp and genion.
    utils.update("add_ions", "running gmx grompp and genion to add ions...")

    os.system("gmx grompp -f IONS.mdp -c {0} -p topol.top -o IONS.tpr >> builder.log 2>&1".format(universe.get('d_nameList')[-1]))

    if neutral:
        os.system("gmx genion -s IONS.tpr -o {0}_ION.pdb -p topol.top -pname {1} -nname {2} -conc {3} -neutral >> builder.log 2>&1 << EOF\nSOL\nEOF".format(universe.get('d_pdbName'), pname, nname, conc))
    else:
        os.system("gmx genion -s IONS.tpr -o {0}_ION.pdb -p topol.top -pname {1} -nname {2} -conc {3} >> builder.log 2>&1 << EOF\nSOL\nEOF".format(universe.get('d_pdbName'), pname, nname, conc))

    # To update d_residues.
    load("{0}_ION.pdb".format(universe.get('d_pdbName')))

    # To update d_nameList.
    utils.add_to_nameList("{0}_ION.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 2
0
def run(gmxPath="/usr/local/gromacs", options=""):
    # If we do a non-constant-pH simulation, gen_constantph will not make index.ndx,
    # so do it here.
    if not os.path.isfile('index.ndx'):
        utils.generate_index()

    # User update:
    if options == "":
        utils.update("run", "gmxPath={0}".format(gmxPath))
    else:
        utils.update(
            "run",
            "gmxPath={0}, additional options= {1}".format(gmxPath, options))

    with open("run.sh", 'w') as file:
        file.write("#!/bin/bash\n\n")

        file.write("# Gromacs version to use:\n")
        file.write("source {0}/bin/GMXRC\n\n".format(gmxPath))

        file.write(
            "gmx grompp -f MD.mdp -c {0} -p topol.top -n index.ndx -o MD.tpr -r {0}\n"
            .format(universe.get('d_nameList')[-1]))
        file.write(
            "gmx mdrun -deffnm MD -v -c {0}_MD.pdb -x MD.xtc {1}\n".format(
                universe.get('d_pdbName'), options))

    os.system("chmod +x run.sh")
Ejemplo n.º 3
0
def process(fname, d_model=1, d_ALI='A', d_chain=[], resetResId=False):
    basename = os.path.basename(fname)
    universe.add('d_pdbName', basename[0:len(basename) - 4])
    universe.add('d_model', d_model)
    universe.add('d_ALI', d_ALI)

    load(fname, d_model, d_ALI, d_chain)

    # Update d_chain from [] to a list of actual chains used:
    d_chain = []
    for residue in universe.get('d_residues'):
        d_chain.append(residue.d_chain)
    d_chain = list(set(d_chain))
    d_chain.sort()
    universe.add('d_chain', d_chain)

    utils.update(
        "process", 'file={0}, MODEL#={1}, ALI={2}, chain(s)={3}...'.format(
            fname, d_model, d_ALI, d_chain))

    # Write processed.pdb to file:
    utils.update(
        "process", "writing processed .pdb file to {}_PR1.pdb...".format(
            universe.get('d_pdbName')))
    write("{0}_PR1.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 4
0
def write(name):
    with open(name, 'w') as file:
        if universe.has('d_title'):
            file.write("TITLE {0}\n".format(universe.get('d_title')))

        if universe.has('d_box'):
            file.write("CRYST1{0}\n".format(universe.get('d_box')))

        file.write("MODEL {:8d}\n".format(universe.get('d_model')))

        atomNumber = 1
        for residue in universe.get('d_residues'):
            for idx in range(0, len(residue.d_atoms)):
                file.write(
                    "{:6s}{:5d} {:^4s}{:1s}{:4s}{:1s}{:4d}{:1s}   {:8.3f}{:8.3f}{:8.3f}\n"
                    .format('ATOM', atomNumber, residue.d_atoms[idx],
                            residue.d_ali[idx], residue.d_resname,
                            residue.d_chain, residue.d_resid, '',
                            residue.d_x[idx], residue.d_y[idx],
                            residue.d_z[idx]))
                atomNumber += 1

        file.write("TER\nENDMDL\n")

    utils.add_to_nameList(name)
Ejemplo n.º 5
0
def restrain_dihedrals(resName, atomNameList, Type, phi, dphi, fc):
    utils.update("restrain_dihedrals", "will add restraints for {0} (all chains)...".format(resName))

    # Every chain has its own .itp file, so we loop through every file:
    for letter in universe.get('d_chain'):
        # This is to make sure we don't have multiple headers when we add multiple different restraints.
        first = False
        if not "[ dihedral_restraints ]" in open("topol_Protein_chain_{0}.itp".format(letter)).read():
            first = True

        # Append to the end of relevant .itp file:
        with open("topol_Protein_chain_{0}.itp".format(letter), 'a') as file:
            if first:
                file.write("[ dihedral_restraints ]\n")
                file.write("; ai aj ak al type phi dphi fc\n")

            # Atomcount resets for every separate .itp file.
            atomCount = 0
            for residue in universe.get('d_residues'):
                # Dictionary resets for every residue, as we can of course have
                # multiple ASPs or GLUs in one chain.
                dictionary = {}
                for atom in residue.d_atoms:
                    # Only increase atomcount when we read the relevant chain:
                    if residue.d_chain == letter:
                        atomCount += 1

                        if residue.d_resname == resName and atom in atomNameList:
                            dictionary[atom] = atomCount

                if len(dictionary) == 4:
                    utils.update("restrain_dihedrals", "adding restraints for chain {0} {1}-{2}...".format(residue.d_chain, resName, residue.d_resid))
                    for atom in atomNameList:
                        file.write("{:<6d} ".format(dictionary[atom]))
                    file.write(" {}  {}  {}  {}\n".format(Type, phi, dphi, fc))
Ejemplo n.º 6
0
def reset():
    utils.update("reset", "writing reset.sh...")

    with open("reset.sh", "w+") as file:
        file.write("#!/bin/bash\n\n")
        
        file.write("if [ -f \"%s_MD.pdb\" ]\nthen\n" % universe.get('d_pdbName'))
        file.write("\tread -p \"Warning: simulation has finished. Proceed? (y)\" var\n")
        file.write("else\n")
        file.write("\trm -rf \\_\\_py* charmm*\n")
        file.write("\trm -f *.itp *.top *.mdp *.tpr *.log *.ndx *.edr *.trr *.xtc *.cpt *.dat *.pdf *.xvg\n")
        file.write("\trm -f \\#*\\# EM.pdb NVT.pdb NPT.pdb MD.pdb \n")
        file.write("\trm -f step*.pdb buffer.pdb %s_*.pdb\n" % universe.get('d_pdbName'))
        file.write("\trm -f run.sh reset.sh jobscript.sh universe\n")                   
        file.write("fi\n\n")

        file.write("if [ \"${var}\" = \"y\" ]\nthen\n")
        file.write("\trm -rf \\_\\_py* charmm*\n")
        file.write("\trm -f *.itp *.top *.mdp *.tpr *.log *.ndx *.edr *.trr *.xtc *.cpt *.dat *.pdf *.xvg\n")
        file.write("\trm -f \\#*\\# EM.pdb NVT.pdb NPT.pdb MD.pdb \n")
        file.write("\trm -f step*.pdb buffer.pdb %s_*.pdb\n" % universe.get('d_pdbName'))
        file.write("\trm -f run.sh reset.sh jobscript.sh universe\n")            
        file.write("fi\n\n")

    os.system("chmod +x reset.sh")
Ejemplo n.º 7
0
def jobscript(jobName, jobTime, nodes, ntasks, queue):
    utils.update(
        "jobscript",
        "jobName={0}, jobTime={1}(hrs), nodes={2}, ntasks={3}, queue={4}...".
        format(jobName, jobTime, nodes, ntasks, queue))

    file = open("jobscript.sh", 'w')

    def writeHead(param, value):
        file.write("#SBATCH --%s=%s\n" % (param, value))

    def moduleLoad(value):
        file.write("module load {0}\n".format(value))

    file.write("#!/bin/bash\n\n")

    writeHead("time", "%d-%.2d:00:00" % (int(jobTime / 24), jobTime % 24))
    writeHead("nodes", nodes)
    # writeHead("ntasks", ntasks)
    writeHead("partition", queue)
    writeHead("job-name", jobName)
    writeHead("mail-user", "*****@*****.**")
    writeHead("mail-type", "ALL")
    file.write("#SBATCH -C gpu --gres=gpu:1\n\n")

    moduleLoad("cmake/latest")
    moduleLoad("gcc/7.4")
    moduleLoad("cuda/10.2")

    file.write('\n')

    if universe.get('ph_constantpH'):
        file.write(
            "# compile our custom Gromacs version on cluster backend node\n")
        file.write("mkdir build\n")
        file.write("cd build\n")
        file.write(
            "CC=gcc-7 CXX=g++-7 cmake ~/gromacs-constantph -DGMX_USE_RDTSCP=ON -DCMAKE_INSTALL_PREFIX=${PWD}/.. -DGMX_BUILD_OWN_FFTW=ON -DGMX_GPU=CUDA\n"
        )
        file.write("make -j 12\n")
        file.write("make install -j 12\n")
        file.write("cd ..\n")
        file.write("rm -r build\n")
        file.write("source ${PWD}/bin/GMXRC\n\n")
    else:
        file.write("module load gromacs/2021.1\n\n")

    file.write(
        "gmx grompp -f MD.mdp -c {0} -p topol.top -n index.ndx -o MD.tpr -r {0}\n"
        .format(universe.get('d_nameList')[-1]))

    if universe.get('ph_constantpH'):
        file.write(
            "gmx mdrun -deffnm MD -c {0}_MD.pdb -x MD.xtc -pme cpu -ntmpi 1\n".
            format(universe.get('d_pdbName')))
    else:
        file.write("gmx mdrun -deffnm MD -c {0}_MD.pdb -x MD.xtc\n".format(
            universe.get('d_pdbName')))
Ejemplo n.º 8
0
def add_water():
    utils.update("add_water", "running gmx solvate...")
    
    os.system("gmx solvate -cp {0} -o {1}_SOL.pdb >> builder.log 2>&1".format(universe.get('d_nameList')[-1], universe.get('d_pdbName')))

    # To update d_residues.
    load("{0}_SOL.pdb".format(universe.get('d_pdbName')))

    # To update topol.top.
    topol.add_mol("{0}.ff/{1}.itp".format(universe.get('d_modelFF'), universe.get('d_modelWater')), "Include water topology", "SOL", countRes('SOL'))

    # To update d_nameList.
    utils.add_to_nameList("{0}_SOL.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 9
0
def energy_minimize():
    gen_mdp('EM')

    utils.update("energy_minimize",
                 "running gmx grompp and mdrun for energy minimization...")

    os.system(
        "gmx grompp -f EM.mdp -c {0} -p topol.top -o EM.tpr -r {0} >> builder.log 2>&1"
        .format(universe.get('d_nameList')[-1]))
    os.system("gmx mdrun -deffnm EM -c {0}_EM.pdb >> builder.log 2>&1".format(
        universe.get('d_pdbName')))

    utils.add_to_nameList("{0}_EM.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 10
0
def add_box(d_boxMargin, d_boxType='cubic'):
    utils.update("add_box", "adding box using gmx editconf (boxMargin = {0}, boxType = {1})...".format(d_boxMargin, d_boxType))

    os.system("gmx editconf -f {0} -o {1}_BOX.pdb -d {2} -bt {3} >> builder.log 2>&1".format(universe.get('d_nameList')[-1], universe.get('d_pdbName'), d_boxMargin, d_boxType))

    # To set d_boxMargin and d_boxType.
    universe.add('d_boxMargin', d_boxMargin)
    universe.add('d_boxType', d_boxType)

    # To update d_box.
    load("{0}_BOX.pdb".format(universe.get('d_pdbName')))

    # To update d_nameList.
    utils.add_to_nameList("{0}_BOX.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 11
0
def energy_pcouple():
    gen_mdp('NPT')

    utils.update("energy_pcouple",
                 "running gmx grompp and mdrun for pressure coupling...")

    os.system(
        "gmx grompp -f NPT.mdp -c {0} -p topol.top -o NPT.tpr -r {0} >> builder.log 2>&1"
        .format(universe.get('d_nameList')[-1]))
    os.system(
        "gmx mdrun -deffnm NPT -c {0}_NPT.pdb >> builder.log 2>&1".format(
            universe.get('d_pdbName')))

    utils.add_to_nameList("{0}_NPT.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 12
0
def fitCalibration(order=5, compare=[]):
    # Get relevant stuff from universe.
    # Note: these data-members are only created when calibrate.py is ran.
    dVdlInitList = universe.get('ph_dvdl_initList')
    dVdlMeanList = universe.get('ph_dvdl_meanList')
    dVdlStdList = universe.get('ph_dvdl_stdList')

    # Compute dV/dl coefficients.
    coeffs = np.polyfit(dVdlInitList, dVdlMeanList, order)[::-1]

    # Update user with the coefficients.
    print(coeffs)

    # Plot the computed values.
    plt.scatter(dVdlInitList, dVdlMeanList, label="mean dV/dl")
    plt.errorbar(dVdlInitList,
                 dVdlMeanList,
                 xerr=0,
                 yerr=dVdlStdList,
                 fmt='o',
                 capsize=3,
                 color='#1f77b4')

    # Our fit
    fit = []
    for i in dVdlInitList:
        value = 0
        for j in range(0, order + 1):
            value += coeffs[j] * i**j
        fit.append(value)
    plt.plot(dVdlInitList, fit, label="fit")

    # Comparison
    if len(compare) != 0:
        fit = []
        for i in dVdlInitList:
            value = 0
            for j in range(0, len(compare)):
                value += compare[j] * i**j
            fit.append(value)
        plt.plot(dVdlInitList, fit, label="compare")

    plt.title("Calibration for {}.pdb".format(universe.get('d_pdbName')))
    plt.ylabel(r"dV/d$\lambda$")
    plt.xlabel(r"$\lambda$-coordinate")
    plt.legend()
    plt.grid()
    plt.show()
Ejemplo n.º 13
0
def countRes(resName):
    count = 0
    for residue in universe.get('d_residues'):
        if (residue.d_resname == resName):
            count += 1
    
    return count
Ejemplo n.º 14
0
def add_to_nameList(name):
    if universe.has('d_nameList'):
        temp = universe.get('d_nameList')
        temp.append(name)
        universe.add('d_nameList', temp)
    else:
        universe.add('d_nameList', [name])
Ejemplo n.º 15
0
def plotforces(pKa):
    R = 8.3145 * 10**-3  # "kJ * mol⁻1 * K^-1"
    T = 300

    lambda_i = load.Col("lambda_dwp.dat", 1, 942, 2062)
    V_bias = load.Col("lambda_dwp.dat", 0, 942, 2062)

    pH = universe.get('ph_pH')

    V_pH = []
    for i in lambda_i:
        V_pH.append(R * T * np.log(10) * (pKa - pH) * i)

    V_bias = np.gradient(V_bias)  # Take derivatives.
    V_pH = np.gradient(V_pH)
    V_comb = [V_bias[i] + V_pH[i] for i in range(0, len(lambda_i))]

    plt.plot(lambda_i, V_bias, color="b", linestyle='--', label="$F_{bias}}$")
    plt.plot(lambda_i, V_pH, color="b", linestyle=':', label="$F_{pH}$")
    plt.plot(lambda_i, V_comb, color="b", label="$F_{combined}$")

    plt.ylim(-0.1, 0.1)
    plt.xlabel(r"$\lambda$-coordinate")
    plt.ylabel("Force")
    plt.grid()
    plt.legend()
    plt.show()
Ejemplo n.º 16
0
def plotlambda(plotBUF=False):
    resnameList = []  # Get the names and such of all the ASPs and GLUs.
    residList = []
    for residue in universe.get('d_residues'):
        if residue.d_resname in ["ASP", "ASPH", "ASPT", "GLU", "GLUH", "GLUT"]:
            resnameList.append(residue.d_resname)
            residList.append(residue.d_resid)

    plt.figure()
    for idx in range(1, len(resnameList) + 1):
        t = load.Col("lambda_{0}.dat".format(idx), 1)
        x = load.Col("lambda_{0}.dat".format(idx), 2)

        plt.plot(t,
                 x,
                 label="%s-%s" % (resnameList[idx - 1], residList[idx - 1]),
                 linewidth=0.5)

    if (plotBUF):
        t = load.Col("lambda_{0}.dat".format(len(resnameList) + 1), 1)
        x = load.Col("lambda_{0}.dat".format(len(resnameList) + 1), 2)

        plt.plot(t, x, label="Buffer", linewidth=0.5)

    plt.xlabel("Time (ps)")
    plt.ylabel(r"$\lambda$-coordinate")
    plt.ylim(-0.1, 1.1)
    plt.ticklabel_format(axis='x', style='sci', scilimits=(0, 3))

    plt.legend()
    plt.grid()
    plt.show()
Ejemplo n.º 17
0
def plotpotentials(pKa):
    R = 8.3145 * 10**-3  # "kJ * mol⁻1 * K^-1"
    T = 300

    lambda_i = load.Col("lambda_dwp.dat", 1, 942, 2062)
    V_bias = load.Col("lambda_dwp.dat", 0, 942, 2062)

    pH = universe.get('ph_pH')

    V_pH = []
    for i in lambda_i:
        V_pH.append(R * T * np.log(10) * (pKa - pH) * i)

    V_comb = []
    for i in range(0, len(lambda_i)):
        V_comb.append(V_bias[i] + V_pH[i])

    plt.plot(lambda_i, V_bias, color="b", linestyle='--', label="$V_{bias}}$")
    plt.plot(lambda_i, V_pH, color="b", linestyle=':', label="$V_{pH}$")
    plt.plot(lambda_i, V_comb, color="b", label="$V_{combined}$")

    plt.xlabel(r"$\lambda$-coordinate")
    plt.ylabel(r"$V$ (kJ/mol)")
    plt.grid()
    plt.legend()
    plt.show()
Ejemplo n.º 18
0
def energy_tcouple():
    gen_mdp('NVT')

    utils.update("energy_tcouple",
                 "running gmx grompp and mdrun for temperature coupling...")

    os.system(
        "gmx grompp -f NVT.mdp -c {0} -p topol.top -o NVT.tpr -r {0} >> builder.log 2>&1"
        .format(universe.get('d_nameList')[-1]))
    os.system("gmx mdrun -deffnm NVT -c NVT.pdb >> builder.log 2>&1")

    utils.add_to_nameList("NVT.pdb")
Ejemplo n.º 19
0
    def writeResBlock(number, name, indexLambda, indexName):
        addParam('lambda-dynamics-atom-set%s-name' % (number), name)
        addParam('lambda-dynamics-atom-set%s-lambda-residues-index' % (number),
                 indexLambda)
        addParam('lambda-dynamics-atom-set%s-index-group-name' % (number),
                 indexName)
        addParam('lambda-dynamics-atom-set%s-initial-lambda' % (number),
                 lambdaInit)

        if universe.get('ph_restrainpH'):
            addParam(
                'lambda-dynamics-atom-set%s-charge-restraint-group-index' %
                (number), 1)

        if (name == 'BUF'):
            addParam('lambda-dynamics-atom-set%s-buffer-residue' % (number),
                     'yes')
            addParam(
                'lambda-dynamics-atom-set%s-buffer-residue-multiplier' %
                (number), universe.get('ph_bufnmol'))

        file.write('\n')
Ejemplo n.º 20
0
    def rebuild_topol():
        # If we have only one chain, gromacs will put everything in topol.top.
        # If we have more than one chain, gromacs will do it for us.
        if (len(universe.get('d_chain')) <= 1):
            readingProtein = False
            
            file = open("topol_Protein_chain_A.itp", 'w')

            for line in open("topol.top").readlines():
                if (not readingProtein and line == "[ moleculetype ]\n"):
                    readingProtein = True
            
                if (readingProtein and line == "; Include water topology\n"):
                    readingProtein = False

                if (readingProtein):
                    file.write(line)
    
            file.close()
    
        with open('topol.top', 'w') as file:
            file.write("; Include forcefield parameters\n")
            file.write("#include \"{0}.ff/forcefield.itp\"\n\n".format(universe.get('d_modelFF')))

            file.write("; Include protein topology\n")
            for letter in universe.get('d_chain'):
                file.write("#include \"topol_Protein_chain_{0}.itp\"\n".format(letter))
            file.write('\n')

            file.write('[ system ]\n')
            file.write('{0}\n\n'.format(universe.get('d_pdbName')))

            file.write('[ molecules ]\n')
            file.write('; Compounts \t\t #mols\n')
            for letter in universe.get('d_chain'):
                file.write("Protein_chain_{0}\t\t1\n".format(letter))
Ejemplo n.º 21
0
def restrain_dihedrals_by_idx(indices, Type, phi, dphi, fc):
    utils.update("restrain_dihedrals", "will restrain dihedral {} {} {} {} (Type={}, phi={}, dphi={}, fc={})".format(indices[0], indices[1], indices[2], indices[3], Type, phi, dphi, fc))

    # Every chain has its own .itp file, so we loop through every file:
    for letter in universe.get('d_chain'):
        # This is to make sure we don't have multiple headers when we add multiple different restraints.
        first = False
        if not "[ dihedral_restraints ]" in open("topol_Protein_chain_{0}.itp".format(letter)).read():
            first = True

        # Append to the end of relevant .itp file:
        with open("topol_Protein_chain_{0}.itp".format(letter), 'a') as file:
            if first:
                file.write("[ dihedral_restraints ]\n")
                file.write("; ai aj ak al type phi dphi fc\n")

            for idx in indices:
                file.write("{:<6d} ".format(idx))
                
            file.write(" {}  {}  {}  {}\n".format(Type, phi, dphi, fc))
Ejemplo n.º 22
0
def add_buffer(ph_bufpdbName, ph_bufitpName, ph_bufMargin=2.0, ph_bufnmol=-1, attempts=100000):
    if not (universe.get('ph_constantpH') and universe.get('ph_restrainpH')):
        utils.update("add_buffer", "either ph_constantpH or ph_restrainpH is False --> skipping...")
        return

    # If user doesn't specified the amount, use #BUF = #ACID.
    if (ph_bufnmol == -1):
        ph_bufnmol = countRes('ASP') + countRes('GLU')

    utils.update("add_buffer", "will attempt to add {0} buffer molecule(s)...".format(ph_bufnmol))

    # RUN GROMACS INSERT-MOLECULES COMMAND
    os.system("touch vdwradii.dat") # we need this dummy file for this to work.

    os.system("gmx insert-molecules -f {0} -o {1}_BUF.pdb -ci {2} -nmol {3} -scale 1.0 -radius {4} -try {5} >> builder.log 2>&1".format(
        universe.get('d_nameList')[-1],
        universe.get('d_pdbName'),
        ph_bufpdbName,
        ph_bufnmol,
        0.5 * ph_bufMargin,
        int(attempts / ph_bufnmol)))

    os.remove("vdwradii.dat") # clean dummy file.

    # To update d_residues.
    load("{0}_BUF.pdb".format(universe.get('d_pdbName')))    

    # Give user a warning if there wasn't enough space.
    actual = countRes('BUF')
    if actual < ph_bufnmol:
        utils.update("add_buffer", "warning: only {0}/{1} requested buffer molecules inserted after {2} attempts,".format(actual, ph_bufnmol, attempts))
        utils.update("add_buffer", "warning: try decreasing ph_bufMargin (={0}nm) or increasing d_boxMargin (={1}nm)...".format(ph_bufMargin, universe.get('d_boxMargin')))
    else:
        utils.update("add_buffer", "succesfully added {0} buffer molecule(s)...".format(actual))

    # To add buffer topology to topol.top.
    utils.update("add_buffer", "updating topology...")
    os.system("cp {} .".format(ph_bufitpName))
    topol.add_mol(os.path.basename(ph_bufitpName), "Include buffer topology", 'BUF', actual)

    # Set some parameters in the universe.
    universe.add('ph_bufpdbName', ph_bufpdbName)
    universe.add('ph_bufitpName', ph_bufitpName)
    universe.add('ph_bufMargin', ph_bufMargin)
    universe.add('ph_bufnmol', actual)

    # To update d_nameList.
    utils.add_to_nameList("{0}_BUF.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 23
0
def gen_constantpH(ph_pH, ph_lambdaM, ph_nstout, ph_barrierE, cal=False, lambdaInit=0.5):
    # Skip this entire step if ph_constantpH is false.
    if (not universe.get('ph_constantpH')):
        utils.update("gen_constantpH", "ph_constantpH is False --> skipping...")
        return

    # Check whether MD.mdp exists and create if necessary.
    if (not os.path.isfile("MD.mdp")):
        utils.update("gen_constantpH", "MD.mdp does not exist, creating...")
        md.gen_mdp('MD', universe.get('d_nsteps'), universe.get('d_nstxout'))

    # Check whether index.ndx exists, and create if necessary.
    if (not os.path.isfile("index.ndx")):
        utils.update("gen_constantpH", "index.ndx does not exist, creating...")
        utils.generate_index()

    ############################################################################
    file = open('MD.mdp', 'a')

    def addParam(name, value): # Formatting function.
            file.write("{:54s} = {:13s}\n".format(name, str(value)))

    # Update user.
    utils.update("gen_constantpH", "Writing general parameters:")
    utils.update("gen_constantpH", "ph_pH={}, ph_lambdaM={}, ph_nstout={}, ph_barrierE={}...".format(ph_pH, ph_lambdaM, ph_nstout, ph_barrierE))

    # PART 1 - WRITE GENERAL PARAMETERS ########################################
    file.write("\n; CONSTANT PH\n")

    addParam('lambda-dynamics', 'yes')
    addParam('lambda-dynamics-simulation-ph', ph_pH)
    addParam('lambda-dynamics-lambda-particle-mass', ph_lambdaM)
    addParam('lambda-dynamics-update-nst', ph_nstout)
    addParam('lambda-dynamics-tau', 2.0) # hardcoded

    if cal: # If we are in calibration mode:
        addParam('lambda-dynamics-calibration', 'yes')

    # If we use "charge-constraining" (2) scheme:
    if (universe.get('ph_QQleveling') == 2):
        addParam('lambda-dynamics-charge-constraints', 'yes')

    # Gather a list of the different lambda residue-type names that were 
    # specified IN THE UNIVERSE by the user.
    lambdaTypeNamesSpecifed = []
    for obj in universe.get('ph_lambdaTypes'):
        lambdaTypeNamesSpecifed.append(obj.d_resname)

    # Gather a list of the names of the lambda residues in the protein.
    lambdaResidueNameList = []
    for residue in universe.get('d_residues'):
        if (residue.d_resname in lambdaTypeNamesSpecifed):
            lambdaResidueNameList.append(residue.d_resname)

    # Gather a list of the names of the lambda residue-types IN THE PROTEIN,
    # And make sure the order is the same as in ph_lambdaTypes = LambdaTypeNamesSpecified.
    lambdaResidueTypeList = []
    for obj in universe.get('ph_lambdaTypes'):
        if (obj.d_resname in set(lambdaResidueNameList)):
            lambdaResidueTypeList.append(obj.d_resname)

    # If we use the charge leveling scheme "charge-restraining" (2) we also have
    # the BUF residue-type as well as one extra lambda group containing all the BUFs.
    if (universe.get('ph_QQleveling') == 2):
        addParam('lambda-dynamics-number-lambda-residues', len(lambdaResidueTypeList) + 1)
        addParam('lambda-dynamics-number-atom-collections', len(lambdaResidueNameList) + 1)
    else:
        addParam('lambda-dynamics-number-lambda-residues', len(lambdaResidueTypeList))
        addParam('lambda-dynamics-number-atom-collections', len(lambdaResidueNameList))

    file.write('\n')

    # PART 2 - WRITE RESIDUE-TYPE SPECIFIC STUFF ###############################
    def writeBlock(number, name, dvdl, pKa, ph_barrierE, qqA, qqB):
        def to_string(Input):
            string = ""
            for element in Input:
                string += "{:.3f} ".format(element)
            return string

        addParam('lambda-dynamics-residue%s-name'              % (number), name)
        addParam('lambda-dynamics-residue%s-dvdl-coefficients' % (number), to_string(dvdl))
        addParam('lambda-dynamics-residue%s-reference-pka'     % (number), pKa)
        addParam('lambda-dynamics-residue%s-barrier'           % (number), ph_barrierE)
        addParam('lambda-dynamics-residue%s-charges-state-A'   % (number), to_string(qqA))
        addParam('lambda-dynamics-residue%s-charges-state-B'   % (number), to_string(qqB))

        file.write('\n')

    # If we use a charge-leveling scheme, we need the buffer charge states.
    # These are added to universe when you run protein.add_buffer()
    if (universe.get('ph_QQleveling') in [1, 2]):
        BUF_qqA = universe.get('ph_bufqqA') # BUF_qqA = [-0.0656, 0.5328, 0.5328] previously hardcoded for water buffer
        BUF_qqB = universe.get('ph_bufqqB') # BUF_qqB = [-0.8476, 0.4238, 0.4238] previously hardcoded for water buffer

    idx = 1
    for obj in universe.get('ph_lambdaTypes'):
        # This if-statement prevents writing a block when there are no residues of this type.
        if (obj.d_resname in lambdaResidueTypeList):
            # If we use "charge-coupling" (1) scheme, extend the charge states:
            if (universe.get('ph_QQleveling') == 1):
                writeBlock(idx, obj.d_resname, obj.d_dvdl[::-1], obj.d_pKa, ph_barrierE, obj.d_qqA + BUF_qqB, obj.d_qqB + BUF_qqA)
            else:
                writeBlock(idx, obj.d_resname, obj.d_dvdl[::-1], obj.d_pKa, ph_barrierE, obj.d_qqA, obj.d_qqB)
            idx += 1

    if (universe.get('ph_QQleveling') == 2):
        # f we use "charge-constraining" (2) scheme, we additionaly need ph_BUF_dvdl.
        writeBlock(idx, 'BUF', universe.get('ph_BUF_dvdl')[::-1], 0, 0, BUF_qqA, BUF_qqB)

    # PART 3 - WRITE INDIVIDUAL RESIDUE/LAMBDA-GROUP STUF ######################
    def writeResBlock(number, name, indexLambda, indexName):
        addParam('lambda-dynamics-atom-set%s-name'                  % (number), name)
        addParam('lambda-dynamics-atom-set%s-lambda-residues-index' % (number), indexLambda)
        addParam('lambda-dynamics-atom-set%s-index-group-name'      % (number), indexName)
        addParam('lambda-dynamics-atom-set%s-initial-lambda'        % (number), lambdaInit)
        
        if (universe.get('ph_QQleveling') == 2):
            addParam('lambda-dynamics-atom-set%s-charge-restraint-group-index' % (number), 1)

        if (name == 'BUF'):
            addParam('lambda-dynamics-atom-set%s-buffer-residue' % (number), 'yes')
            addParam('lambda-dynamics-atom-set%s-buffer-residue-multiplier' % (number), universe.get('ph_bufnmol'))

        file.write('\n')

    utils.update("gen_constantpH", "Writing individual lambda groups...")

    idx = 1
    for name in lambdaResidueNameList:
        writeResBlock(idx, name, lambdaResidueTypeList.index(name) + 1, 'LAMBDA{}'.format(idx))
        idx += 1

    if (universe.get('ph_QQleveling') == 2):
        writeResBlock(idx, 'BUF', len(lambdaResidueTypeList) + 1, 'LAMBDA{}'.format(len(lambdaResidueNameList) + 1))

    file.close() # MD.mdp

    # PART 4 - APPEND THE LAMBDA INDEX GROUPS TO INDEX.NDX #####################
    utils.update("gen_constantpH", "Writing lambda index groups to index.ndx...")

    # If we use a charge-leveling scheme, we need a list of atomIndices of the BUFs:
    if (universe.get('ph_QQleveling') in [1, 2]):
        bufferAtomIndexList = []

        count = 1
        for residue in universe.get('d_residues'):
            for atom in residue.d_atoms:
                if (residue.d_resname == 'BUF'):
                    bufferAtomIndexList.append(count)

                count += 1

    file = open('index.ndx', 'a') # Append to existing index.ndx

    def writeTheGroup(number, atomIndexList):
        file.write('\n[ LAMBDA{} ]\n'.format(number))
        for index in atomIndexList:
            file.write('{} '.format(index))
        file.write('\n')

    ph_lambdaTypes = universe.get('ph_lambdaTypes')

    atomCount = 1; groupNumber = 1
    for residue in universe.get('d_residues'):
        if residue.d_resname in lambdaResidueTypeList:

            atomIndexList = []
            obj = ph_lambdaTypes[lambdaTypeNamesSpecifed.index(residue.d_resname)]

            for atom in residue.d_atoms:
                if atom in obj.d_atoms:
                    atomIndexList.append(atomCount)

                atomCount += 1

            # If we use "charge-coupling" (1), assign the atomIndices of one BUF
            # to one protonatable lambda residue (use clever list slicing):            
            if (universe.get('ph_QQleveling') == 1):
                start = (groupNumber - 1) * len(BUF_qqA)
                stop  = start + len(BUF_qqA)
                atomIndexList += bufferAtomIndexList[start:stop]                

            writeTheGroup(groupNumber, atomIndexList)
            groupNumber += 1

        else:
            for atom in residue.d_atoms:
                atomCount += 1

    # If we use "charge-restraining" (2), add everything in bufferAtomIndexList
    # to the last lambda index group:
    if (universe.get('ph_QQleveling') == 2):
        writeTheGroup(groupNumber, bufferAtomIndexList)

    file.close() # index.ndx

    # Put relevant pH variables in universe
    universe.add('ph_pH', ph_pH)
    universe.add('ph_lambdaM', ph_lambdaM)
    universe.add('ph_nstout', ph_nstout)
    universe.add('ph_barrierE', ph_barrierE)
Ejemplo n.º 24
0
def gen_constantpH(ph_pH,
                   ph_lambdaM,
                   ph_nstout,
                   ph_barrierE,
                   cal=False,
                   lambdaInit=0.5):
    # Hardcoded stuff
    GLU_pKa = 4.25
    GLU_atoms = [' CG ', ' CD ', ' OE1', ' OE2', ' HE2']  # atoms part of model
    GLU_qqA = [-0.21, 0.75, -0.55, -0.61, 0.44]  # protonated charge
    GLU_qqB = [-0.28, 0.62, -0.76, -0.76, 0.00]  # deprotonated charge

    ASP_pKa = 3.65
    ASP_atoms = [' CB ', ' CG ', ' OD1', ' OD2', ' HD2']  # atoms part of model
    ASP_qqA = [-0.21, 0.75, -0.55, -0.61, 0.44]  # protonated charge
    ASP_qqB = [-0.28, 0.62, -0.76, -0.76, 0.00]  # deprotonated charge

    BUF_qqA = [-0.0656, 0.5328, 0.5328]
    BUF_qqB = [-0.8476, 0.4238, 0.4238]

    # Skip this entire step if ph_constantpH is false.
    if (not universe.get('ph_constantpH')):
        utils.update("gen_constantpH",
                     "ph_constantpH is False --> skipping...")
        return

    # Load dV/dl coefficients
    GLU_dvdl = universe.get('ph_GLU_dvdl')
    ASP_dvdl = universe.get('ph_ASP_dvdl')

    if (universe.get('ph_restrainpH')):
        BUF_dvdl = universe.get('ph_BUF_dvdl')

    # Check whether MD.mdp exists.
    if (not os.path.isfile("MD.mdp")):
        utils.update("gen_constantpH", "MD.mdp does not exist, creating...")
        md.gen_mdp('MD', universe.get('d_nsteps'), universe.get('d_nstxout'))

    # Check whether index.ndx exists.
    if (not os.path.isfile("index.ndx")):
        utils.update("gen_constantpH", "index.ndx does not exist, creating...")
        utils.generate_index()

    file = open('MD.mdp', 'a')

    # Formatting function.
    def addParam(name, value, comment="NUL"):
        if (comment == "NUL"):
            file.write("{:54s} = {:13s}\n".format(name, str(value)))
        else:
            file.write("{:54s} = {:13s} ; {:13s}\n".format(
                name, str(value), comment))

    file.write("\n; CONSTANT PH\n")

    # PART 1 - WRITE GENERAL PARAMETERS ########################################

    # Update user.
    utils.update("gen_constantpH", "Writing general parameters:")
    utils.update(
        "gen_constantpH",
        "ph_pH={}, ph_lambdaM={}, ph_nstout={}, ph_barrierE={}...".format(
            ph_pH, ph_lambdaM, ph_nstout, ph_barrierE))

    addParam('lambda-dynamics', 'yes')
    addParam('lambda-dynamics-simulation-ph', ph_pH)
    addParam('lambda-dynamics-lambda-particle-mass', ph_lambdaM)
    addParam('lambda-dynamics-update-nst', ph_nstout)
    addParam('lambda-dynamics-tau', 2.0)  # hardcoded

    if cal:
        addParam('lambda-dynamics-calibration', 'yes')

    if universe.get('ph_restrainpH'):
        addParam('lambda-dynamics-charge-constraints', 'yes')

    # Compile a list of acidic residues and their ResIDs.
    acidicResidueNameList = []
    acidicResidueNumberList = []
    acidicResidueTypeList = []

    for residue in universe.get('d_residues'):
        if (residue.d_resname == 'GLU'):
            acidicResidueNameList.append('GLU')
            acidicResidueNumberList.append(residue.d_resid)

        if (residue.d_resname == 'ASP'):
            acidicResidueNameList.append('ASP')
            acidicResidueNumberList.append(residue.d_resid)

    if ('GLU' in acidicResidueNameList):
        acidicResidueTypeList.append('GLU')

    if ('ASP' in acidicResidueNameList):
        acidicResidueTypeList.append('ASP')

    if universe.get('ph_restrainpH'):  # If we restrain the charge
        acidicResidueTypeList.append('BUF')  # we also have BUF.

    addParam('lambda-dynamics-number-lambda-residues',
             len(acidicResidueTypeList))

    if universe.get('ph_restrainpH'):
        addParam('lambda-dynamics-number-atom-collections',
                 len(acidicResidueNameList) + 1)
    else:
        addParam('lambda-dynamics-number-atom-collections',
                 len(acidicResidueNameList))

    file.write('\n')

    # print(acidicResidueNameList)   # debug
    # print(acidicResidueNumberList) # debug
    # print(acidicResidueTypeList)   # debug

    # PART 2 - WRITE RESIDUE-TYPE SPECIFIC STUFF ###############################

    utils.update("gen_constantpH", "Writing residue-type specific stuff...")

    def writeBlock(number, name, dvdl, pKa, ph_barrierE, qqA, qqB):
        def to_string(Input):
            string = ""
            for element in Input:
                string += "{:.3f}".format(element)
                string += ' '
            return string

        addParam('lambda-dynamics-residue%s-name' % (number), name)
        addParam('lambda-dynamics-residue%s-dvdl-coefficients' % (number),
                 to_string(dvdl))
        addParam('lambda-dynamics-residue%s-reference-pka' % (number), pKa)
        addParam('lambda-dynamics-residue%s-barrier' % (number), ph_barrierE)
        addParam('lambda-dynamics-residue%s-charges-state-A' % (number),
                 to_string(qqA))
        addParam('lambda-dynamics-residue%s-charges-state-B' % (number),
                 to_string(qqB))

        file.write('\n')

    for idx in range(0, len(acidicResidueTypeList)):
        if (acidicResidueTypeList[idx] == 'GLU'):
            writeBlock(idx + 1, 'GLU', GLU_dvdl, GLU_pKa, ph_barrierE, GLU_qqA,
                       GLU_qqB)

        if (acidicResidueTypeList[idx] == 'ASP'):
            writeBlock(idx + 1, 'ASP', ASP_dvdl, ASP_pKa, ph_barrierE, ASP_qqA,
                       ASP_qqB)

        if (acidicResidueTypeList[idx] == 'BUF'):
            # If number of protonatable residues != number of buffer molecules,
            # we need to increase buffer charge in state A by the ratio:
            nLams = protein.countRes('ASP') + protein.countRes('GLU')
            nBufs = universe.get('ph_bufnmol')
            BUF_qqA = [(nLams / float(nBufs)) * i for i in BUF_qqA]

            writeBlock(idx + 1, 'BUF', BUF_dvdl, 0, 0, BUF_qqA, BUF_qqB)

    # PART 3 - WRITE INDIVIDUAL RESIDUE/LAMBDA-GROUP STUF ######################

    utils.update("gen_constantpH", "Writing individual lambda groups...")

    def writeResBlock(number, name, indexLambda, indexName):
        addParam('lambda-dynamics-atom-set%s-name' % (number), name)
        addParam('lambda-dynamics-atom-set%s-lambda-residues-index' % (number),
                 indexLambda)
        addParam('lambda-dynamics-atom-set%s-index-group-name' % (number),
                 indexName)
        addParam('lambda-dynamics-atom-set%s-initial-lambda' % (number),
                 lambdaInit)

        if universe.get('ph_restrainpH'):
            addParam(
                'lambda-dynamics-atom-set%s-charge-restraint-group-index' %
                (number), 1)

        if (name == 'BUF'):
            addParam('lambda-dynamics-atom-set%s-buffer-residue' % (number),
                     'yes')
            addParam(
                'lambda-dynamics-atom-set%s-buffer-residue-multiplier' %
                (number), universe.get('ph_bufnmol'))

        file.write('\n')

    for idx in range(0, len(acidicResidueNameList)):
        writeResBlock(
            idx + 1, acidicResidueNameList[idx],
            acidicResidueTypeList.index(acidicResidueNameList[idx]) + 1,
            'LAMBDA%s' % (idx + 1))

    if universe.get('ph_restrainpH'):
        writeResBlock(
            len(acidicResidueNameList) + 1, 'BUF',
            acidicResidueTypeList.index('BUF') + 1,
            'LAMBDA%s' % (len(acidicResidueNameList) + 1))

    file.close()  # MD.mdp

    # PART 4 - APPEND THE LAMBDA INDEX GROUPS TO INDEX.NDX #####################

    utils.update("gen_constantpH",
                 "Writing lambda index groups to index.ndx...")

    file = open('index.ndx', 'a')  # Append to existing index.ndx

    # Function for adding an indexList to index.ndx
    def writeTheGroup(number, indexList):
        file.write('\n[ LAMBDA{} ]\n'.format(number))
        for index in indexList:
            file.write('{} '.format(index))
        file.write('\n')

    atomCount = 1  # Keeps track of the atom number.
    grpNum = 1  # Keeps track of the group (the LAMBDA%s).

    for residue in universe.get('d_residues'):  # loop through all residues

        indexList = []  # clear indexList

        for atom in residue.d_atoms:  # for each residue, loop through the atoms

            if (residue.d_resname == 'GLU' and atom in GLU_atoms):
                indexList.append(atomCount)

            elif (residue.d_resname == 'ASP' and atom in ASP_atoms):
                indexList.append(atomCount)

            atomCount += 1  # increment atomcount

        if (len(indexList) > 0):
            writeTheGroup(grpNum, indexList)
            grpNum += 1

    if universe.get('ph_restrainpH'):

        atomCount = 1
        indexList = []

        for residue in universe.get('d_residues'):
            for atom in residue.d_atoms:

                if (residue.d_resname == 'BUF'):
                    indexList.append(atomCount)

                atomCount += 1

        writeTheGroup(grpNum, indexList)

    file.close()  # index.ndx

    # Put relevant pH variables in universe
    universe.add('ph_pH', ph_pH)
    universe.add('ph_lambdaM', ph_lambdaM)
    universe.add('ph_nstout', ph_nstout)
    universe.add('ph_barrierE', ph_barrierE)
Ejemplo n.º 25
0
def glicphstates():
    # EXPERIMENTAL DATA ON PROTONATION STATES AT VARIOUS PH ####################
    biophys = {  # also prevost2012
        'ASP-13': 1,
        'ASP-31': 1,
        'ASP-32': 1,
        'ASP-49': 1,
        'ASP-55': 1,
        'ASP-86': 0,
        'ASP-88': 0,
        'ASP-91': 1,
        'ASP-97': 1,
        'ASP-115': 1,
        'ASP-122': 1,
        'ASP-136': 1,
        'ASP-145': 1,
        'ASP-153': 1,
        'ASP-154': 1,
        'ASP-161': 1,
        'ASP-178': 1,
        'ASP-185': 1,
        'GLU-14': 1,
        'GLU-26': 0,
        'GLU-35': 0,
        'GLU-67': 0,
        'GLU-69': 1,
        'GLU-75': 0,
        'GLU-82': 0,
        'GLU-104': 1,
        'GLU-147': 1,
        'GLU-163': 1,
        'GLU-177': 0,
        'GLU-181': 1,
        'GLU-222': 1,
        'GLU-243': 0,
        'GLU-272': 1,
        'GLU-282': 1
    }

    nury2010 = {  # this is also cheng2010, calimet2013
        'ASP-13': 1,
        'ASP-31': 1,
        'ASP-32': 1,
        'ASP-49': 1,
        'ASP-55': 1,
        'ASP-86': 0,
        'ASP-88': 0,
        'ASP-91': 1,
        'ASP-97': 1,
        'ASP-115': 1,
        'ASP-122': 1,
        'ASP-136': 1,
        'ASP-145': 1,
        'ASP-153': 1,
        'ASP-154': 1,
        'ASP-161': 1,
        'ASP-178': 1,
        'ASP-185': 1,
        'GLU-14': 1,
        'GLU-26': 0,
        'GLU-35': 0,
        'GLU-67': 0,
        'GLU-69': 0,
        'GLU-75': 0,
        'GLU-82': 0,
        'GLU-104': 1,
        'GLU-147': 1,
        'GLU-163': 1,
        'GLU-177': 0,
        'GLU-181': 1,
        'GLU-222': 1,
        'GLU-243': 0,
        'GLU-272': 1,
        'GLU-282': 1
    }

    fritsch2011 = {
        'ASP-13': 0,
        'ASP-31': 0,
        'ASP-32': 1,
        'ASP-49': 1,
        'ASP-55': 0,
        'ASP-86': 0,
        'ASP-88': 0,
        'ASP-91': 0,
        'ASP-97': 0,
        'ASP-115': 1,
        'ASP-122': 1,
        'ASP-136': 1,
        'ASP-145': 0,
        'ASP-153': 0,
        'ASP-154': 0,
        'ASP-161': 0,
        'ASP-178': 0,
        'ASP-185': 0,
        'GLU-14': 0,
        'GLU-26': 0,
        'GLU-35': 0,
        'GLU-67': 0,
        'GLU-69': 0,
        'GLU-75': 0,
        'GLU-82': 0,
        'GLU-104': 1,
        'GLU-147': 0,
        'GLU-163': 0,
        'GLU-177': 0,
        'GLU-181': 0,
        'GLU-222': 1,
        'GLU-243': 0,
        'GLU-272': 0,
        'GLU-282': 0
    }

    lev2017 = {
        'ASP-13': 1,
        'ASP-31': 1,
        'ASP-32': 1,
        'ASP-49': 1,
        'ASP-55': 1,
        'ASP-86': 1,
        'ASP-88': 1,
        'ASP-91': 1,
        'ASP-97': 1,
        'ASP-115': 1,
        'ASP-122': 1,
        'ASP-136': 1,
        'ASP-145': 1,
        'ASP-153': 1,
        'ASP-154': 1,
        'ASP-161': 1,
        'ASP-178': 1,
        'ASP-185': 1,
        'GLU-14': 1,
        'GLU-26': 0,
        'GLU-35': 0,
        'GLU-67': 0,
        'GLU-69': 0,
        'GLU-75': 0,
        'GLU-82': 0,
        'GLU-104': 1,
        'GLU-147': 1,
        'GLU-163': 1,
        'GLU-177': 0,
        'GLU-181': 1,
        'GLU-222': 1,
        'GLU-243': 0,
        'GLU-272': 1,
        'GLU-282': 1
    }

    nemecz2017 = {  # also Hu2018
        'ASP-13': 1,
        'ASP-31': 1,
        'ASP-32': 1,
        'ASP-49': 1,
        'ASP-55': 1,
        'ASP-86': 0,
        'ASP-88': 0,
        'ASP-91': 1,
        'ASP-97': 1,
        'ASP-115': 1,
        'ASP-122': 1,
        'ASP-136': 1,
        'ASP-145': 1,
        'ASP-153': 1,
        'ASP-154': 1,
        'ASP-161': 1,
        'ASP-178': 1,
        'ASP-185': 1,
        'GLU-14': 1,
        'GLU-26': 0,
        'GLU-35': 0,
        'GLU-67': 1,
        'GLU-69': 1,
        'GLU-75': 1,
        'GLU-82': 1,
        'GLU-104': 1,
        'GLU-147': 1,
        'GLU-163': 1,
        'GLU-177': 1,
        'GLU-181': 1,
        'GLU-222': 0,
        'GLU-243': 0,
        'GLU-272': 1,
        'GLU-282': 1
    }

    ullman = {  # unpublished
        'ASP-13': 1,
        'ASP-31': 1,
        'ASP-32': 1,
        'ASP-49': 1,
        'ASP-55': 1,
        'ASP-86': 1,
        'ASP-88': 1,
        'ASP-91': 1,
        'ASP-97': 1,
        'ASP-115': 1,
        'ASP-122': 1,
        'ASP-136': 1,
        'ASP-145': 1,
        'ASP-153': 1,
        'ASP-154': 1,
        'ASP-161': 1,
        'ASP-178': 1,
        'ASP-185': 1,
        'GLU-14': 1,
        'GLU-26': 0,
        'GLU-35': 0,
        'GLU-67': 0,
        'GLU-69': 0,
        'GLU-75': 0,
        'GLU-82': 1,
        'GLU-104': 1,
        'GLU-147': 0,
        'GLU-163': 0,
        'GLU-177': 0,
        'GLU-181': 1,
        'GLU-222': 1,
        'GLU-243': 0,
        'GLU-272': 0,
        'GLU-282': 1
    }

    # DIRECTORY STRUCTURE ######################################################
    dirname = "lambdaplots"
    if not os.path.isdir(dirname):
        os.mkdir(dirname)
    else:
        os.system("rm -f {0}/*.png {0}/*.pdf".format(dirname))

    # GET THE RESIDUE NUMBER, NAME, AND CHAIN OF ALL PROTO RESIDUES ############

    resnameList = []
    residList = []
    chainList = []
    for residue in universe.get('d_residues'):
        if residue.d_resname in ["ASP", "GLU"]:
            resnameList.append(residue.d_resname)
            residList.append(residue.d_resid)
            chainList.append(residue.d_chain)

    # CREATE LAMBDA PLOT FOR EVERY INDIVIDUAL PROTONATABLE RESIDUE #############

    # Loop through all the lambdas:
    # for idx in range(1, len(resnameList) + 1):

    #     plt.figure(figsize=(8, 6))

    #     # Update user
    #     print("plotting {}/{}".format(idx, len(resnameList)), end='\r')

    #     # Load columns from .dat files
    #     t = load.Col("lambda_{0}.dat".format(idx), 1)
    #     x = load.Col("lambda_{0}.dat".format(idx), 2)

    #     # Analyze a running sim not all columns will be equal long so trim:
    #     if len(t) > len(x):
    #         t.pop()
    #     elif len(t) < len(x):
    #         x.pop()

    #     plt.plot(t, x, linewidth=0.5)

    #     # Title
    #     plt.title("{0}-{1} in chain {2} in {3}.pdb\npH={4}, nstlambda={5}, deprotonation={6:.2f}\n\
    #         Experimentally determined state for {0}-{1} at this pH = {7}".format(
    #         resnameList[idx-1],
    #         residList[idx-1],
    #         chainList[idx-1],
    #         universe.get('d_pdbName'),
    #         universe.get('ph_pH'),
    #         universe.get('ph_nstout'),
    #         titrate("lambda_{}.dat".format(idx)),
    #         expVals40["{0}-{1}".format(resnameList[idx-1], residList[idx-1])]
    #         ))

    #     # Axes and stuff
    #     plt.ylim(-0.1, 1.1)
    #     plt.xlabel("Time (ps)")
    #     plt.ticklabel_format(axis='x', style='sci', scilimits=(0, 3))
    #     plt.ylabel(r"$\lambda$-coordinate")
    #     plt.grid()

    #     # Save.
    #     fileName = "{}/{}_{}-{:03d}".format(dirname, chainList[idx-1], resnameList[idx-1], residList[idx-1])
    #     # plt.savefig("{}.pdf".format(fileName)); os.system("pdfcrop {0}.pdf {0}.pdf >> /dev/null 2>&1".format(fileName))
    #     plt.savefig("{}.png".format(fileName))

    #     # clf = clear the entire current figure. close = closes a window.
    #     plt.clf(); plt.close()

    # CREATE HISTOGRAM PLOTS FOR COMBINED PROTO STATE OF ALL FIVE CHAINS #######
    number_of_chains = len(set(chainList))
    residues_per_chain = int(len(resnameList) / number_of_chains)

    for ii in range(1, residues_per_chain + 1):
        data = []
        for jj in range(0, number_of_chains):
            print(ii + residues_per_chain * jj, end=' ')
            data += (load.Col(
                'lambda_{}.dat'.format(ii + residues_per_chain * jj), 2, 49713,
                124320))
        print()

        # PLOTTING STUFF #######################################################

        plt.figure(figsize=(8, 6))
        plt.hist(data, density=True, bins=200)

        # Title
        plt.title(
            "{0}-{1} (all chains) in {2}.pdb\npH={3}, nstlambda={4}, deprotonation={5:.2f}"
            .format(
                resnameList[ii - 1], residList[ii - 1],
                universe.get('d_pdbName'), universe.get('ph_pH'),
                universe.get('ph_nstout'),
                titrate("lambda_{}.dat".format(ii))
                # expVals40["{0}-{1}".format(resnameList[ii-1], residList[ii-1])]
            ))

        # Axes and stuff
        plt.axis([-0.1, 1.1, -0.1, 12])
        plt.xlabel(r"$\lambda$-coordinate")
        plt.ticklabel_format(axis='x', style='sci', scilimits=(0, 3))
        plt.grid()

        # Add green vertical line indicating experimental value
        plt.vlines(x=biophys["{0}-{1}".format(resnameList[ii - 1],
                                              residList[ii - 1])],
                   ymin=0,
                   ymax=12,
                   color='r',
                   linewidth=4.0,
                   label="biophysics.se/Prevost2012 = {}".format(
                       biophys["{0}-{1}".format(resnameList[ii - 1],
                                                residList[ii - 1])]))
        plt.vlines(x=nury2010["{0}-{1}".format(resnameList[ii - 1],
                                               residList[ii - 1])],
                   ymin=0,
                   ymax=10,
                   color='g',
                   linewidth=4.0,
                   label="Nury2010/Cheng2010/Calimet2013 = {}".format(
                       nury2010["{0}-{1}".format(resnameList[ii - 1],
                                                 residList[ii - 1])]))
        plt.vlines(x=fritsch2011["{0}-{1}".format(resnameList[ii - 1],
                                                  residList[ii - 1])],
                   ymin=0,
                   ymax=8,
                   color='b',
                   linewidth=4.0,
                   label="Fritsch2011 = {}".format(
                       fritsch2011["{0}-{1}".format(resnameList[ii - 1],
                                                    residList[ii - 1])]))
        plt.vlines(x=lev2017["{0}-{1}".format(resnameList[ii - 1],
                                              residList[ii - 1])],
                   ymin=0,
                   ymax=6,
                   color='c',
                   linewidth=4.0,
                   label="Lev2017 = {}".format(lev2017["{0}-{1}".format(
                       resnameList[ii - 1], residList[ii - 1])]))
        plt.vlines(x=nemecz2017["{0}-{1}".format(resnameList[ii - 1],
                                                 residList[ii - 1])],
                   ymin=0,
                   ymax=4,
                   color='m',
                   linewidth=4.0,
                   label="Nemecz2017/Hu2018 = {}".format(
                       nemecz2017["{0}-{1}".format(resnameList[ii - 1],
                                                   residList[ii - 1])]))
        plt.vlines(x=ullman["{0}-{1}".format(resnameList[ii - 1],
                                             residList[ii - 1])],
                   ymin=0,
                   ymax=2,
                   color='y',
                   linewidth=4.0,
                   label="Ullman (unpublished) = {}".format(
                       ullman["{0}-{1}".format(resnameList[ii - 1],
                                               residList[ii - 1])]))

        plt.legend()
        # Save and clear
        fileName = "{}/hist_{}-{:03d}".format(dirname, resnameList[ii - 1],
                                              residList[ii - 1])
        # plt.savefig("{}.pdf".format(fileName)); os.system("pdfcrop {0}.pdf {0}.pdf >> /dev/null 2>&1".format(fileName))
        plt.savefig('{}.png'.format(fileName))
        plt.clf()
        plt.close()
Ejemplo n.º 26
0
def add_buffer(ph_bufpdbName="",
               ph_bufitpName="",
               ph_bufqqA=[1],
               ph_bufqqB=[0],
               ph_bufMargin=2.5,
               attempts=100000):
    # This function writes a dummy .pdb containing the default buffer (ion).
    def writeDefaultPDB():
        with open("defaultBuffer.pdb", 'w') as file:
            file.write("TITLE     BUFFER PARTICLE\n")
            file.write("MODEL        1\n")
            file.write(
                "ATOM      1  NA  BUF     1     110.896   2.872  68.855  1.00  0.00            \n"
            )
            file.write("TER\n")
            file.write("ENDMDL\n")

    # This function writes the topology for the default buffer (ion).
    # Note: charge should not be 0 because then some interactions are not generated???
    # Update: this was fixed by Berk in e2c2340.
    def writeDefaultITP():
        with open("defaultBuffer.itp", 'w') as file:
            file.write("[ moleculetype ]\n")
            file.write("; molname	nrexcl\n")
            file.write("BUF		1\n\n")
            file.write("[ atoms ]\n")
            file.write(
                "; id	at type		res nr	residu name at name  cg nr	charge	 \n")
            file.write("1		SOD			1		   BUF			NA		   1		0	 \n\n")
            file.write("#ifdef POSRES_BUF\n")
            file.write("; Position restraint for each buffer ion\n")
            file.write("[ position_restraints ]\n")
            file.write(";  i funct       fcx        fcy        fcz\n")
            file.write("   1    1       1000       1000       1000\n")
            file.write("#endif\n")

    # Skip this whole step if we don't need it.
    if not (universe.get('ph_constantpH')
            and universe.get('ph_QQleveling') in [1, 2]):
        utils.update(
            "add_buffer",
            "either ph_constantpH is False or ph_QQleveling = 0 --> skipping..."
        )
        return

    # Make sure that the sum of the charges in state A and B are correct.
    if (sum(ph_bufqqA) != 1 or sum(ph_bufqqB) != 0):
        utils.warning(
            "add_buffer",
            "buffer charges incorrectly specified! sums must be 1 and 0")
        universe.get('ph_bufqqA')
        universe.get('ph_bufqqB')

    # Determine whether we use the default or a custom buffer.
    useDefault = False
    if (ph_bufpdbName == "" and ph_bufitpName == ""):
        utils.update("add_buffer", "using default (built-in) buffer...")
        useDefault = True
    elif (ph_bufpdbName == "" and ph_bufitpName != ""):
        utils.warning(
            "add_buffer",
            "ph_bufitpName not specified, resorting to default buffer!")
        useDefault = True
    elif (ph_bufpdbName != "" and ph_bufitpName == ""):
        utils.warning(
            "add_buffer",
            "ph_bufpdbName not specified, resorting to default buffer!")
        useDefault = True
    else:
        utils.update("add_buffer", "using custom buffer...")

    if (useDefault):
        # Check to make sure that the charges for the default buffer are correct.
        if (ph_bufqqA != [1] or ph_bufqqB != [0]):
            utils.warning(
                "add_buffer",
                "buffer charges incorrectly specified for default buffer!")
            universe.get('ph_bufqqA')
            universe.get('ph_bufqqB')

        # Generate the files for the default buffer and update data members.
        writeDefaultPDB()
        ph_bufpdbName = "defaultBuffer.pdb"
        writeDefaultITP()
        ph_bufitpName = "defaultBuffer.itp"

    # Get the number of buffer molecules we need.
    ph_bufnmol = 0
    for lambdaType in universe.get('ph_lambdaTypes'):
        ph_bufnmol += countRes(lambdaType.d_resname)

    utils.update(
        "add_buffer",
        "will attempt to add {0} buffer molecule(s)...".format(ph_bufnmol))

    # RUN GROMACS INSERT-MOLECULES COMMAND
    os.system(
        "touch vdwradii.dat")  # we need this dummy file for this to work.

    os.system(
        "gmx insert-molecules -f {0} -o {1}_BUF.pdb -ci {2} -nmol {3} -scale 1.0 -radius {4} -try {5} >> builder.log 2>&1"
        .format(
            universe.get('d_nameList')[-1], universe.get('d_pdbName'),
            ph_bufpdbName, ph_bufnmol, 0.5 * ph_bufMargin,
            int(attempts / ph_bufnmol)))

    os.remove("vdwradii.dat")  # clean dummy file.

    # To update d_residues.
    load("{0}_BUF.pdb".format(universe.get('d_pdbName')))

    # Give user a warning if there wasn't enough space.
    actual = countRes('BUF')
    if actual < ph_bufnmol:
        utils.warning(
            "add_buffer",
            "only {0}/{1} requested buffer molecules inserted after {2} attempts,"
            .format(actual, ph_bufnmol, attempts))
        utils.warning(
            "add_buffer",
            "try decreasing ph_bufMargin (={0}nm) or increasing d_boxMargin (={1}nm)..."
            .format(ph_bufMargin, universe.get('d_boxMargin')))
    else:
        utils.update(
            "add_buffer",
            "succesfully added {0} buffer molecule(s)...".format(actual))

    # To add buffer topology to topol.top.
    utils.update("add_buffer", "updating topology...")

    if (useDefault):
        os.remove("defaultBuffer.pdb")  # Remove dummy .pdb file.
    else:
        os.system("cp {} .".format(ph_bufitpName))  # Copy to working dir.

    topol.add_mol(os.path.basename(ph_bufitpName), "Include buffer topology",
                  'BUF', actual)

    # Set some parameters in the universe.
    universe.add('ph_bufpdbName', ph_bufpdbName)
    universe.add('ph_bufitpName', ph_bufitpName)
    universe.add('ph_bufqqA', ph_bufqqA)
    universe.add('ph_bufqqB', ph_bufqqB)
    universe.add('ph_bufMargin', ph_bufMargin)
    universe.add('ph_bufnmol', actual)

    # To update d_nameList.
    utils.add_to_nameList("{0}_BUF.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 27
0
def gen_mdp(Type, nsteps=25000, nstxout=0, posres=False):
    # HEAD
    if (Type not in ['EM', 'NVT', 'NPT', 'MD']):
        raise Exception(
            "Unknown .mdp Type specified. Types are: EM, NVT, NPT, MD.")

    utils.update(
        "gen_mdp", "Type={0}, nsteps={1}, nstxout={2}, posres={3}".format(
            Type, nsteps, nstxout, posres))

    file = open("{0}.mdp".format(Type), 'w')

    def addTitle(title):
        file.write("\n; {0}\n".format(title.upper()))

    def addParam(name, value, comment=''):
        if (comment == ''):
            file.write("{:20s} = {:13s}\n".format(name, str(value)))
        else:
            file.write("{:20s} = {:13s} ; {:13s}\n".format(
                name, str(value), comment))

    # POSITION RESTRAIN SECTION
    if Type in ['EM', 'MD']:
        if universe.get('ph_constantpH') and universe.get(
                'ph_restrainpH') and posres:
            addTitle('Position restrain')
            addParam('define', '-DPOSRES -DPOSRES_BUF', 'Position restraints.')
        elif universe.get('ph_constantpH') and universe.get('ph_restrainpH'):
            addTitle('Position restrain')
            addParam('define', '-DPOSRES_BUF', 'Position restraints.')

    if (Type in ['NVT', 'NPT']):  # position restrain temp and press coupling.
        addTitle('Position restrain')
        if universe.get('ph_constantpH') and universe.get('ph_restrainpH'):
            addParam('define', '-DPOSRES -DPOSRES_BUF', 'Position restraints.')
        else:
            addParam('define', '-DPOSRES', 'Position restraints.')

    # RUN CONTROL
    addTitle("Run control")

    if (Type == 'EM'):  # emtol hardcored, pretty typical for normal MD.
        dt = 0.01
        addParam('integrator', 'steep', 'Use steep for EM.')
        addParam('emtol', 1000, 'Stop when max force < 1000 kJ/mol/nm.')
        addParam('emstep', dt, 'Time step (ps).')

    if (Type in ['NVT', 'NPT', 'MD']):
        dt = 0.002
        addParam('integrator', 'md')
        addParam('dt', dt, 'Time step (ps).')

    addParam('nsteps', nsteps, '%.1f ns.' % ((dt * nsteps) / 1000.0))

    # We restrain the COM to prevent protein from coming too close to the BUFs.
    if Type == 'MD' and universe.get('ph_restrainpH'):
        addParam('comm-mode', 'Linear', 'Remove center of mass translation.')
        addParam('comm-grps', 'Protein Non-Protein')

    # OUTPUT CONTROL
    addTitle("Output control")
    addParam('nstxout-compressed', nstxout,
             'Write frame every %.3f ps.' % (dt * nstxout))

    # NEIGHBOUR SEARCHING PARAMETERS
    addTitle("Neighbour searching")
    addParam('cutoff-scheme', 'Verlet',
             'Related params are inferred by Gromacs.')

    # BONDED
    if (Type in ['NVT', 'NPT', 'MD']):
        addTitle("Bond parameters")
        addParam('constraints', 'h-bonds', 'Constrain H-bond vibrations.')
        addParam('constraint_algorithm', 'lincs', 'Holonomic constraints.')
        addParam('lincs_iter', 1, 'Related to accuracy of LINCS.')
        addParam('lincs_order', 4, 'Related to accuracy of LINCS.')

    # ELECTROSTATICS
    addTitle("Electrostatics")
    addParam('coulombtype', 'PME', 'Use Particle Mesh Ewald.')

    if (universe.get('d_modelFF')[0:5].lower() == "charm"
        ):  # if we use a CHARMM force field...
        addParam('rcoulomb', 1.2, 'Berk: CHARMM was calibrated for 1.2 nm.')
        addParam('fourierspacing', 0.14, 'Berk: set this to 0.14 for CHARMM.')
    else:  # Default for force fields:
        addParam('rcoulomb', 1.0, 'Coulomb cut-off (nm).')

    # VAN DER WAALS
    addTitle("Van der Waals")
    addParam('vdwtype', 'cut-off', 'Twin range cut-off with nblist cut-off.')

    if (universe.get('d_modelFF')[0:5].lower() == "charm"
        ):  # if we use a CHARMM force field...
        addParam('rvdw', 1.2, 'Berk: CHARMM was calibrated for 1.2 nm.')
        addParam('vdw-modifier', 'force-switch', 'Berk: specific for CHARMM.')
        addParam('rvdw-switch', 1.0, 'Berk: specific for CHARMM.')
    else:  # Default for force fields:
        addParam('rvdw', 1.0, 'Van der Waals cut-off (nm).')

    # TEMPERATURE COUPLING
    if (Type in ['NVT', 'NPT', 'MD']):
        addTitle("Temperature coupling")
        addParam('tcoupl', 'v-rescale')
        addParam('tc-grps', 'SYSTEM')
        addParam('tau-t', 0.5, 'Berk: change from 0.1 to 0.5.')
        addParam('ref-t', 300, 'Reference temp. (K) (for each group).')

    # PRESSURE COUPLING
    if (Type in ['NPT', 'MD']):
        addTitle('Pressure coupling')

        if (Type == 'NPT'):
            addParam('pcoupl', 'Berendsen', 'Use Berendsen for NPT.')
        else:
            addParam('pcoupl', 'Parrinello-Rahman')

        addParam('pcoupltype', 'isotropic', 'Uniform scaling of box.')
        addParam('tau_p', 5.0, 'Berk: better to change from 2.0 to 5.0.')
        addParam('ref_p', 1.0, 'Reference pressure (bar).')
        addParam('compressibility', 4.5e-5,
                 'Isothermal compressbility of water.')
        addParam('refcoord_scaling', 'all',
                 'Required with position restraints.')

    # PERIODIC BOUNDARY CONDITIONS
    addTitle("Periodic boundary condition")
    addParam('pbc', 'xyz', 'To keep molecule(s) in box.')

    # GENERATE VELOCITIES FOR STARTUP
    if (Type == 'NVT'):
        addTitle('Generate velocities for startup')
        addParam('gen_vel', 'yes')

    file.close()

    # PUT RELEVANT PARAMETERS IN UNIVERSE
    if (Type == 'MD'):
        universe.add('d_dt', dt)
        universe.add('d_nsteps', nsteps)
        universe.add('d_nstxout', nstxout)
Ejemplo n.º 28
0
def generate(d_modelFF, d_modelWater, d_terministring="", d_customitp=""):
    # Internal helper function.
    def rebuild_topol():
        # If we have only one chain, gromacs will put everything in topol.top.
        # If we have more than one chain, gromacs will do it for us.
        if (len(universe.get('d_chain')) <= 1):
            readingProtein = False
            
            file = open("topol_Protein_chain_A.itp", 'w')

            for line in open("topol.top").readlines():
                if (not readingProtein and line == "[ moleculetype ]\n"):
                    readingProtein = True
            
                if (readingProtein and line == "; Include water topology\n"):
                    readingProtein = False

                if (readingProtein):
                    file.write(line)
    
            file.close()
    
        with open('topol.top', 'w') as file:
            file.write("; Include forcefield parameters\n")
            file.write("#include \"{0}.ff/forcefield.itp\"\n\n".format(universe.get('d_modelFF')))

            file.write("; Include protein topology\n")
            for letter in universe.get('d_chain'):
                file.write("#include \"topol_Protein_chain_{0}.itp\"\n".format(letter))
            file.write('\n')

            file.write('[ system ]\n')
            file.write('{0}\n\n'.format(universe.get('d_pdbName')))

            file.write('[ molecules ]\n')
            file.write('; Compounts \t\t #mols\n')
            for letter in universe.get('d_chain'):
                file.write("Protein_chain_{0}\t\t1\n".format(letter))

    # ADD RELEVANT PARAMETERS TO UNIVERSE ######################################
    universe.add('d_modelFF', d_modelFF)
    universe.add('d_modelWater', d_modelWater)
    universe.add('d_terministring', d_terministring)

    # USER UPDATE STUFF ########################################################
    countACID = protein.countRes("ASP") + protein.countRes("GLU")

    # If constant-pH is on,
    if universe.get('ph_constantpH'):
        utils.update("generate", 'constant-pH is turned on...')
        
        # and we have at least one protonatable reside,
        if countACID > 0:
            utils.update("generate", "detected {} acidic residue(s):".format(countACID))

            for letter in universe.get('d_chain'):
                count = 1

                for residue in universe.get('d_residues'):
                    if residue.d_chain == letter:
                        count += 1

                        if residue.d_resname in ['ASP', 'GLU']:
                            utils.update("generate", "{:3s}-{:<4d} in chain {}".format(residue.d_resname, count, letter))

            utils.update("generate", "(setting protonation state to true (option 1) for all of these)")

        else:
            utils.update("generate", "no acidic residues detected, constant-pH is turned off...")
            universe.add('ph_constantpH', False)
            universe.add('ph_restrainpH', False)

    else:
        utils.update("generate", 'constant-pH is turned off...')
        universe.add('ph_restrainpH', False) # If ph_constantpH is False then this is also False.

    utils.update("generate", "using the {} force field with the {} water model...".format(d_modelFF, d_modelWater))

    # CREATE EOFSTRING FOR PDB2GMX COMMAND #####################################

    # Here we create EOFstring to circumvent pd2gmx prompting for user input.
    xstr = "<< EOF"
    # The for-loop sets the protonation state of all GLUs and ASPs to 1
    # (True) if ph_constantpH is True, and to 0 (False) if ph_constantpH is False.
    for chain in universe.get('d_chain'):
        for residue in universe.get('d_residues'):
            if residue.d_resname in ['ASP', 'GLU'] and residue.d_chain == chain:
                xstr += "\n{:d}".format(universe.get('ph_constantpH'))
        
        # Furthermore, if the user specified a two-letter string for the termini,
        # add those to the EOFstring as well:
        if (d_terministring != ""):
            xstr += "\n{}".format(d_terministring[0])
            xstr += "\n{}".format(d_terministring[1])
    # End EOFstring:
    xstr += "\nEOF"
    # print(xstr) # Debug

    # UPDATE USER ABOUT WHAT WE DO WITH THE TERMINI ############################

    if (d_terministring != ""):
        utils.update("generate", "Using options {} for termini...".format(d_terministring))
    else:
        utils.update("generate", "No termini specified, using gmx default (00 = NH3+ and COO-)...")
    
    utils.update("generate", "running pdb2gmx to create {}_PR2.pdb and topol.top...".format(universe.get('d_pdbName')))

    # RUN ACTUAL PDB2GMX COMMAND ###############################################

    if (d_terministring != ""):
        os.system("gmx pdb2gmx -f {0} -o {1}_PR2.pdb -asp -glu -ignh -ff {2} -water {3} -ter >> builder.log 2>&1 {4}".format(universe.get('d_nameList')[-1], universe.get('d_pdbName'), d_modelFF, d_modelWater, xstr))
    else:
        os.system("gmx pdb2gmx -f {0} -o {1}_PR2.pdb -asp -glu -ignh -ff {2} -water {3} >> builder.log 2>&1 {4}".format(universe.get('d_nameList')[-1], universe.get('d_pdbName'), d_modelFF, d_modelWater, xstr))

    # Rebuild topology.
    rebuild_topol()

    # Use custom topol_Protein_chain_A.itp (this is a temporary fix for charmm36-mar2019-m4)
    if (d_customitp != ""):
        utils.update("generate", "Overwriting topol_Protein_chain_A.itp generated by pdb2gmx with {}...".format(d_customitp))
        os.system("cp {} .".format(d_customitp))

    # To update d_residues.
    protein.load("{0}_PR2.pdb".format(universe.get('d_pdbName')))

    # To update d_nameList.
    utils.add_to_nameList("{0}_PR2.pdb".format(universe.get('d_pdbName')))
Ejemplo n.º 29
0
def generate_index():
    os.system("gmx make_ndx -f {0} >> builder.log 2>&1 << EOF\nq\nEOF".format(
        universe.get('d_nameList')[-1]))