Ejemplo n.º 1
0
def randomDisperse(bgf_file, size, number, out_file, silent=False):
	"""
def randomDisperse():
	Create a randomly distributed cubic with full of the monomers

Function Parameters:
	bgf_file	A string which contains a monomer information in a BGF format. 
	size
	number
	out_file
	"""

	# initialize

	# open bgf
	if not silent: print("reading monomer..")
	cubicBGF = bgf.BgfFile()
	#for atom in cubicBGF.a:
	#	cubicBGF.delAtom(cubicBGF.a2i[atom.aNo])

	# repeat up to number:
	if not silent: print("generating cubic box..")
	for i in xrange(number):

        # create three random numbers
		x1 = random.uniform(0, size)
		y1 = random.uniform(0, size)
		z1 = random.uniform(0, size)
		
        # move the monomer
		addBGF = bgf.BgfFile(bgf_file)
		headAtom = addBGF.a[0]
		#delta = (headAtom.x - x1, headAtom.y - y1, headAtom.z - z1)
		delta = (x1 - headAtom.x, y1 - headAtom.y, z1 - headAtom.z)
		bgf.moveBGF(addBGF, delta[0], delta[1], delta[2])

        # merge
		cubicBGF = cubicBGF.merge(addBGF, True)

	# make it periodic
	cubicBGF.BIOGRF = "200"
	cubicBGF.DESCRP = bgf_file[:-4]
	cubicBGF.REMARK.insert(0, "Cubic generated by " + os.path.basename(sys.argv[0]) + " by " + os.environ["USER"] + " on " + time.asctime(time.gmtime()))
	cubicBGF.FF = "FORCEFIELD DREIDING"
	cubicBGF.PERIOD = "111"
	cubicBGF.CRYSTX = [ size, size, size, 90.0, 90.0, 90.0 ]
	cubicBGF.AXES = "ZYX"
	cubicBGF.SGNAME = "P 1                  1    1\n"
	cubicBGF.CELLS = [-1, 1, -1, 1, -1, 1]

	# save
	if not silent: print("saving.. " + out_file)
	cubicBGF.saveBGF(out_file)
Ejemplo n.º 2
0
def centerbgffileclass(myBGF, method="com_origin"):

    new_x, new_y, new_z = bgftools.getCom(myBGF, "")

    if len(myBGF.CRYSTX) > 2:
        boxcenter = [(i / 2.0) for i in myBGF.CRYSTX[0:3]]
    else:
        boxsize = bgf.getBGFSize(myBGF, 0)
        boxcenter = [(boxsize[1] - boxsize[0]) / 2,
                     (boxsize[3] - boxsize[2]) / 2,
                     (boxsize[5] - boxsize[4]) / 2]

    if method == "com_origin":
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))
    elif method == "com_center":
        dx = boxcenter[0] - new_x
        dy = boxcenter[1] - new_y
        dz = boxcenter[2] - new_z
        bgf.moveBGF(myBGF, dx, dy, dz)
    elif method == "box_origin":
        dx = boxcenter[0]
        dy = boxcenter[1]
        dz = boxcenter[2]
        bgf.moveBGF(myBGF, dx, dy, dz)
    else:
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))

    return myBGF
