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)
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
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
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
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
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()
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