示例#1
0
def addsolvent(bgf_file,
               solvent_bgf,
               size,
               margin,
               out_file,
               ff_file,
               silent=True):

    ### initialize
    water = False

    ### load the solute bgf file
    if not silent: print("Initializing..")
    myBGF = bgf.BgfFile(bgf_file)  # str

    #solventBGF = bgf.BgfFile("/home/noische/scripts/dat/WAT/f3c_box.bgf")	# F3C waterbox
    if not silent: print("Loading the solvent file " + solvent_bgf + " ..")
    solventBGF = bgf.BgfFile(solvent_bgf)

    ### Generate error when the solvent box is not periodic:
    if not solventBGF.PERIOD:
        nu.die(
            "addSolvent: The solvent file is not periodic. Use a box full of solvent."
        )

    ### Check the type of solvent
    if not silent:
        print("(the solvent box seems to be full of " +
              os.path.basename(solvent_file)[:-4] + " )")
    if "f3c" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.
    if "spc" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.
    if "tip" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.

    ### calculate the box size
    if not silent: print("Analyzing box information..")
    if len(myBGF.CRYSTX) > 2:
        strsize = [myBGF.CRYSTX[0], myBGF.CRYSTX[1], myBGF.CRYSTX[2]]
    else:
        box = bgf.getBGFSize(myBGF, 0)  # [xlo, xhi, ylo, yhi, zlo, zhi]
        strsize = [box[1] - box[0], box[3] - box[2], box[5] - box[4]]

    ###
    if size == "" and margin != "":
        strsize = [
            strsize[0] + 2 * margin[0], strsize[1] + 2 * margin[1],
            strsize[2] + 2 * margin[2]
        ]  # add margin on str size
    elif size != "" and margin == "":
        strsize = size

    waterboxsize = solventBGF.CRYSTX[:3]  # REMARK: This is a kind of constant.
    copyNumber = [0, 0, 0]
    for index, i in enumerate(copyNumber):
        copyNumber[index] = math.ceil(
            strsize[index] /
            waterboxsize[index])  # how many times to replicate the water box

    if not silent: print("Creating box information: " + str(strsize))

    ### replicate the solvent box
    bigboxBGF = bgftools.replicateCell(solventBGF, copyNumber, True)
    bigboxBGF.saveBGF("_replicate.bgf")
    if not silent:
        print("- Number of atoms in the created box: " + str(len(bigboxBGF.a)))

    ### trim the water box
    if water:
        if not silent:
            print("Generating water box.. Calculating water molecules")
        delatom = []
        delwater = []
        delwaterindex = []
        for atom in bigboxBGF.a:
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)
        for aNo in delatom:
            water_molecule = bgftools.is_water(bigboxBGF, aNo)
            if not water_molecule in delwater:
                delwater.append(water_molecule)
        delwater = nu.flatten(delwater)
        delwater = nu.removeRepeat(delwater)
        delwater.sort()
        delwater.reverse()
        for aNo in delwater:
            delwaterindex.append(bigboxBGF.getAtomIndex(aNo))
        del (delwater)
        if not silent: print("Generating water box.. Trimming")
        bigboxBGF.delAtoms(delwaterindex, False)
        bigboxBGF.renumber()
    elif not water:
        if not silent:
            print("Generating solvent box.. Extracting solvent molecules")
        delatom = []
        delsolvent = []
        delsolventindex = []
        for atom in bigboxBGF.a:
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)
        for aNo in delatom:
            molecule_list = []
            molecule = bgftools.getmolecule(bigboxBGF, bigboxBGF.getAtom(aNo),
                                            molecule_list)
            for number in molecule_list:
                if not number in delsolvent: delsolvent.append(number)
        delsolvent = nu.flatten(delsolvent)
        delsolvent = nu.removeRepeat(delsolvent)
        delsolvent.sort()
        delsolvent.reverse()
        for aNo in delsolvent:
            delsolventindex.append(bigboxBGF.getAtomIndex(aNo))
        if not silent: print("Generating solvent box.. Trimming")
        bigboxBGF.delAtoms(delsolventindex, False)
        bigboxBGF.renumber()

    ### merge two structure
    # REMARK: it is natural to have the periodic information of water box for the output BGF file.
    # REMARK: HETATOM should be located on the first of the BGF file. So use dummy for merging.
    if not silent: print("\nAdding trimmed solvent box to the structure..")
    bigboxcenter = [strsize[0] / 2, strsize[1] / 2, strsize[2] / 2]
    a, b, c = bgftools.getCom(myBGF, ff_file)
    bgf.moveBGF(myBGF, bigboxcenter[0] - a, bigboxcenter[1] - b,
                bigboxcenter[2] - c)

    ## remove bad contacts between solutes and solvents
    if not silent: print("Atom distance calculation for contacts..")
    delatom = []
    delsolvent = []
    delsolventindex = []
    for atom1 in myBGF.a:
        for atom2 in bigboxBGF.a:
            # if the distance between atom1 and atom2 is less than 2.8, add to a delete list
            dist_sq = (atom1.x - atom2.x)**2 + (atom1.y - atom2.y)**2 + (
                atom1.z - atom2.z)**2
            if dist_sq < 7.84:
                delatom.append(atom2.aNo)

    # delete bad atoms!
    if not silent: print("Removing bad contacts..")
    for aNo in delatom:
        molecule_list = []
        molecule = bgftools.getmolecule(bigboxBGF, bigboxBGF.getAtom(aNo),
                                        molecule_list)
        for number in molecule_list:
            if not number in delsolvent: delsolvent.append(number)
    delsolvent = nu.flatten(delsolvent)
    delsolvent = nu.removeRepeat(delsolvent)
    delsolvent.sort()
    delsolvent.reverse()
    for aNo in delsolvent:
        delsolventindex.append(bigboxBGF.getAtomIndex(aNo))
    bigboxBGF.delAtoms(delsolventindex, False)
    bigboxBGF.renumber()

    ## compute stats for adding solvents
    if not silent: print("\nComputing stats..")
    mol_list = bgftools.getMoleculeList(bigboxBGF)
    n_mol = len(mol_list)
    n_atom = len(nu.flatten(mol_list))
    if not silent:
        print(
            str(n_mol) + " molecules (" + str(n_atom) +
            " atoms) will be added.")

    ## merge
    bigboxBGF = myBGF.merge(bigboxBGF, True)
    if not silent: print("Total atoms in the file: " + str(len(bigboxBGF.a)))

    ## some paperworking for periodic box
    bigboxBGF.OTHER = solventBGF.OTHER
    bigboxBGF.PERIOD = solventBGF.PERIOD
    bigboxBGF.AXES = solventBGF.AXES
    bigboxBGF.SGNAME = solventBGF.SGNAME
    bigboxBGF.CRYSTX = solventBGF.CRYSTX
    bigboxBGF.CELLS = solventBGF.CELLS

    ## adjust the size of the box
    bigboxBGF.CRYSTX = [
        strsize[0], strsize[1], strsize[2], solventBGF.CRYSTX[3],
        solventBGF.CRYSTX[4], solventBGF.CRYSTX[5]
    ]
    """
	### remove bad contacts and save
	if water:
		if not silent: print("Removing bad contacts: distance criteria is 2.8 A")
		bigboxBGF = removebadcontacts(bigboxBGF, bigboxBGF, 2.8)

		### renumber residue numbers
		# RULE: all rNos for water molecules will be renumbered from 2. (for createLammpsInput.pl)
		if not silent: print("Renumbering water molecules..")
		max_rNo_in_hetatm = 0;
		oxygen_list = bgftools.listOxygenAtoms(bigboxBGF)
	
		### find the biggest rNo among HETATM
		for atom in bigboxBGF.a:
			if atom.aTag == 1:
				if max_rNo_in_hetatm < atom.rNo: max_rNo_in_hetatm = atom.rNo
	
		### update rNo in water molecules
		rNo_for_water = max_rNo_in_hetatm + 500;
		for aNo in oxygen_list:
			water_aNo = bgftools.is_water(bigboxBGF, aNo)	# get aNo in a water molecule by checking the oxygen atom
			if water_aNo != []:
				for atom_aNo in water_aNo:
					bigboxBGF.getAtom(atom_aNo).rNo = rNo_for_water
				rNo_for_water += 1
	"""

    ### record BGF remarks
    bigboxBGF.REMARK.insert(
        0, "Solvents added by " + os.path.basename(sys.argv[0]) + " by " +
        os.environ["USER"] + " on " + time.asctime(time.gmtime()))
    bigboxBGF.REMARK.insert(0, "Solvents: " + str(solvent_file))

    ### save BGF
    if not silent: print("Saving the file.. see " + str(out_file))
    bigboxBGF.saveBGF(out_file)

    return 1