Ejemplo n.º 3
0
def centerbgf(bgf_file, out_file, ff_file, method="com_origin", silent=False):
    if silent == 1:
        nu.shutup()

    boxcenter = []

    # open bgf
    if isinstance(bgf_file, bgf.BgfFile):
        myBGF = bgf_file
    else:
        if not silent: print("Reading " + bgf_file + " ..")
        myBGF = bgf.BgfFile(bgf_file)
        if not silent:
            print("Moving the origin of the coordinate in " + bgf_file +
                  " and saving to " + out_file + ".")

    if method != "box_origin":
        new_x, new_y, new_z = bgftools.getCom(myBGF, ff_file)

    if len(myBGF.CRYSTX) > 2:
        boxcenter = [(i / 2.0) for i in myBGF.CRYSTX[0:3]]
    else:
        boxsize = bgf.getBGFSize(myBGF, 0)  # [xlo, xhi, ylo, yhi, zlo, zhi]
        boxcenter = [(boxsize[1] - boxsize[0]) / 2,
                     (boxsize[3] - boxsize[2]) / 2,
                     (boxsize[5] - boxsize[4]) / 2]

    if method == "com_origin":
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))
    elif method == "com_center":
        dx = boxcenter[0] - new_x
        dy = boxcenter[1] - new_y
        dz = boxcenter[2] - new_z
        bgf.moveBGF(myBGF, dx, dy, dz)
    elif method == "box_origin":
        dx = boxcenter[0]
        dy = boxcenter[1]
        dz = boxcenter[2]
        bgf.moveBGF(myBGF, dx, dy, dz)
    else:
        bgf.moveBGF(myBGF, (-new_x), (-new_y), (-new_z))

    # save
    if isinstance(out_file, str):
        if not silent: print("Saving information to " + out_file + " ..")
        myBGF.saveBGF(out_file)
        return 1
    else:
        return myBGF
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def replicateCell(myBGF, multiplication, spaceFilling=True):
    """
replicateCell():
    Requires a BgfFile class.
    Returns a BgfFile class of the replicated structure of the given structure.

    Options:
    spaceFilling = True
        Just copy the cell (x, y, z) times to the (x, y, z) coordinateas. Negative multiplication indices are allowed.
        (1, 1, 1) with a cell gives 4 cells (i.e. replication to x, y, and z coordinates).

    spaceFilling = False
        Fill the space as a Cuboid form for a given times. Negative multiplication indices are NOT allowed.
        (2, 1, 3) with a cell gives the 6 cells (i.e. cubiod). (1, 1, 1) with a cell gives the identical structure (nothing happens).
    """

    copyTime = [
        int(multiplication[0]),
        int(multiplication[1]),
        int(multiplication[2])
    ]
    # the number of cells that will be copied
    myBGFx = bgf.BgfFile()
    myBGFy = bgf.BgfFile()
    myBGFz = bgf.BgfFile()
    boxsize = [0, 0, 0]

    if len(myBGF.CRYSTX) > 2:
        boxsize = [myBGF.CRYSTX[0], myBGF.CRYSTX[1], myBGF.CRYSTX[2]]
    else:
        box = bgf.getBGFSize(myBGF, 0)  # [xlo, xhi, ylo, yhi, zlo, zhi]
        boxsize = [box[1] - box[0], box[3] - box[2], box[5] - box[4]]

    if spaceFilling:
        if copyTime[0] != 0:
            myBGF2 = copy.deepcopy(myBGF)
            for n in range(0, copyTime[0] - 1):
                bgf.moveBGF(myBGF2, boxsize[0], 0, 0)
                myBGF = myBGF.merge(myBGF2, True)
        if copyTime[1] != 0:
            myBGF2 = copy.deepcopy(myBGF)
            for n in range(0, copyTime[1] - 1):
                bgf.moveBGF(myBGF2, 0, boxsize[1], 0)
                myBGF = myBGF.merge(myBGF2, True)
        if copyTime[2] != 0:
            myBGF2 = copy.deepcopy(myBGF)
            for n in range(0, copyTime[2] - 1):
                bgf.moveBGF(myBGF2, 0, 0, boxsize[2])
                myBGF = myBGF.merge(myBGF2, True)

        # update the CRYSTX information
        if len(myBGF.CRYSTX) > 2:
            for index, number in enumerate(copyTime):
                myBGF.CRYSTX[index] *= copyTime[index]

    else:
        # replication
        if copyTime[0] != 0:
            if copyTime[0] < 0: sign = -1
            else: sign = 1
            for n in range(0, abs(copyTime[0])):
                if copyTime[0] < 0: n -= 1
                myBGF2 = copy.deepcopy(myBGF)
                bgf.moveBGF(myBGF2, boxsize[0] * (n + 1) * sign, 0, 0)
                myBGFx = myBGFx.merge(myBGF2, True)
        if copyTime[1] != 0:
            if copyTime[0] < 0: sign = -1
            else: sign = 1
            for n in range(0, abs(copyTime[1])):
                if copyTime[0] < 0: n -= 1
                myBGF2 = copy.deepcopy(myBGF)
                bgf.moveBGF(myBGF2, 0, boxsize[1] * (n + 1) * sign, 0)
                myBGFy = myBGFy.merge(myBGF2, True)
        if copyTime[2] != 0:
            if copyTime[0] < 0: sign = -1
            else: sign = 1
            for n in range(0, abs(copyTime[2])):
                if copyTime[0] < 0: n -= 1
                myBGF2 = copy.deepcopy(myBGF)
                bgf.moveBGF(myBGF2, 0, 0, boxsize[2] * (n + 1) * sign)
                myBGFz = myBGFz.merge(myBGF2, True)

        myBGF = myBGF.merge(myBGFx, True)
        myBGF = myBGF.merge(myBGFy, True)
        myBGF = myBGF.merge(myBGFz, True)

        # update the CRYSTX information
        if len(myBGF.CRYSTX) > 2:
            for index, number in enumerate(copyTime):
                myBGF.CRYSTX[index] += myBGF.CRYSTX[index] * copyTime[index]

    return myBGF
