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 poresize(bgf_file, out_file, grid=0.25, thresh=0.25, silent=False): """ def poresize(): Calculates pore sizes in the BGF molecule Function Parameters: bgf_file A string which contains a PEI information in a BGF format. (e.g. "file1.bgf file2.bgf file3.bgf ...") """ # initialize xyz = [] rvdw = dict() ubound = 10 lbound = 0 # open bgf myBGF = bgf.BgfFile(bgf_file) # read van der waals radii rvdw['H'] = 1.2 rvdw['C'] = 1.7 rvdw['N'] = 1.55 rvdw['O'] = 1.52 # copy positions: [ x y z vdw ] for atom in myBGF.a: atomtype = atom.ffType[:-1].strip("_") xyz.append( [float(atom.x), float(atom.y), float(atom.z), rvdw[atomtype]]) xyz = np.array(xyz) # get bgf size size = np.array(bgf.getBGFSize(myBGF)) np.around(size, decimals=1) # make grid grid_x = np.arange(size[0], size[1], grid) grid_y = np.arange(size[2], size[3], grid) grid_z = np.arange(size[4], size[5], grid) len_grid_x = len(grid_x) len_grid_y = len(grid_y) len_grid_z = len(grid_z) poresize = np.zeros((len_grid_x, len_grid_y, len_grid_z)) ix = 0 iy = 0 iz = 0 t1 = 0 t2 = 0 # for each grid for ix, x in enumerate(grid_x): t1 = time.time() for iy, y in enumerate(grid_y): for iz, z in enumerate(grid_z): ubound = 10 lbound = 0 minubound = 10 while ubound - lbound > thresh: test_r = random.uniform(lbound, ubound) flag = True for atom in xyz: value = (x - atom[0])**2 + (y - atom[1])**2 + ( z - atom[2])**2 - atom[3]**2 - test_r**2 if value < 0: flag = False if minubound > test_r: minubound = test_r if flag: lbound = test_r else: ubound = minubound poresize[ix, iy, iz] = test_r t2 = time.time() print( str(ix) + " out of " + str(len_grid_x) + "( elapsed time for the step: " + str(t2 - t1) + " sec)") # store them as a matrix scipy.io.savemat(out_file, {'m': poresize})
def poresize(bgf_file, out_file, grid=0.25, thresh=0.25, silent=False): """ def poresize(): Calculates pore sizes in the BGF molecule Function Parameters: bgf_file A string which contains a PEI information in a BGF format. (e.g. "file1.bgf file2.bgf file3.bgf ...") """ # initialize xyz = [] rvdw = dict() ubound = 10 lbound = 0 # open bgf myBGF = bgf.BgfFile(bgf_file) # read van der waals radii rvdw['H'] = 1.2 rvdw['C'] = 1.7 rvdw['N'] = 1.55 rvdw['O'] = 1.52 # copy positions: [ x y z vdw ] for atom in myBGF.a: atomtype = atom.ffType[:-1].strip("_") xyz.append( [float(atom.x), float(atom.y), float(atom.z), rvdw[atomtype]]) xyz = np.array(xyz) # get bgf size size = np.array(bgf.getBGFSize(myBGF)) np.around(size, decimals=1) # make grid grid_x = np.arange(size[0], size[1], grid) grid_y = np.arange(size[2], size[3], grid) grid_z = np.arange(size[4], size[5], grid) len_grid_x = len(grid_x) len_grid_y = len(grid_y) len_grid_z = len(grid_z) poresize = np.zeros((len_grid_x, len_grid_y, len_grid_z)) # for each grid for ix, x in enumerate(grid_x): print(str(ix) + " out of " + str(len_grid_x)) for iy, y in enumerate(grid_y): for iz, z in enumerate(grid_z): ubound = 10 lbound = 0 minubound = 10 while ubound - lbound > thresh: test_r = random.uniform(lbound, ubound) ### check the distance flag = True for atom in xyz: value = (x - atom[0])**2 + (y - atom[1])**2 + ( z - atom[2])**2 - atom[3]**2 - test_r**2 if value < 0: flag = False if minubound > test_r: minubound = test_r if flag: lbound = test_r else: ubound = minubound poresize[ix, iy, iz] = test_r # store them as a matrix with file(out_file, 'w') as outfile: for data in poresize: outfile.write("# new shot\n") np.savetxt(outfile, data, fmt='%8.2f')