示例#2
0
def anneal(bgf_dir, ff_file, suffix, out_file):

    # *** variables ***

    # used for log file output
    output = ""

    # initialization
    #t1 = 0; t2 = 0;	# clock for measuring time for a cycle

    curr_dir = os.path.abspath(bgf_dir)
    temp_dir = curr_dir + "/anneal/"

    # LAMMPS executive command: defined in ~/scripts/clusterSettings.py
    #lammps_parallel = mpi_command + " -np 8 " + lammps_command
    lammps_parallel = "/home/tpascal/codes/openmpi/1.4.3/bin/mpirun -np 8 " + lammps_command

    # Annealing procedure
    anneal_proc = "/home/noische/script/dat/in.lammps.anneal"

    # get BGF file list in the directory
    pei_files = glob.glob(bgf_dir + "/*.bgf")
    pei_files.sort()

    os.chdir(bgf_dir)

    #print("pei_files: ", pei_files)

    # for file in the directory
    for file in pei_files:
        ### working filename
        print("*** Working on %s" % file)

        filename = file.split(".bgf")[0]
        print("filename: " + filename)

        # centerBGF
        print("Centering %s" % file)
        cmd_centerbgf = "/home/tpascal/scripts/centerBGF.pl -b " + file + " -f " + ff_file + " -s " + filename + ".center.bgf" + " -c com_center"
        nu.shutup()
        os.system(cmd_centerbgf)
        nu.say()

        filename = filename.split("/")[-1]
        print("filename: " + filename)

        # createLammps: with finite options
        # Note that the script refers /home/noische/script/data/in.lammps.anneal for the annealing process
        cmd_createLammpsInput = "/home/tpascal/scripts/createLammpsInput.pl -b " + filename + ".center.bgf" + " -f " + ff_file + " -t /home/noische/script/data/in.lammps.anneal " + " -s " + filename + " -o finite "
        nu.shutup()
        os.system(cmd_createLammpsInput)
        nu.say()

        # patch in.lammps file
        print("Patching infile")
        cmd_sed = "sed -i 's/2 5.0 90/2 4.5 5.0 90/' in." + filename
        nu.shutup()
        os.system(cmd_sed)
        nu.say()

        # patch data.lammps file
        print("Patching datafile")
        cmd_mv = "mv data." + filename + " data." + filename + ".bak"
        os.system(cmd_mv)
        file1 = open("data." + filename, "w")
        file2 = open("data." + filename + ".bak")
        while 1:
            line = file2.readline()
            if not line: break
            if "xlo" in line:
                line = "-50.0 50.0 xlo xhi\n"
                file1.write(line)
            elif "ylo" in line:
                line = "-50.0 50.0 ylo yhi\n"
                file1.write(line)
            elif "zlo" in line:
                line = "-50.0 50.0 zlo zhi\n"
                file1.write(line)
            elif "# X N_3 C_3 X" in line:
                line = line.replace("# X N_3 C_3 X", "0 # X N_3 C_3 X")
                file1.write(line)
            elif "# X C_3 C_3 X" in line:
                line = line.replace("# X C_3 C_3 X", "0 # X C_3 C_3 X")
                file1.write(line)
            else:
                file1.write(line)

        # run
        print("Running simulation")
        lammps_thermo_log_file = filename + ".anneal.log"
        cmd_lammps = lammps_parallel + " -log " + lammps_thermo_log_file
        nu.shutup()
        os.system(cmd_lammps)
        nu.say()

        # read potential energy from file
        # in in.lammps.anneal: "poteng" is the averaged value of potential energy after cooldown
        print("Treating Potential Energy")
        poteng = []
        poteng_files = glob.glob(filename + "*poteng")
        for poteng_file in poteng_files:
            f_poteng_file = open(poteng_file)
            while 1:
                line = f_poteng_file.readline()
                if not line:
                    break
                if not line[0] == "#":
                    parse = line.split()
                    poteng.append([parse[0], float(parse[1])])
        poteng = nu.removeRepeat(poteng)

        ### print potential energy
        for i in poteng:
            print(i)

        # when is the minimum energy during annealing?
        min_poteng = 0
        min_poteng_step = 0
        # usually poteng < 0
        for i in poteng:
            if i[1] < min_poteng:
                min_poteng_step = i[0]
                min_poteng = i[1]

        # convert that timestep into BGF
        trj_file = filename + ".lammpstrj"
        anneal_output_bgf_file = filename + ".annealed.bgf"
        result = LAMMPS_trj2bgf.getLAMMPSTrajectory(pei_file, trj_file,
                                                    anneal_output_bgf_file,
                                                    min_poteng_step, False)
        print("The lowest potential energy structure found")

        # create LAMMPS input for annealed BGF file

        # run the NVT simulation at 300 K

        # average the potential energy

        # average Rg

        # write data: filename, the minimum structure, avr_poteng, avr_Rg
    """
示例#3
0
def periodicMoleculeSort(bgf_file,
                         boxinfo,
                         fragments=[],
                         selection='',
                         out_file='',
                         ff_file="",
                         silent=False,
                         recursion_limit=10000):
    """
