def xyz2bgf(xyz_file, bgf_file, silent=False): """ Converts xyz to bgf """ ### open xyz f_xyz = open(xyz_file, 'r') ### create bgf myBGF = bgf.BgfFile() myBGF.BIOGRF = '200' myBGF.DESCRP = xyz_file ### read and create atoms for bgf file while 1: line = f_xyz.readline() if not line: break words = string.split(line) if not words: break natoms = int(words[0]) myBGF.REMARK = [cleansym(f_xyz.readline())] for i in range(natoms): line = f_xyz.readline() words = string.split(line) sym = words[0] sym = cleansym(sym) x, y, z = float(words[1]), float(words[2]), float(words[3]) ### add atoms atom = bgf.BgfAtom() atom.x = x atom.y = y atom.z = z atom.ffType = sym atom.aNo = i atom.aName = sym + str(i) atom.rNo = 1 atom.chain = "A" atom.rName = "RES" myBGF.addAtom(atom) ### save bgf myBGF.OTHER = [] myBGF.saveBGF(bgf_file)
def convertBGF(self): myBGF = bgf.BgfFile() natom = 0 for index, i in enumerate(self._atom_numbers): name = self._atom_types[index] name = raw_input("- assign the force field type for " + name + " (default: " + name + ") ?? ") or self._atom_types[index] for j in xrange(i): atom = bgf.BgfAtom() atom.x = self._coords[natom][0] atom.y = self._coords[natom][1] atom.z = self._coords[natom][2] atom.aTag = 1 atom.aNo = natom + 1 atom.aName = self._atom_types[index] + str(j + 1) atom.rName = "RES" atom.rNo = 100 atom.chain = "A" atom.ffType = name myBGF.addAtom(atom) natom += 1 # assign remarks myBGF.BIOGRF = 200 myBGF.DESCRP = "From " + self._filename + " at " + time.asctime( time.gmtime( )) + " on " + os.environ["HOSTNAME"] + " by " + os.environ["USER"] myBGF.PERIOD = "111" myBGF.AXES = "ZYX" myBGF.SGNAME = "P 1 1 1" myBGF.CELLS = [-1, 1, -1, 1, -1, 1] myBGF.CRYSTX = self._latticeParams self._bgf = myBGF
def add_ions_inside_nanotube(self, n_ion): """ Add Na+ and Cl- ions inside nanotube. """ if not self.isRadiusCalc == True: nu.warn("Nanotube radius not defined. Exiting.") return 0 ### find the last atom before resname WAT aNo_lastatom = 0 for i in self.bgfmodel.a: aNo = i.aNo if not "WAT" in i.rName: if aNo > aNo_lastatom: aNo_lastatom = aNo ### add n_add = 0 while n_add < n_ion: x = random.uniform(0, self.pbc[0]) y = random.uniform(0, self.pbc[1]) z = random.uniform(0, self.pbc[2]) xyz = np.array([x, y, z]) r = np.sqrt( ((xyz * self.axis - self.center * self.axis)**2).sum(axis=-1)) h = (xyz * self.axismask).sum() if r < self.radius and self.zlo < h < self.zhi: # Na+ ion atom_Na = bgf.BgfAtom() atom_Na.x = x atom_Na.y = y atom_Na.z = z atom_Na.aTag = 1 # HETATM atom_Na.ffType = "Na" atom_Na.rName = "ION" atom_Na.aName = "Na" atom_Na.charge = 1.00 atom_Na.rNo = 0 atom_Na.chain = "X" # Cl- ion atom_Cl = bgf.BgfAtom() atom_Cl.x = x + 2 atom_Cl.y = y + 2 atom_Cl.z = z + 2 atom_Cl.aTag = 1 # HETATM atom_Cl.ffType = "Cl" atom_Cl.rName = "ION" atom_Cl.aName = "Cl" atom_Cl.charge = -1.00 atom_Cl.rNo = 0 atom_Cl.chain = "X" self.bgfmodel.addAtom(atom_Na, self.bgfmodel.a2i[aNo_lastatom + 1]) self.bgfmodel.addAtom(atom_Cl, self.bgfmodel.a2i[aNo_lastatom + 2]) n_add += 1 self.bgfmodel.renumber() print("%d atoms added to the nanotube." % n_add)
def countWater(bgf_file, trj_file, n_step, watercopy, ff_file, 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 myBGF = bgf.BgfFile(bgf_file) myTRJ = open(trj_file) myTRJ.seek(0) global out_file if out_file == "": out_file = "countWater5.profile" print("The result will be recorded to the file " + out_file + " ...") ftemp = open(out_file, 'w') ftemp.write(str(sys.argv) + "\n") ftemp.write("t" + '\t' + "n_O" + '\t' + "r_CNT" + '\t' + "std_r" + '\t' + "min_x" + '\t' + "max_x" + '\t' + "min_y" + '\t' + "max_y" + '\t' + "min_z" + '\t' + "max_z" + '\t' + "l_NT" + '\t' + "replNum" + '\t' + "copyNum" + '\t' + "n_WAT" + '\t' + "remark" + '\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 first " + str(n_step) + " timesteps.") ### read mass from ff_file atominfo = dict() try: parse = ff_file.split(" ") except: nu.die( "Error occurred when reading the force field file.. Check your " + str(ff_file)) else: if not silent: print("Found " + str(len(parse)) + " Cerius2 Force Fields.") for i in parse: FF = dreiding.loadFF(i) temp_atominfo = dreiding.loadAtomTypes(FF) atominfo.update(temp_atominfo) ### extract aNos of CNT in the BGF file aNo_CNT = [] aNo_WAT_O = [] aNo_WAT_all = [] mass_CNT = [] for atom in myBGF.a: # Carbons in CNT or atoms in BNNT if "NT" in atom.rName: aNo_CNT.append(atom.aNo) ffType = string.strip(atom.ffType) try: aMass = atominfo[ffType]['MASS'] except: nu.die("Cannot read the atom type " + str(atom.ffType) + " in the data file.") mass_CNT.append(aMass) # 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: ### 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(' ') 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:] # load atom coordinates from chunk 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]) ### convert atom coordinates to lists CNT = [] WATER = [] for atom in myBGF.a: if "NT" in atom.rName: CNT.append([atom.x, atom.y, atom.z]) if "WAT" in atom.rName and "O" in atom.ffType: WATER.append([atom.x, atom.y, atom.z]) CNT = np.array(CNT) n_CNT = len(CNT) # CNT coordinates WATER = np.array(WATER) # Water coordinates WATERONLY = np.copy(WATER) boxsize = np.array(boxsize) ### 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 Mx, My, Mz = np.average(CNT, axis=0, weights=mass_CNT) # CoM of CNT COM = np.array([[Mx, My, Mz]]) CNT = CNT - COM + boxsize / 2.0 # move WATER = WATER - COM + boxsize / 2.0 ### apply PBC WATER = np.mod(WATER, boxsize) ### save coordinates to BGF before rotation myBGF2 = bgf.BgfFile() for index, i in enumerate(CNT): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index newatom.aName = 'C' + str(index) newatom.rName = 'CNT' newatom.ffType = 'C_' newatom.chain = 'A' newatom.rNo = 1 myBGF2.addAtom(newatom) for index, i in enumerate(WATER): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index + n_CNT newatom.aName = 'O' newatom.rName = 'WAT' newatom.ffType = 'OW' newatom.chain = 'O' newatom.rNo = 100 myBGF2.addAtom(newatom) myBGF2.REMARK.append('TIMESTEP ' + str(timestep)) myBGF2.PERIOD = "111" myBGF2.AXES = "ZYX" myBGF2.SGNAME = "P 1 1 1" myBGF2.CELLS = [-1, 1, -1, 1, -1, 1] myBGF2.CRYSTX = [boxsize[0], boxsize[1], boxsize[2], 90.0, 90.0, 90.0] myBGF2.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".bgf") ### move CM of CNT to origin CNT = CNT - boxsize / 2.0 WATER = WATER - boxsize / 2.0 ### how the CNT is lying across the periodic box? for atom in CNT: min_x_CNT, min_y_CNT, min_z_CNT = CNT.min(axis=0) max_x_CNT, max_y_CNT, max_z_CNT = CNT.max(axis=0) margin = 5.0 ### copy water molecules max_x_axis = int(round((max_x_CNT + margin) / boxsize[0])) min_x_axis = int(round((min_x_CNT - margin) / boxsize[0])) max_y_axis = int(round((max_y_CNT + margin) / boxsize[1])) min_y_axis = int(round((min_y_CNT - margin) / boxsize[1])) max_z_axis = int(round((max_z_CNT + margin) / boxsize[2])) min_z_axis = int(round((min_z_CNT - margin) / boxsize[2])) replNum = (min_x_axis, max_x_axis, min_y_axis, max_y_axis, min_z_axis, max_z_axis) copyNum = 0 remark = "" if watercopy: for x in range(min_x_axis, max_x_axis + 1): remark += "x: " if x != 0: WATER2 = np.copy(WATERONLY) dx = np.array([[boxsize[0] * x, 0, 0]]) WATER2 = WATER2 + dx WATER = np.concatenate((WATER, WATER2)) copyNum += 1 remark += str(x) + " " for y in range(min_y_axis, max_y_axis + 1): remark += "y: " if y != 0: WATER2 = np.copy(WATERONLY) dy = np.array([[0, boxsize[1] * y, 0]]) WATER2 = WATER2 + dy WATER = np.concatenate((WATER, WATER2)) copyNum += 1 remark += str(y) + " " for z in range(min_z_axis, max_z_axis + 1): remark += "z: " if z != 0: WATER2 = np.copy(WATERONLY) dz = np.array([[0, 0, boxsize[2] * z]]) WATER2 = WATER2 + dz WATER = np.concatenate((WATER, WATER2)) copyNum += 1 remark += str(z) + " " ''' ### WATER distribution check x_axis = np.linspace(WATER[:,0].min(), WATER[:,0].max(), 10) y_axis = np.linspace(WATER[:,1].min(), WATER[:,1].max(), 10) z_axis = np.linspace(WATER[:,2].min(), WATER[:,2].max(), 10) x_hist, _ = np.histogram(WATER[:,0], x_axis, normed=True) y_hist, _ = np.histogram(WATER[:,1], y_axis, normed=True) z_hist, _ = np.histogram(WATER[:,2], z_axis, normed=True) remark += " xdist: " for i in x_hist: remark += "{0:6.3f}".format(i) remark += " ydist: " for i in y_hist: remark += "{0:6.3f}".format(i) remark += " zdist: " for i in z_hist: remark += "{0:6.3f}".format(i) ''' ### MI of CNT calculation for atom in CNT: Ixx += (atom[1]**2 + atom[2]**2) / N_CNT Iyy += (atom[0]**2 + atom[2]**2) / N_CNT Izz += (atom[0]**2 + atom[1]**2) / N_CNT Ixy -= (atom[0] * atom[1]) / N_CNT Ixz -= (atom[0] * atom[2]) / N_CNT Iyz -= (atom[1] * atom[2]) / N_CNT I = np.array([[Ixx, Ixy, Ixz], [Ixy, Iyy, Iyz], [Ixz, Iyz, Izz]]) # the moment of inertia tensor eigval, eigvec = np.linalg.eig( I) # eigval[0] is the minimum among the values. U = np.matrix(eigvec) Ut = U.T ### box rotation for atom in CNT: v = np.matrix([atom[0], atom[1], atom[2]]).T Uv = Ut * v atom[0] = float(Uv[2]) atom[1] = float(Uv[1]) atom[2] = float(Uv[0]) # CNT rotation for atom in WATER: v = np.matrix([atom[0], atom[1], atom[2]]).T Uv = Ut * v atom[0] = float(Uv[2]) atom[1] = float(Uv[1]) atom[2] = float(Uv[0]) # water rotation ### save coordinates to BGF after rotation myBGF2 = bgf.BgfFile() for index, i in enumerate(CNT): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index newatom.aName = 'C' + str(index) newatom.rName = 'CNT' newatom.ffType = 'C_' newatom.chain = 'A' newatom.rNo = 1 myBGF2.addAtom(newatom) for index, i in enumerate(WATER): newatom = bgf.BgfAtom() newatom.x, newatom.y, newatom.z = i newatom.aNo = index + n_CNT newatom.aName = 'O' newatom.rName = 'WAT' newatom.ffType = 'OW' newatom.chain = 'O' newatom.rNo = 100 myBGF2.addAtom(newatom) myBGF2.REMARK.append('TIMESTEP ' + str(timestep)) myBGF2.PERIOD = "111" myBGF2.AXES = "ZYX" myBGF2.SGNAME = "P 1 1 1" myBGF2.CELLS = [-1, 1, -1, 1, -1, 1] myBGF2.CRYSTX = [boxsize[0], boxsize[1], boxsize[2], 90.0, 90.0, 90.0] myBGF2.saveBGF(temp_dir + bgf_file.split(".bgf")[0] + "." + str(timestep) + ".rot.bgf") ### CNT height _, _, min_z_CNT = CNT.min(axis=0) _, _, max_z_CNT = CNT.max(axis=0) height_CNT = max_z_CNT - min_z_CNT ### CNT radius x_CNT, y_CNT, z_CNT = np.mean(CNT, axis=0) x_std_CNT, y_std_CNT, z_std_CNT = np.std(CNT, axis=0) if x_std_CNT > 1.0 or y_std_CNT > 1.0: remark += "" ### radius of CNT l_r_CNT = [] for atom in CNT: l_r_CNT.append( math.sqrt((atom[0] - x_CNT)**2 + (atom[1] - y_CNT)**2)) r_CNT = np.mean(l_r_CNT) std_r_CNT = np.std(l_r_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 < r_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 WAT_in_CNT = [] for atom in WATER: dist_sq = (atom[0] - x_CNT)**2 + (atom[1] - y_CNT)**2 if min_z_CNT + margin <= atom[2] and atom[ 2] <= max_z_CNT - margin and dist_sq < r_CNT**2: WAT_in_CNT.append(atom) n_WAT_in_CNT = len(WAT_in_CNT) ''' ### WATER bad contact check: copy-failure-proof: NEED CORRECTION WAT1 = []; WAT2 = []; for index1, i in enumerate(WAT_in_CNT): for j in WATER[index1:]: WAT1.append(i); WAT2.append(j); WAT1 = np.array(WAT1); WAT2 = np.array(WAT2) min_dists = np.min(np.dstack(((WAT1 - WAT2) % boxsize, (WAT2 - WAT1) % boxsize)), axis = 2) dists = np.sqrt(np.sum(min_dists ** 2, axis = 1)) for d in dists: if d > 0 and d < 1.0: remark += "Bad contacts" + str(d) continue; ''' d = "{0:8.3f}" e = "{0:6.1f}" output = "{0:<10}".format(timestep) + str( n_WAT_in_CNT ) + ' | ' + d.format(r_CNT) + d.format(std_r_CNT) + ' | ' + e.format( boxsize[0] ) + e.format(boxsize[1]) + e.format(boxsize[2]) + ' | ' + e.format( min_x_CNT) + e.format(max_x_CNT) + e.format(min_y_CNT) + e.format( max_y_CNT) + e.format(min_z_CNT) + e.format( max_z_CNT) + ' | ' + e.format(height_CNT) + ' | ' + str( replNum) + '\t' + str(copyNum) + '\t' + str( len(WATER)) + '\t' + str(remark) + '\n' ftemp.write(output) 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 " + out_file + " ..Done.") return 1
def main(): if len(sys.argv) < 2: print usage sys.exit(0) head = bgf.BgfFile(sys.argv[1]) head_mon = bgf.BgfFile(sys.argv[2]) monomer = bgf.BgfFile(sys.argv[3]) tail_mon = bgf.BgfFile(sys.argv[4]) tail = bgf.BgfFile(sys.argv[5]) target_mw = float(sys.argv[6]) ff_file = sys.argv[7] # number of required monomers to make a PEGDE chain mw_head = bgftools.getMoleculeMass(head, ff_file) print("** Mw of Molecule head: " + "{0:5.3f}".format(mw_head)) mw_tail = bgftools.getMoleculeMass(tail, ff_file) print("** Mw of Molecule tail: " + "{0:5.3f}".format(mw_tail)) mw_monomer = bgftools.getMoleculeMass(monomer, ff_file) print("** Mw of Molecule monomer: " + "{0:5.3f}".format(mw_monomer)) print("** Requested Mw: " + str(target_mw)) # number of required monomers n_monomers = round((target_mw - mw_head - mw_tail) / mw_monomer) print("** Required number of monomers: " + str(int(n_monomers))) actual_mw = mw_head + mw_tail + mw_monomer * n_monomers print("** Actual Mw: " + "{0:5.3f}".format(actual_mw)) ### overall structure ### head -- head_mon -- monomer -- tail_mon -- tail ### connect blocks m1 = copy.deepcopy( head_mon) # start adding monomers from the head_near monomer for atom in m1.a: atom.rNo = 1 atom.rName = 'MON' print("* attaching head_monomer") n_monomers = int(n_monomers) ### monomer - monomer: 1H_T -- 2H_H for i in range(n_monomers - 1): # if the last monomer, attach tail_monomer # else prepare monomer 2 if i == n_monomers - 2: print("* attaching tail_monomer") m2 = copy.deepcopy(tail_mon) else: print("* attaching monomer " + str(i)) m2 = copy.deepcopy(monomer) # renumber residue numbers for atom in m2.a: atom.rNo = i + 2 atom.rName = 'MON' # move H_H of m2 to H_T of m1 position h_t = 0 h_h = 0 for atom in m1.a: if atom.ffType == "H_T" and atom.rNo == i + 1: h_t = atom for atom in m2.a: if atom.ffType == "H_H" and atom.rNo == i + 2: h_h = atom for atom in m2.a: atom.x += h_t.x atom.y += h_t.y atom.z += h_t.z # delete H_T in monomer m1.delAtom(m1.a2i[h_t.aNo]) m1.renumber() # delete H_H in monomer2 m2.delAtom(m2.a2i[h_h.aNo]) m2.renumber() # merge m1 = m1.merge(m2, True) m1.renumber() # find tag in the merged molecule atomH = bgf.BgfAtom() atomT = bgf.BgfAtom() for atom in m1.a: if 'T' in atom.chain and atom.rNo == i + 1: atomT = atom if 'H' in atom.chain and atom.rNo == i + 2: atomH = atom # update chain atomT.chain = "A" atomH.chain = "A" # connect m1.connect(m1.a2i[atomH.aNo], m1.a2i[atomT.aNo]) #m1.saveBGF('temp_monomer.bgf') ### head - monomer: H_EG -- H_H # head h1 = copy.deepcopy(head) for atom in h1.a: atom.rNo = 100 atom.rName = 'HED' h_eg = 0 h_h = 0 for atom in h1.a: if atom.ffType == "H_EG": h_eg = atom for atom in m1.a: if atom.ffType == "H_H": h_h = atom for atom in m1.a: atom.x += h_eg.x atom.y += h_eg.y atom.z += h_eg.z h1.delAtom(h1.a2i[h_eg.aNo]) h1.renumber() m1.delAtom(m1.a2i[h_h.aNo]) m1.renumber() h1 = h1.merge(m1, True) h1.renumber() atomH = bgf.BgfAtom() atomT = bgf.BgfAtom() for atom in h1.a: if 'T' in atom.chain and 'HED' in atom.rName: atomT = atom if 'H' in atom.chain and 'MON' in atom.rName: atomH = atom h1.connect(h1.a2i[atomT.aNo], h1.a2i[atomH.aNo]) #h1.saveBGF('temp_h-m.bgf') # monomer - tail: H_T -- H_EG t1 = copy.deepcopy(tail) for atom in t1.a: atom.rNo = 200 atom.rName = 'TAL' h_t = 0 h_eg = 0 for atom in h1.a: if atom.ffType == "H_T": h_t = atom for atom in t1.a: if atom.ffType == "H_EG": h_eg = atom for atom in t1.a: atom.x += h_t.x atom.y += h_t.y atom.z += h_t.z h1.delAtom(h1.a2i[h_t.aNo]) h1.renumber() t1.delAtom(t1.a2i[h_eg.aNo]) t1.renumber() h1 = h1.merge(t1, True) h1.renumber() atomH = bgf.BgfAtom() atomT = bgf.BgfAtom() for atom in h1.a: if 'T' in atom.chain and 'MON' in atom.rName: atomT = atom if 'H' in atom.chain and 'TAL' in atom.rName: atomH = atom h1.connect(h1.a2i[atomT.aNo], h1.a2i[atomH.aNo]) # adding remarks h1.REMARK.append("Polymer Generated at " + str(time.asctime(time.gmtime()))) h1.REMARK.append("head: " + sys.argv[1] + ", head_mon: " + sys.argv[2] + ", monomer: " + sys.argv[3] + ", tail_mon: " + sys.argv[4] + ", tail: " + sys.argv[5]) h1.REMARK.append("Target Mw: " + str(sys.argv[6]) + ", Actual Mw: " + "{0:5.3f}".format(actual_mw)) h1.REMARK.append("Number of monomers: " + str(n_monomers)) h1.REMARK.append("ff: " + sys.argv[7]) h1.saveBGF('generated_charge.bgf')
def addIons(bgf_file, out_file, region, number, silent=False): """ def addIons(): Write what this function does. Function Parameters: -b bgf_file A string of filename or BgfFile class. -o out_file A string of filename or BgfFile class. -n number -r region: "xlo xhi ylo yhi zlo zhi" """ # open BGF if isinstance(bgf_file, bgf.BgfFile): myBGF = bgf_file else: if not silent: print("opening bgf file.. " + str(bgf_file)) myBGF = bgf.BgfFile(bgf_file) boxsize = [myBGF.CRYSTX[0], myBGF.CRYSTX[1], myBGF.CRYSTX[2]] ### find the last HETATM aNo_lastHETAtom = 0 for i in myBGF.a: aNo = i.aNo if i.aTag == 1: if aNo > aNo_lastHETAtom: aNo_lastHETAtom = aNo for i in range(number): """ randx = random.uniform(0, boxsize[0]) randy = random.uniform(0, boxsize[1]) randz = random.uniform(0, boxsize[2]) """ randx = random.uniform(region[0], region[1]) randy = random.uniform(region[2], region[3]) randz = random.uniform(region[4], region[5]) # Na+ ion atom_Na = bgf.BgfAtom() atom_Na.x = randx atom_Na.y = randy atom_Na.z = randz atom_Na.aTag = 1 # HETATM atom_Na.ffType = "Na" atom_Na.rName = "ION" atom_Na.aName = "Na" atom_Na.charge = 1.00 atom_Na.rNo = 0 atom_Na.chain = "X" # Cl- ion atom_Cl = bgf.BgfAtom() atom_Cl.x = randx + 2 atom_Cl.y = randy + 2 atom_Cl.z = randz + 2 atom_Cl.aTag = 1 # HETATM atom_Cl.ffType = "Cl" atom_Cl.rName = "ION" atom_Cl.aName = "Cl" atom_Cl.charge = -1.00 atom_Cl.rNo = 0 atom_Cl.chain = "X" myBGF.addAtom(atom_Na, myBGF.a2i[aNo_lastHETAtom + 1]) myBGF.addAtom(atom_Cl, myBGF.a2i[aNo_lastHETAtom + 2]) myBGF.renumber() # save BGF if isinstance(out_file, str): if not silent: print("Saving information to " + out_file + " ..") myBGF.saveBGF(out_file) return 1 else: return myBGF
def protonate(bgf_file, out_file, log_file, silent=False): """ protonate(bgf_file, out_file, log_file, silent=False): Protonate (performs alkylation of primary amines) the given bgf file. To-do: """ # initialization # open bgffile myBGF = bgf.BgfFile(bgf_file) # find all inserted hydrogen N_index = [] for atom in myBGF.a: if "H+" in atom.aName: N_index.append(atom.aNo) N_number = len(N_index) # the number of all inserted hydrogen atoms if not silent: print(str(N_number) + " protonated sites are found.") # find the last HETATM (insertion position) last_hetatm_aNo = 0 for atom in myBGF.a: if atom.aTag != 1: last_hetatm_aNo = atom.aNo break # add Cl atoms if len(N_index) > 0: for index, aNo in enumerate(N_index): if not silent: print("*** Protonated Hydrogen " + str(aNo) + " ***") atom_H = myBGF.getAtom(aNo) # new Cl atom near atom_H atom_Cl = bgf.BgfAtom() atom_Cl.x = atom_H.x + 3 atom_Cl.y = atom_H.y + 3 atom_Cl.z = atom_H.z + 3 atom_Cl.aName = "Cl" atom_Cl.rName = "ION" atom_Cl.chain = "A" atom_Cl.aTag = 1 atom_Cl.rNo = 0 atom_Cl.ffType = "Cl" atom_Cl.aNo = last_hetatm_aNo atom_Cl.charge = -1.0000 myBGF.addAtom(atom_Cl, last_hetatm_aNo - 1) if not silent: print("Total charge: " + " : " + str(myBGF.charge())) # renumber myBGF.renumber() # save myBGF.REMARK.insert( 0, "Ion added by " + os.path.basename(sys.argv[0]) + " by " + os.environ["USER"] + " on " + time.asctime(time.gmtime())) myBGF.saveBGF(out_file) if not silent: print("saving file " + out_file) else: if not silent: print("No amine groups to be counter-ionized") sys.exit(0) if not silent: print("Done.")
def protonate(bgf_file, ff_file, probability, out_file, log_file, silent=False): """ protonate(bgf_file, ff_file, suffix, nodes, criteria, t, out_file): Protonate (performs alkylation of primary amines) the given bgf file. To-do: clean temp file management display appropriate messages server environments """ # initialization # open bgffile myBGF = bgf.BgfFile(bgf_file) # find all tertiary amines N_index = [] last_hetatm_aNo = 0 for atom in myBGF.a: if string.strip(atom.ffType) == "N_3": if "PRI" in atom.rName: N_index.append(atom.aNo) N_number = len(N_index) # the number of all tertiary amines if not silent: print(str(N_number) + " primary amines are found.") # find the last HETATM (insertion position) for atom in myBGF.a: if atom.aTag != 1: last_hetatm_aNo = atom.aNo break print(last_hetatm_aNo) # choose the primary amines randomly according to the probability if not probability == 1.0: N_choose = int(N_number * probability) N_index = random.sample(N_index, N_choose) if not silent: print(str(len(N_index)) + " primary amines will be protonated.") # add an hydrogen if len(N_index) > 0: for index, aNo in enumerate(N_index): if not silent: print("*** Primary amine " + str(aNo) + " ***") atom_Npri = myBGF.getAtom(aNo) # N from the N_index list # new proton on primary amine proton = bgf.BgfAtom() proton.x = atom_Npri.x + 1 proton.y = atom_Npri.y + 1 proton.z = atom_Npri.z + 1 proton.aName = "H+_" + str(index) proton.rName = "PRI" proton.chain = "A" proton.aTag = 1 proton.rNo = atom_Npri.rNo proton.ffType = "H_" proton.aNo = last_hetatm_aNo myBGF.addAtom(proton, last_hetatm_aNo - 1) proton = myBGF.getAtom( last_hetatm_aNo) # since (proton) != (proton add in myBGF) #proton.aName = "H++" myBGF.connect(myBGF.a2i[atom_Npri.aNo], myBGF.a2i[proton.aNo]) # connect # charge change: NH3 - CH2 - CH2 - ..... # 1. NH3 part N_CONECT_aNo = atom_Npri.CONECT N_CONECT_C_aNo = [] N_CONECT_H_aNo = [] for ano in N_CONECT_aNo: atom = myBGF.getAtom(ano) if "C" in atom.ffType: N_CONECT_C_aNo.append(atom.aNo) elif "H" in atom.ffType: N_CONECT_H_aNo.append(atom.aNo) else: nu.die(str(atom)) if len(N_CONECT_C_aNo) != 1: nu.die("Number of C atoms connected with primary amine " + str(atom_Npri.aNo) + " mismatch!") if len(N_CONECT_H_aNo) != 3: nu.die("Number of H atoms connected with primary amine " + str(atom_Npri.aNo) + " mismatch!") atom_C2 = myBGF.getAtom(N_CONECT_C_aNo[0]) atom_HN1 = myBGF.getAtom(N_CONECT_H_aNo[0]) atom_HN2 = myBGF.getAtom(N_CONECT_H_aNo[1]) atom_HN3 = myBGF.getAtom(N_CONECT_H_aNo[2]) # update charges old_NH3_charge = atom_Npri.charge + atom_HN1.charge + atom_HN2.charge + atom_HN3.charge atom_Npri.charge = -0.72540 atom_HN1.charge = 0.43330 atom_HN2.charge = 0.43330 atom_HN3.charge = 0.43330 new_NH3_charge = atom_Npri.charge + atom_HN1.charge + atom_HN2.charge + atom_HN3.charge NH3_charge_change = new_NH3_charge - old_NH3_charge if not silent: print("NH3 site charge change: " + str(atom_Npri.aNo) + " : " + str(NH3_charge_change)) # 2. first CH2 part C2_CONECT_aNo = atom_C2.CONECT C2_CONECT_C_aNo = [] C2_CONECT_H_aNo = [] for ano in C2_CONECT_aNo: atom = myBGF.getAtom(ano) if "H" in atom.ffType: C2_CONECT_H_aNo.append(atom.aNo) elif "C" in atom.ffType and ano != atom_C2.aNo: C2_CONECT_C_aNo.append(atom.aNo) if len(C2_CONECT_H_aNo) != 2: nu.die("Number of H atoms connected with primary amine " + str(atom_C2.aNo) + " mismatch!") if len(C2_CONECT_C_aNo) != 1: nu.die("Number of C atoms connected with primary amine " + str(atom_C2.aNo) + " mismatch!") atom_C3 = myBGF.getAtom(C2_CONECT_C_aNo[0]) atom_HC21 = myBGF.getAtom(C2_CONECT_H_aNo[0]) atom_HC22 = myBGF.getAtom(C2_CONECT_H_aNo[1]) old_CH2_charge = atom_C2.charge + atom_HC21.charge + atom_HC22.charge #if not silent: print((atom_C2.charge, atom_HC21.charge, atom_HC22.charge)) #if not silent: print("old CH2 site charge change: " + str(atom_Npri.aNo) + " : " + str(old_CH2_charge)) atom_C2.charge = -0.20790 atom_HC21.charge = 0.24090 atom_HC22.charge = 0.24090 new_CH2_charge = atom_C2.charge + atom_HC21.charge + atom_HC22.charge #if not silent: print("new CH2 site charge change: " + str(atom_Npri.aNo) + " : " + str(new_CH2_charge)) CH2_charge_change = new_CH2_charge - old_CH2_charge if not silent: print("CH2 site charge change: " + str(atom_Npri.aNo) + " : " + str(CH2_charge_change)) delta_charge = NH3_charge_change + CH2_charge_change if not silent: print("Primary amine site charge change: " + str(atom_Npri.aNo) + " : " + str(delta_charge)) # 3. second CH2 part old_C3_charge = atom_C3.charge if not silent: print("Old C3 charge: " + str(atom_C3.charge)) atom_C3.charge = atom_C3.charge + (1 - delta_charge) if not silent: print("New C3 charge: " + str(atom_C3.charge)) if not silent: print("Total charge: " + " : " + str(myBGF.charge())) # renumber myBGF.renumber() # save myBGF.REMARK.insert( 0, "Protonated by " + os.path.basename(sys.argv[0]) + " by " + os.environ["USER"] + " on " + time.asctime(time.gmtime())) myBGF.saveBGF(bgf_file[:-4] + "_protonated.bgf") if not silent: print("saving file " + bgf_file[:-4] + "_protonated.bgf") else: if not silent: print("No amine groups to be protonated") sys.exit(0) if not silent: print("Done.")