Ejemplo n.º 6
0
def fourPEI(bgf_file, ff_file, suffix, out_file, monomers, Rg, directory, silent):
	"""
def fourPEI(bgf_file, ff_file, suffix, out_file, monomers, Rg, directory, silent):
	Runs a simulation which performs a crosslinking with given monomers.

Function Parameters:
	bgf_file	A string which contains a PEI information in a BGF format. 
			(e.g. "file1.bgf file2.bgf file3.bgf ...")

	ff_file		A string which contains a ForceField information. 
			(e.g. "~/ff/dreiding_den.par")

	suffix		A string which represents the job suffix. e.g. "tetramer"

	out_file	A string which represents the name of the output file.

	monomers	An integer which represents the number of PEIs that participates in a crosslinker.
			If # of bgf_file < monomers, then additional PEI structure files will be added by looking up files from 
			"/home/noische/research/dendrimer/structure/600/minEnergyOrder". You can change this directory by changing
			structure_dir variables in the script.

	Rg		A float which contains the distance between monomers.

	directory	A string which contains the pool of BGF files.

	silent		True/False flag for determining printing output messages.
	"""

	if monomers == 4:
		pass;
	elif monomers == 10:
		pass;
	elif monomers == 16:
		pass;
	elif monomers == 27:
		pass;
	elif monomers == 2:
		pass;
	else:
		nu.die("Sorry, %s crosslinking is not yet provided." % str(monomers))

	# variables
	chosen_pei = []
	extension = ".bgf"
	log_file = suffix + ".log"
	f_log_file = open(log_file, 'w')

	f_log_file.write("fourPEI.py: version " + str(version) + "\n")
	f_log_file.write("" + "\n")
	f_log_file.write("Job started at " + time.asctime(time.gmtime()) + " on " + os.environ["HOSTNAME"] + " by " + os.environ["USER"] + "\n")
	f_log_file.write("Command executed at " + os.getcwd() + "\n")
	f_log_file.write("Requested options: " + str(sys.argv) + "\n")
	f_log_file.write("" + "\n")

	# CONSTANTS
	#Rg = 6.0055	# average radius of gyration of PEI 600
	#Rg = 8.4088	# don't know?
	#Rg = 12.0100	# just feeling: actually Rg * 2
	f_log_file.write("Using the PEI intermolecular distance " + str(Rg) + "\n")

	# file preparation
	#structure_dir = "/home/noische/research/dendrimer/structure/600/minEnergyOrder"		# basic bgf repository
	structure_dir = directory
	curr_dir = os.path.abspath(".")
	temp_dir = os.path.join(curr_dir, suffix)
	pei_file = glob.glob(structure_dir + "/*.bgf")	# only extracts bgf filename.ext
	#pei_file = [os.path.basename(i) for i in glob.glob(structure_dir + "/*.bgf")]	# only extracts bgf filename.ext
	pei_name = [i.rstrip(".bgf\n")[0] for i in pei_file]				# only extracts bgf filename

	chosen_pei = bgf_file.split(" ")
	if chosen_pei == ['']: chosen_pei = []

	if len(chosen_pei) != monomers:
		for file in chosen_pei:
			if file in pei_file: pei_file.remove(file)	# prevents repeated selections of monomer
		for i in range(0, monomers - len(chosen_pei)):
			a = random.choice(pei_file)
			chosen_pei.append(a)
			pei_file.remove(a)	# prevents repeat. Now chosen_pei contains the files
	# REMARK: chosen_pei = ['a.bgf', 'b.bgf', 'c.bgf', '/home/noische/research/dendrimer/structure/600/minEnergyOrder/600_E025.bgf']

	# scratch preparation
	if not os.path.isdir(temp_dir):
		os.makedirs(temp_dir)
	else:
		#shutil.rmtree(temp_dir)
		os.makedirs(temp_dir)

	# copy files to the scratch
	for file in chosen_pei:
		shutil.copy(file, temp_dir)

	# move to the scratch directory
	os.chdir(temp_dir)

	chosen_pei = [os.path.basename(i) for i in chosen_pei]			# REMARK: ['a.bgf', 'b.bgf', 'c.bgf', '600_E018.bgf']
	chosen_pei_name = [i.partition(".bgf")[0] for i in chosen_pei]		# REMARK: ['a', 'b', 'c', '600_E018']

	f_log_file.write("Structure file directory: " + structure_dir + "\n")
	f_log_file.write("Current working directory: " + curr_dir + "\n")
	f_log_file.write("Temp file directory: " + temp_dir + "\n")
	f_log_file.write("Chosen PEI molecules: " + str(chosen_pei) + "\n")
	if not silent: print(chosen_pei)

	# open BGF structures as BgfFile
	myBGF = [ bgf.BgfFile(i) for i in chosen_pei ]

	# center BGF
	for structure in myBGF:
		structure = centerBGF.centerbgf(structure, 0, ff_file, "com_center", True)
	
	# move BGF for tetrahedron
	#moveBGF(myBGF[1], 0, Rg, Rg)
	#moveBGF(myBGF[2], Rg, 0, Rg)
	#moveBGF(myBGF[3], Rg, Rg, 0)

	# move BGF for planar
	if monomers == 4:
		# Tetrahedron
		bgf.moveBGF(myBGF[1], Rg, Rg, 0)
		bgf.moveBGF(myBGF[2], Rg, 0, Rg)
		bgf.moveBGF(myBGF[3], 0, Rg, Rg)
	elif monomers == 10:
		# Decahedron
		bgf.moveBGF(myBGF[1], Rg, 0, 0)
		bgf.moveBGF(myBGF[2], 2 * Rg, 0, 0)
		bgf.moveBGF(myBGF[3], 0.5 * Rg, 0.86603 * Rg, 0)
		bgf.moveBGF(myBGF[4], 1.5 * Rg, 0.86603 * Rg, 0)
		bgf.moveBGF(myBGF[5], Rg, 1.73205 * Rg, 0)
		bgf.moveBGF(myBGF[6], 0.5 * Rg, 0.28868 * Rg, 0.81650 * Rg)
		bgf.moveBGF(myBGF[7], 1.5 * Rg, 0.28868 * Rg, 0.81650 * Rg)
		bgf.moveBGF(myBGF[8], Rg, 1.15470 * Rg, 0.81650 * Rg)
		bgf.moveBGF(myBGF[9], Rg, 0.57735 * Rg, 1.63300 * Rg)
	elif monomers == 16:
		"""
		# < planar >
		bgf.moveBGF(myBGF[1], 0, Rg, 0)
		bgf.moveBGF(myBGF[2], 0, 2*Rg, 0)
		bgf.moveBGF(myBGF[3], 0, 3*Rg, 0)
		bgf.moveBGF(myBGF[4], Rg, 0, 0)
		bgf.moveBGF(myBGF[5], Rg, Rg, 0)
		bgf.moveBGF(myBGF[6], Rg, 2*Rg, 0)
		bgf.moveBGF(myBGF[7], Rg, 3*Rg, 0)
		bgf.moveBGF(myBGF[8], 2*Rg, 0, 0)
		bgf.moveBGF(myBGF[9], 2*Rg, Rg, 0)
		bgf.moveBGF(myBGF[10], 2*Rg, 2*Rg, 0)
		bgf.moveBGF(myBGF[11], 2*Rg, 3*Rg, 0)
		bgf.moveBGF(myBGF[12], 3*Rg, 0, 0)
		bgf.moveBGF(myBGF[13], 3*Rg, Rg, 0)
		bgf.moveBGF(myBGF[14], 3*Rg, 2*Rg, 0)
		bgf.moveBGF(myBGF[15], 3*Rg, 3*Rg, 0)
		"""
		# L shaped box
		bgf.moveBGF(myBGF[1], Rg, 2*Rg, 2*Rg)
		bgf.moveBGF(myBGF[2], 0, Rg, 0)
		bgf.moveBGF(myBGF[3], Rg, Rg, 0)
		bgf.moveBGF(myBGF[4], 0, 2*Rg, 0)
		bgf.moveBGF(myBGF[5], Rg, 2*Rg, 0)
		bgf.moveBGF(myBGF[6], Rg, 0, Rg)
		bgf.moveBGF(myBGF[7], Rg, Rg, Rg)
		bgf.moveBGF(myBGF[8], Rg, 2*Rg, Rg)
		bgf.moveBGF(myBGF[9], 0, 2*Rg, Rg)
		bgf.moveBGF(myBGF[10], 0, Rg, Rg)
		bgf.moveBGF(myBGF[11], 0, 0, Rg)
		bgf.moveBGF(myBGF[12], Rg, 0, 2*Rg)
		bgf.moveBGF(myBGF[13], Rg, Rg, 2*Rg)
		bgf.moveBGF(myBGF[14], 0, 0, 2*Rg)
		bgf.moveBGF(myBGF[15], 0, Rg, 2*Rg)
	elif monomers == 27:
		# cubic style crosslinking
		bgf.moveBGF(myBGF[1],   Rg,    0,    0)
		bgf.moveBGF(myBGF[2], 2*Rg,    0,    0)
		bgf.moveBGF(myBGF[3],    0,   Rg,    0)
		bgf.moveBGF(myBGF[4],   Rg,   Rg,    0)
		bgf.moveBGF(myBGF[5], 2*Rg,   Rg,    0)
		bgf.moveBGF(myBGF[6],    0, 2*Rg,    0)
		bgf.moveBGF(myBGF[7],   Rg, 2*Rg,    0)
		bgf.moveBGF(myBGF[8], 2*Rg, 2*Rg,    0)
		bgf.moveBGF(myBGF[9],    0,    0,   Rg)
		bgf.moveBGF(myBGF[10],   Rg,    0,   Rg)
		bgf.moveBGF(myBGF[11], 2*Rg,    0,   Rg)
		bgf.moveBGF(myBGF[12],    0,   Rg,   Rg)
		bgf.moveBGF(myBGF[13],   Rg,   Rg,   Rg)
		bgf.moveBGF(myBGF[14], 2*Rg,   Rg,   Rg)
		bgf.moveBGF(myBGF[15],    0, 2*Rg,   Rg)
		bgf.moveBGF(myBGF[16],   Rg, 2*Rg,   Rg)
		bgf.moveBGF(myBGF[17], 2*Rg, 2*Rg,   Rg)
		bgf.moveBGF(myBGF[18],    0,    0, 2*Rg)
		bgf.moveBGF(myBGF[19],   Rg,    0, 2*Rg)
		bgf.moveBGF(myBGF[20], 2*Rg,    0, 2*Rg)
		bgf.moveBGF(myBGF[21],    0,   Rg, 2*Rg)
		bgf.moveBGF(myBGF[22],   Rg,   Rg, 2*Rg)
		bgf.moveBGF(myBGF[23], 2*Rg,   Rg, 2*Rg)
		bgf.moveBGF(myBGF[24],    0, 2*Rg, 2*Rg)
		bgf.moveBGF(myBGF[25],   Rg, 2*Rg, 2*Rg)
		bgf.moveBGF(myBGF[26], 2*Rg, 2*Rg, 2*Rg)
	elif monomers == 2:
		bgf.moveBGF(myBGF[1], Rg, 0, 0)

	# change resnumber of monomers
	for index, structure in enumerate(myBGF):
		for atom in structure.a:
			#atom.rNo = index + 1
			#atom.rNo += (index + 1) * 10
			atom.rNo += (index + 1) * 100

	# merge BGF for any number of monomers
	"""
	myBGF[0] = myBGF[0].merge(myBGF[1], True)
	myBGF[0] = myBGF[0].merge(myBGF[2], True)
	myBGF[0] = myBGF[0].merge(myBGF[3], True)
	"""
	for i in range(1, monomers):
		myBGF[0] = myBGF[0].merge(myBGF[i], True)

	# record BGF properties
	myBGF[0].REMARK.insert(0, "Crosslinked structures: " + str(chosen_pei))
	myBGF[0].REMARK.insert(0, "Crosslinked by " + os.path.basename(sys.argv[0]) + " by " + os.environ["USER"] + " on " + time.asctime(time.gmtime()))

	# save BGF
	myBGF[0].saveBGF(suffix + ".bgf")

	# crosslink
	#if yes_crosslink:
	#	f_log_file.write("Entering crosslinking.\n")
	#	crosslink.crosslink(suffix + ".bgf", ff_file, suffix, nodes, criteria, t, out_file)
	#else:
	#	f_log_file.write("-M option activated. Ignore crosslinking process.\n")

	# file copy
	shutil.copy(os.path.join(temp_dir, suffix + ".bgf"), curr_dir)
	#os.system("cp -rp " + temp_dir + " " + curr_dir)

	f_log_file.close()