def periodicMoleculeSort(bgf_file, out_file, boxinfo, silent=True, recursion_limit=10000):

    read a BGF format from bgf_file and write the periodic information to out_file
    fragments = [ [atom no. of molecule 1], [atom no. of molecule 2], ... ]
    """
    # open bgf
    if isinstance(bgf_file, bgf.BgfFile):
        if not silent:
            print("bgftools.periodicMoleculeSort: Got a tossed BGF format ..")
        myBGF = bgf_file
    else:
        if not silent:
            print("bgftools.periodicMoleculeSort: Reading " + bgf_file + " ..")
        myBGF = bgf.BgfFile(bgf_file)

    # if there is a requesting box size, assign
    if boxinfo:
        myBGF.CRYSTX = boxinfo
        # assign requsted boxinfo to CRYSTX

    # get periodic information of bgf file
    l_myBGFbox = []
    # box size
    if myBGF.CRYSTX == []:
        if not silent:
            nu.die(
                "bgftools.periodicMoleculeSort: ERROR: This BGF file is not periodic. Exiting."
            )
        else:
            print(
                "bgftools.periodicMoleculeSort: ERROR: This BGF file is not periodic. Exiting."
            )
            sys.exit(0)
    else:
        l_myBGFbox = copy.deepcopy(myBGF.CRYSTX)

    # get molecules information
    if fragments:
        l_all_molecules = fragments
    else:
        l_all_molecules = getMoleculeList(myBGF, recursion_limit)

    if selection:
        selected_atoms = [atom.aNo for atom in myBGF.a if eval(selection)]
        new_molecules_list = [
            mol for mol in l_all_molecules for ano in selected_atoms
            if ano in mol
        ]
        new_molecules_list = nu.removeRepeat(new_molecules_list)
    else:
        new_molecules_list = l_all_molecules

    # for every molecules..
    for molecule in new_molecules_list:
        # calculate COM
        cx, cy, cz = getCom(myBGF,
                            ff_file=ff_file,
                            aNo_list=molecule,
                            silent=True)

        # if COM is out of the box then take the residue
        qx, _ = divmod(cx, l_myBGFbox[0])
        qy, _ = divmod(cy, l_myBGFbox[1])
        qz, _ = divmod(cz, l_myBGFbox[2])
        for aNo in molecule:
            atom = myBGF.getAtom(aNo)
            atom.x = atom.x - l_myBGFbox[0] * qx
            atom.y = atom.y - l_myBGFbox[1] * qy
            atom.z = atom.z - l_myBGFbox[2] * qz

    # save
    if out_file:
        if not silent: print("saving information to " + out_file + " ..")
        myBGF.saveBGF(out_file)

    return myBGF
示例#4
0
def addsolvent(bgf_file,
               solvent_bgf,
               min,
               max,
               n_solvent,
               out_file,
               ff_file,
               margin,
               mark,
               silent=True):

    ### initialize
    water = False
    default_margin = 1.0
    x_margin = 0.0
    y_margin = 0.0
    z_margin = 0.0
    if "x" in margin.lower():
        x_margin = default_margin
    if "y" in margin.lower():
        y_margin = default_margin
    if "z" in margin.lower():
        z_margin = default_margin

    ### load the solute bgf file
    if not silent: print("Initializing..")
    myBGF = bgf.BgfFile(bgf_file)  # str
    myBGF.renumber()

    if not silent: print("Loading the solvent file " + solvent_bgf + " ..")
    solventBGF = bgf.BgfFile(solvent_bgf)

    ### Generate error when the solvent box is not periodic:
    if not solventBGF.PERIOD:
        nu.die(
            "addSolvent: The solvent file is not periodic. Use a box full of solvent."
        )

    ### Check the type of solvent
    if not silent:
        print("(the solvent box seems to be full of " +
              os.path.basename(solvent_file)[:-4] + " )")
    if "f3c" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.
    if "spc" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.
    if "tip" in solvent_bgf:
        water = True  # this flag is used to remove the bad contacts with the molecule.

    ### calculate the box size
    if not silent: print("Analyzing box information..")
    if not min:
        min = [0.0, 0.0, 0.0]
    if not max:
        max = myBGF.CRYSTX[:3]

    strsize = [
        max[0] - min[0] - x_margin, max[1] - min[1] - y_margin,
        max[2] - min[2] - z_margin
    ]

    waterboxsize = solventBGF.CRYSTX[:3]  # REMARK: This is a kind of constant.
    copyNumber = [0, 0, 0]
    for index, i in enumerate(copyNumber):
        copyNumber[index] = math.ceil(
            strsize[index] /
            waterboxsize[index])  # how many times to replicate the water box

    if not silent: print("Creating box information: " + str(strsize))

    ### replicate the solvent box
    if not silent: print("Creating box.. this may take some time.")
    bigboxBGF = bgftools.replicateCell(solventBGF, copyNumber, True)
    bigboxBGF.saveBGF("_replicate.bgf")
    if not silent:
        print("- Number of atoms in the created box: " + str(len(bigboxBGF.a)))
    delatom = []
    delsolvent = []
    delsolventindex = []
    delwater = []
    delwaterindex = []

    bigboxBGF = bgf.BgfFile("_replicate.bgf")
    bigboxBGF.renumber()

    ### trim the water box
    if water:
        if not silent:
            print("Generating water box.. Calculating water molecules")
        for atom in bigboxBGF.a:
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)
        for aNo in delatom:
            water_molecule = bgftools.is_water(bigboxBGF, aNo)
            if not water_molecule in delwater:
                delwater.append(water_molecule)
        delwater = nu.flatten(delwater)
        delwater = nu.removeRepeat(delwater)
        for aNo in delwater:
            delwaterindex.append(bigboxBGF.a2i[aNo])
        if not silent: print("Generating water box.. Trimming")
        bigboxBGF.delAtoms(delwaterindex, False)
        bigboxBGF.renumber()
    elif not water:
        if not silent:
            print("Generating solvent box.. Extracting solvent molecules")
        for atom in tqdm.tqdm(bigboxBGF.a, desc='Iterating', ncols=120):
            if atom.x > strsize[0] or atom.y > strsize[1] or atom.z > strsize[
                    2]:
                delatom.append(atom.aNo)

        molecule = bgftools.getMoleculeList(bigboxBGF)
        for aNo in tqdm.tqdm(delatom,
                             desc='Appending atoms to remove',
                             ncols=120):
            for i in molecule:
                if aNo in i:
                    delsolvent += i
                    break
        delsolvent = list(set(delsolvent))
        for aNo in delsolvent:
            delsolventindex.append(bigboxBGF.a2i[aNo])
        if not silent: print("Generating solvent box.. Trimming")
        delsolventindex.sort()
        #delsolventindex.reverse()
        bigboxBGF.delAtoms(delsolventindex, False)
        bigboxBGF.renumber()

    bigboxBGF.saveBGF("_temp.bgf")  ## debug

    ### remain n molecules and delete residues
    bigboxBGF = bgftools.renumberMolecules(bigboxBGF, 0, False)  # renumber rNo

    if n_solvent:
        residues = set()
        for atom in bigboxBGF.a:
            residues.add(atom.rNo)  # scan molecule rNo
        residues = list(residues)
        if not silent: print("Found %d water molecules." % len(residues))
        if len(residues) < n_solvent:
            nu.die("Too few solvent molecules to choose %d molecules." %
                   n_solvent)

        rNos = random.sample(residues, n_solvent)  # select n molecules
        if not silent: print("%d water molecules are chosen." % n_solvent)

        # delete molecules
        delist = []
        for atom in bigboxBGF.a:
            if not atom.rNo in rNos:
                delist.append(bigboxBGF.a2i[atom.aNo])  # if not chosen, delete
        delist.sort()
        bigboxBGF.delAtoms(delist, False)
        bigboxBGF.renumber()

        bigboxBGF = bgftools.renumberMolecules(bigboxBGF, 0, False)

    ### move the water box to min position
    for atom in bigboxBGF.a:
        atom.x += min[0] + x_margin / 2
        atom.y += min[1] + y_margin / 2
        atom.z += min[2] + z_margin / 2

    ### add mark to the solvents
    if mark:
        for atom in bigboxBGF.a:
            atom.chain = mark

    bigboxBGF.saveBGF('_temp.bgf')

    # REMARK: it is natural to have the periodic information of water box for the output BGF file.
    # REMARK: HETATOM should be located on the first of the BGF file. So use dummy for merging.
    ## compute stats for adding solvents
    if not silent: print("\nComputing stats..")
    mol_list = bgftools.getMoleculeList(bigboxBGF)
    n_mol = len(mol_list)
    n_atom = len(nu.flatten(mol_list))
    if not silent:
        print(
            str(n_mol) + " molecules (" + str(n_atom) +
            " atoms) will be added.")

    ## merge
    #bigboxBGF = myBGF.merge(bigboxBGF, True)
    myBGF = bgf.BgfFile(bgf_file)
    bigboxBGF = bgf.BgfFile("_temp.bgf")
    bigboxBGF2 = myBGF.merge(bigboxBGF)
    if not silent: print("Total atoms in the file: " + str(len(bigboxBGF.a)))

    ## some paperworking for periodic box
    bigboxBGF2.OTHER = myBGF.OTHER
    bigboxBGF2.PERIOD = myBGF.PERIOD
    bigboxBGF2.AXES = myBGF.AXES
    bigboxBGF2.SGNAME = myBGF.SGNAME
    bigboxBGF2.CRYSTX = myBGF.CRYSTX
    bigboxBGF2.CELLS = myBGF.CELLS

    ### record BGF remarks
    bigboxBGF2.REMARK.insert(
        0, "Solvents added by " + os.path.basename(sys.argv[0]) + " by " +
        os.environ["USER"] + " on " + time.asctime(time.gmtime()))
    bigboxBGF2.REMARK.insert(0, "Solvents: " + str(solvent_file))

    ### save BGF
    if not silent: print("Saving the file.. see " + str(out_file))
    bigboxBGF2.saveBGF(out_file)

    return 1