Ejemplo n.º 7
0
def getVelocity(bgf_file, trj_file, n_step, silent=False):

	# const
	PI = math.pi
	vdw_r_C = 1.7

	# init
	timestep = 0; l_timestep = []; line = []; n_header = 0;
	t1 = 0; t2 = 0; # clock

	l_data = [];	# stores vz
	l_avg_radius_CNT = [];

	myBGF = bgf.BgfFile(bgf_file)
	myTRJ = open(trj_file)
	myTRJ.seek(0)

	ftemp = open("countWater4.profile.test", 'w')
	ftemp.write(str(sys.argv) + "\n")

	curr_dir = os.path.abspath(".")
	temp_dir = curr_dir + "/CountWAT5/"
	print(temp_dir)
	if not os.path.isdir(temp_dir): os.makedirs(temp_dir)

	# how many steps to go?
	n_timestep = len(lt.getTrjInfo(trj_file))
	if n_step == 0:
		n_step = n_timestep;

	print(" ..The trajectory contains " + str(n_timestep) + " timesteps.")
	print("The script will proceed for the last " + str(n_step) + " timesteps.")

	# extract aNos of CNT in the BGF file
	aNo_CNT = []
	aNo_WAT_O = []
	aNo_WAT_all = []

	for atom in myBGF.a:
		# Carbons in CNT or atoms in BNNT
		if "NT" in atom.rName:
			aNo_CNT.append(atom.aNo)

		# Oxygen in water
		if "WAT" in atom.rName and "O" in atom.aName:
			aNo_WAT_O.append(atom.aNo)

	N_CNT = len(aNo_CNT)	# the number of CNT atoms

	# check if there exists water properly
	if len(aNo_WAT_O) == 0:
		nu.die("No water molecules in the BGF file.")
	if len(aNo_CNT) == 0:
		nu.die("No CNT molecules in the BGF file.")

	# Find header of the trajectory file
	while 1:
		templine = myTRJ.readline()
		line.append(templine.strip('\n').strip('ITEM: '))
		n_header += 1
		if "ITEM: ATOMS" in templine:
			break;

	# INITIAL trajectory information
	timestep = int(line[1])
	natoms = int(line[3])
	boxsize = [line[5].split(' ')[0], line[5].split(' ')[1], line[6].split(' ')[0], line[6].split(' ')[1], line[7].split(' ')[0], line[7].split(' ')[1]]
	boxsize = [float(i) for i in boxsize]
	keywords = line[8].strip('ATOMS ')

	# for every shot in the trajectory file update BGF and manipulate
	dumpatom = get_line(trj_file)
	processed_step = 0;

	t1 = t2 = 0; elapsed_time = 0;

	while 1:

		### tester
		if processed_step == 50:
			break;

		### Show progress
		t1 = time.time();
		remaining_time = elapsed_time * (n_step - processed_step)
		sys.stdout.write('\r' + "Reading timestep.. " + str(timestep) + " (Remaining time: " + "{0:4.1f}".format(remaining_time) + " seconds, " + "{0:4.1f} minutes".format(remaining_time/60) + ")")
		sys.stdout.flush()

		if processed_step == n_step:
			break;

		### Read
		myBGF = bgf.BgfFile(bgf_file)
		try:
			chunk = [next(dumpatom) for i in range(natoms+n_header)]
		except StopIteration:
			break;

		timestep = int(chunk[1])
		natoms = int(chunk[3])
		boxsize = [chunk[5].split(' ')[0], chunk[5].split(' ')[1], chunk[6].split(' ')[0], chunk[6].split(' ')[1], chunk[7].split(' ')[0], chunk[7].split(' ')[1]]; 
		boxsize = [float(i) for i in boxsize]; boxsize = [(boxsize[1] - boxsize[0]), (boxsize[3] - boxsize[2]), (boxsize[5] - boxsize[4])]
		keywords = chunk[8].split('ATOMS ')[1].strip('\n').split(' ')

			
		### update myBGF with trajectory information ###
		natom_bgf = len(myBGF.a)	# number of atoms in BGF file
	
		if not natom_bgf == natoms:
			nu.die("Number of atoms in trajectory file does not match with BGF file.")
	
		mode = 'unwrapped'	# assume that "dump            1 all custom 100 ${sname}${rtemp}K.nvt.lammps id type xu yu zu vx vy vz" in lammps input
	
		# actual coordinate
		coordinfo = chunk[9:]
	
		# modified for fast treatment
		for atomline in coordinfo:
			atomcoord = atomline.split(' ')
			atom = myBGF.getAtom(int(atomcoord[0]))
	
			atom.x = float(atomcoord[2])
			atom.y = float(atomcoord[3])
			atom.z = float(atomcoord[4])
			atom.vx = float(atomcoord[5])
			atom.vy = float(atomcoord[6])
			atom.vz = float(atomcoord[7])

			
		### myBGF update complete! ###


		### align CNT to z axis
		# initialize for the moment of inertia and the center of mass calculation
		U = 0; Ut = 0; Uv = 0;
		Ixx = 0; Ixy = 0; Ixz = 0;
		Iyx = 0; Iyy = 0; Iyz = 0;
		Izx = 0; Izy = 0; Izz = 0;
		Mx = 0; My = 0; Mz = 0;

		# transpose "all atoms in BGF": move COM of CNT as origin
		# com of CNT (important: only one CNT!)
		Mx = 0; My = 0; Mz = 0;
		min_x_CNT = 0.0; max_x_CNT = 0.0; min_y_CNT = 0.0; max_y_CNT = 0.0; min_z_CNT = 0.0; max_z_CNT = 0.0;
		for atom in myBGF.a:
			if "NT" in atom.rName:
				Mx += atom.x / N_CNT
				My += atom.y / N_CNT
				Mz += atom.z / N_CNT

				### before we proceed to calculate MI first check how the CNT is lying across the periodic box
				if atom.x < min_x_CNT:
					min_x_CNT = atom.x
				if atom.x > max_x_CNT:
					max_x_CNT = atom.x
				if atom.y < min_y_CNT:
					min_y_CNT = atom.y
				if atom.y > max_y_CNT:
					max_y_CNT = atom.y
				if atom.z < min_z_CNT:
					min_z_CNT = atom.z
				if atom.z > max_z_CNT:
					max_z_CNT = atom.z
	
		max_x_axis = int(math.ceil(max_x_CNT/boxsize[0]))
		min_x_axis = int(math.floor(min_x_CNT/boxsize[0]))
		max_y_axis = int(math.ceil(max_y_CNT/boxsize[1]))
		min_y_axis = int(math.floor(min_y_CNT/boxsize[1]))
		max_z_axis = int(math.ceil(max_z_CNT/boxsize[2]))
		min_z_axis = int(math.floor(min_z_CNT/boxsize[2]))

		replNum = (min_x_axis, max_x_axis, min_y_axis, max_y_axis, min_z_axis, max_z_axis)
		copyNum = 0

		### copy water molecules
		for x in range(min_x_axis, max_x_axis):
			if x != 0: 
				myBGF2 = copy.deepcopy(myBGF)
				bgf.moveBGF(myBGF2, boxsize[0]*x, 0, 0)
				myBGF = myBGF.merge(myBGF2)
				copyNum += 1

		for y in range(min_y_axis, max_y_axis):
			if y != 0: 
				myBGF2 = copy.deepcopy(myBGF)
				bgf.moveBGF(myBGF2, 0, boxsize[1]*y, 0)
				myBGF = myBGF.merge(myBGF2)
				copyNum += 1

		for z in range(min_z_axis, max_z_axis):
			if z != 0: 
				myBGF2 = copy.deepcopy(myBGF)
				bgf.moveBGF(myBGF2, 0, 0, boxsize[2]*z)
				myBGF = myBGF.merge(myBGF2)
				copyNum += 1

		print(str(replNum) + " " + str(copyNum) + " natoms: " + str(len(myBGF.a)))


		### now continute to MI calculation
		# move atoms to box center
		COM = nu.array([[Mx, My, Mz]])
		CNT = CNT - COM
		'''
		for atom in myBGF.a:
			atom.x -= Mx 
			atom.y -= My 
			atom.z -= Mz 
		'''

		# calculate the moment of inertia (MI) and the center of mass (COM) of CNT from "myBGF"
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			Ixx += (atom.y**2 + atom.z**2) / N_CNT
			Iyy += (atom.x**2 + atom.z**2) / N_CNT
			Izz += (atom.x**2 + atom.y**2) / N_CNT
			Ixy -= (atom.x * atom.y) / N_CNT
			Ixz -= (atom.x * atom.z) / N_CNT
			Iyz -= (atom.y * atom.z) / N_CNT
			
		# the moment of inertia tensor
		I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]])

		# eigenvalue & eigenvector calculation
		eigval, eigvec = np.linalg.eig(I)	# eigval[0] is the minimum among the values.
	
		# rearrange the U vector
		U = np.matrix(eigvec)
		Ut = U.T

		# "myBGF" rotation
		for atom in myBGF.a:
			v = np.matrix([atom.x, atom.y, atom.z]).T
			Uv = Ut * v
			atom.x = float(Uv[2])
			atom.y = float(Uv[1])
			atom.z = float(Uv[0])


		# for CNT atoms, calculate some properties
		min_x_CNT = 1000.0; max_x_CNT = -1000.0; radius_CNT = 0.0; height_CNT = 0.0; 
		min_y_CNT = 1000.0; max_y_CNT = -1000.0;
		min_z_CNT = 1000.0; max_z_CNT = -1000.0;
		CNT_orientation = "-"

		# move origin to box center
		for atom in myBGF.a:
			atom.x += boxsize[0]/2.0
			atom.y += boxsize[1]/2.0
			atom.z += boxsize[2]/2.0

		#myBGF = bgftools.periodicMoleculeSort(myBGF, 0, myBGF.CRYSTX)	##### testestestest

		### update PBC information
		myBGF.PERIOD = "111"
		myBGF.AXES = "ZYX"
		myBGF.SGNAME = "P 1                  1    1\n"
		myBGF.CELLS = [-1, 1, -1, 1, -1, 1]
		if myBGF.CRYSTX != []:
			for i in range(0, 3):
				myBGF.CRYSTX[i] = boxsize[i]
		else:
			for i in range(0, 3):
				myBGF.CRYSTX.append(boxsize[i])
			myBGF.CRYSTX += [90.0, 90.0, 90.0]

		myBGF.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".bgf")

		l_radius_CNT = [];
		l_x_CNT = [];
		l_y_CNT = [];
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)

			# center of CNT
			l_x_CNT.append(atom.x)
			l_y_CNT.append(atom.y)

			# height
			if atom.z < min_z_CNT:
				min_z_CNT = atom.z
			if atom.z > max_z_CNT:
				max_z_CNT = atom.z
	
		x_CNT, a = nu.meanstdv(l_x_CNT)
		y_CNT, a = nu.meanstdv(l_y_CNT)
		z_diff = max_z_CNT - min_z_CNT
		height_CNT = z_diff

		# radius of CNT
		for aNo in aNo_CNT:
			atom = myBGF.getAtom(aNo)
			l_radius_CNT.append( math.sqrt( (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2 ))

		radius_CNT, a = nu.meanstdv(l_radius_CNT)
		l_avg_radius_CNT.append(radius_CNT)


		### get water molecules in CNT

		# inside the CNT := min_z_CNT <= z <= max_z_CNT and (x - (x_diff/2))**2 + (y - (y_diff/2))**2 < radius_CNT**2
		# aNo_WAT_O_atoms: molecules which O atom is within CNT
		# we don't need to calculate H atoms. Let's consider only O atoms
		margin = 0.0;	# water molecules far from the margin will be only considered
		aNo_WAT_O_in_CNT = []
		for aNo in aNo_WAT_O:
			atom = myBGF.getAtom(aNo)
			dist_sq = (atom.x - x_CNT)**2 + (atom.y - y_CNT)**2
			if "WAT" in atom.rName and "O" in atom.ffType and min_z_CNT + margin <= atom.z and atom.z <= max_z_CNT - margin and dist_sq < radius_CNT**2:
				aNo_WAT_O_in_CNT.append(aNo)
			else:
				pass;

		#output = str(timestep) + '\t' + str(len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(z_diff) + '\n'
		output = str(timestep) + '\t' + str(len(aNo_WAT_O_in_CNT)) + '\t' + str(radius_CNT) + '\t' + str(boxsize[0]/2) + '\t' + str(boxsize[1]/2) + '\t' + str(min_z_CNT) + '\t' + str(max_z_CNT) + '\t' + str(z_diff) + '\t' + str(height_CNT) + '\t' + str(len(aNo_CNT)) + '\t' + str(replNum) + '\t' + str(copyNum) + '\n'	# debug
		ftemp.write(output)


		#sys.stdout.write('Done                                                        ')
		sys.stdout.flush()

		t2 = time.time()	# time mark
		elapsed_time = t2 - t1;
		processed_step += 1;


	print('')
	ftemp.close()
	print("numbers of water molecules are written in countWater.profile ..Done.")


	return 1