def hook6(lattice): global nwateratoms lattice.logger.info("Hook6: Output water molecules in Yaplot format.") lattice.logger.info(" Total number of atoms: {0}".format( len(lattice.atoms))) # prepare the reverse dict waters = defaultdict(dict) for atom in lattice.atoms: resno, resname, atomname, position, order = atom if "O" in atomname: waters[order]["O"] = position elif "H" in atomname: if "H0" not in waters[order]: waters[order]["H0"] = position else: waters[order]["H1"] = position s = "" s += yp.Color(3) for order, water in waters.items(): O = water["O"] H0 = water["H0"] H1 = water["H1"] s += yp.Layer(4) s += yp.Color(3) s += yp.Size(0.03) s += yp.Circle(O) s += yp.Line(O, H0) s += yp.Line(O, H1) s += yp.Size(lattice.yaplot_size_H) s += yp.Circle(H0) s += yp.Circle(H1) s += yp.Color(2) s += yp.Layer(1) s += yp.Text(O, "{0}".format(order)) s += yp.Layer(3) s += yp.Color(4) s += yp.ArrowType(1) s += yp.Size(0.03) for i, j in lattice.spacegraph.edges(data=False): if i in waters and j in waters: # edge may connect to the dopant O = waters[j]["O"] H0 = waters[i]["H0"] H1 = waters[i]["H1"] d0 = H0 - O d1 = H1 - O rr0 = np.dot(d0, d0) rr1 = np.dot(d1, d1) if rr0 < rr1 and rr0 < 0.245**2: s += yp.Arrow(H0, O) if rr1 < rr0 and rr1 < 0.245**2: s += yp.Arrow(H1, O) print(s, end="") nwateratoms = len(lattice.atoms) lattice.logger.info("Hook6: end.")
def to_yaplot(cellmat, rpos, anions, cations, G, cation="N", anion="F"): """ cellmat: セル行列(後置記法) rpos: 分子のセル内相対位置 anions: アニオン番号 cations: カチオン番号 G: 水素結合ネットワーク """ # 水分子の原子位置 water = tip4picesites() s = "" for mol in G: if mol not in anions and mol not in cations: # genuine water molecule. rO = rpos[mol] H1, H2 = G[mol] rH1 = rpos[H1] - rO rH1 -= np.floor(rH1 + 0.5) rH2 = rpos[H2] - rO rH2 -= np.floor(rH2 + 0.5) # 実座標 (angstrom) pO = rO @ cellmat pH1 = rH1 @ cellmat pH2 = rH2 @ cellmat ey = pH1 - pH2 ez = pH1 + pH2 ex = np.cross(ey, ez) # 分子内座標方向の単位ベクトル ex /= np.linalg.norm(ex) ey /= np.linalg.norm(ey) ez /= np.linalg.norm(ez) # 回転行列 R = np.array([ex, ey, ez]) # 水分子の原子位置 intra = water @ R + pO s += draw_water(intra) s += yp.Layer(3) s += yp.Size(0.5) s += yp.Color(6) for mol in G: if mol in anions: pos = rpos[mol] @ cellmat s += yp.Circle(pos) s += yp.Size(0.3) s += yp.Color(7) for mol in G: if mol in cations: pos = rpos[mol] @ cellmat s += yp.Circle(pos) s += yp.NewPage() return s
def hook7(lattice): global nwateratoms lattice.logger.info("Hook7: Output water molecules in Yaplot format.") lattice.logger.info(" Total number of atoms: {0}".format( len(lattice.atoms))) gatoms = lattice.atoms[nwateratoms:] palettes = dict() s = "" s += yp.Layer(4) s += yp.ArrowType(1) H = [] O = "" for atom in gatoms: resno, resname, atomname, position, order = atom if atomname in palettes: pal = palettes[atomname] else: pal = 4 + len(palettes) palettes[atomname] = pal s += yp.Color(pal) s += yp.Size(0.04) s += yp.Circle(position) s = '#' + "\n#".join(lattice.doc) + "\n" + s print(s) lattice.logger.info("Hook7: end.")
def draw_water(water, povray=False): s = "" if povray: s += pov.Sphere(water[0], r="RH", material="MATH") s += pov.Sphere(water[1], r="RH", material="MATH") s += pov.Sphere(water[2], r="RO", material="MATO") s += pov.Cylinder(water[0], water[2], r="ROH", material="MATOH") s += pov.Cylinder(water[1], water[2], r="ROH", material="MATOH") else: s += yp.Layer(1) s += yp.Color(5) s += yp.Size(0.2) s += yp.Circle(water[0]) s += yp.Circle(water[1]) s += yp.Color(4) s += yp.Size(0.4) s += yp.Circle(water[2]) s += yp.Color(2) d0 = water[0] - water[2] L0 = np.linalg.norm(d0) s += yp.Line(water[2] + d0 / L0 * 0.4, water[0] - d0 / L0 * 0.2) d1 = water[1] - water[2] L1 = np.linalg.norm(d1) s += yp.Line(water[2] + d1 / L1 * 0.4, water[1] - d1 / L1 * 0.2) # draw a tetrahedron y = water[1] - water[0] z = (water[1] + water[0]) / 2 - water[2] x = np.cross(y, z) x /= np.linalg.norm(x) y /= np.linalg.norm(y) z /= np.linalg.norm(z) com = (water[1] + water[0] + water[2] * 16) / 18 R = 2.76 / 2 a = y * (2 / 3)**0.5 + z * (1 / 3)**0.5 b = -y * (2 / 3)**0.5 + z * (1 / 3)**0.5 c = x * (2 / 3)**0.5 - z * (1 / 3)**0.5 d = -x * (2 / 3)**0.5 - z * (1 / 3)**0.5 s += yp.Layer(2) for e, f in it.combinations((a, b, c, d), 2): s += yp.Line(com + e * R, com + f * R) return s
def main(): import sys groname, twiname = sys.argv[1:3] with open(twiname) as twifile: with open(groname) as grofile: while True: if groname[-4:] == ".pdb": gr = pdb.PDB(grofile, "O", "H", resname="WAT") else: # assume it is gromacs gr = gro.Gromacs(grofile, "Ow", "Hw", "Mw") btw = btwc.load_BTWC(twifile) if btw is None or gr is None: break celli = np.linalg.inv(gr.cell) # relative coord rs = np.array([np.dot(x, celli) for x in gr.solutes]) ro = np.array([np.dot(x, celli) for x in gr.waters]) print(len(rs)) print(len(ro)) grid = pl.determine_grid(gr.cell, 0.245) shell1 = np.vstack( pl.pairs_fine_hetero(rs, ro, 0.4, gr.cell, grid, distance=False)) # some solute atoms are isolated from water. shell1s = set(shell1[:, 0]) shell1w = set(shell1[:, 1]) #show all bonds in yaplot s = "" for i in range(-10, 0): s += yap.SetPalette(i + 10 + 3, 255 * (-i) // 10, 0, 0) for i in range(11): s += yap.SetPalette(i + 10 + 3, 0, 0, 255 * i // 10) for b in btw: i, j = b[0] if i in shell1w or j in shell1w: s += yap.Layer(1) else: s += yap.Layer(2) r = abs(b[2]) sine = b[2].imag s += yap.Size(r) s += yap.Color(int(sine * 10) + 10 + 3) s += yap.Circle(b[1]) print(s)
def hook2(lattice): global nwateratoms if lattice.yaplot_size_H > 0: return lattice.logger.info( "Hook2: Output CoM of water molecules in Yaplot format.") # prepare the reverse dict waters = defaultdict(dict) pos = lattice.reppositions @ lattice.repcell.mat s = "" for p in pos: s += yp.Layer(4) s += yp.Color(3) s += yp.Size(0.03) s += yp.Circle(p) print(s, end="") lattice.logger.info("Hook2: end.") return True
def main(): basicConfig(level=INFO, format="%(levelname)s %(message)s") logger = getLogger() every = 1 maxval = 1.0 adjdens = False while sys.argv[1][0] == "-": if sys.argv[1] == "-e": sys.argv.pop(1) every = int(sys.argv[2]) sys.argv.pop(1) elif sys.argv[1] == "-v": maxval = float(sys.argv[2]) sys.argv.pop(1) sys.argv.pop(1) elif sys.argv[1] == "-a": adjdens = True sys.argv.pop(1) else: usage() gcell, gatoms = LoadGRO(open(sys.argv[1])) # in AA, in AA ucell, uatoms = LoadGRO(open(sys.argv[2])) # in AA dens0 = gatoms.shape[0] / np.linalg.det(gcell) dens1 = uatoms.shape[0] / np.linalg.det(ucell) ratio = (dens1 / dens0)**(1. / 3.) if adjdens: logger.info(f"Scaling ratio: {ratio}") ucell *= ratio uatoms *= ratio gcelli = np.linalg.inv(gcell) ucelli = np.linalg.inv(ucell) mode = "" if len(sys.argv) > 3: mode = sys.argv[3] s = "" s += yp.Color(2) s += yp.Layer(1) origin = np.zeros(3) s += drawbox(origin, gcell, halfshift=False) #in absolute coord # unitatoms = np.dot(unitatoms, ucell) #s += unitatoms) #s = "" nline = 0 matched = set() palette = dict() while True: line = sys.stdin.readline() if len(line) == 0: break nline += 1 #parse the line cols = line.split() if len(cols) < 13: break # 2018-4-9 New output format of matcher.c msd = float(cols[0]) gcenter = gatoms[int(cols[1])].copy() #atom at the matching center gcenter -= np.floor(gcenter @ gcelli) @ gcell ucenter = int(cols[2]) rotmat = np.array([float(x) for x in cols[3:12]]).reshape((3, 3)) N = int(cols[12]) if len(cols) < 13 + N: break irot = np.linalg.inv(rotmat) members = [int(x) for x in cols[13:N + 13]] #draw matched box # roll the unit cell to center (abs) rel = uatoms - uatoms[ucenter] rel -= np.floor(rel @ ucelli + 0.5) @ ucell # rel to abs Slid = rel # rotate box Rotucell = ucell @ rotmat # Boxslide = -uatoms[ucenter] @ rotmat + gcenter # rotate atoms in the unit cell Slidunit = (Slid @ rotmat) + gcenter #s += yp.Color(3) if mode == "R": color = direction2color(rotmat[0] + rotmat[1] + rotmat[2]) elif mode == "T": color = direction2color(rotmat[2]) else: color = (0, 3, 0) #green if color not in palette: palette[color] = len(palette) + 6 s += yp.SetPalette(palette[color], color[0] * 255 // 3, color[1] * 255 // 3, color[2] * 255 // 3) if msd < maxval: matched |= set(members) if every != 0 and nline % every == 0 and msd < maxval: s += yp.Color(palette[color]) # matched box s += yp.Layer(4) s += drawbox(gcenter, Rotucell, halfshift=True, diag=(mode == "R")) # s += yp.Layer(2) # # unit cell # s += drawbox(Boxslide,Rotucell,halfshift=True) s += yp.Layer(2) #s += drawbox2(Boxslide,Rotucell) s += yp.Layer(5) s += yp.Size(0.3) s += yp.Color(5) s += drawatoms(Slidunit) for i in range(len(Slidunit)): g = gatoms[members[i]] d = Slidunit[i] - gatoms[members[i]] d -= np.floor(d @ gcelli + 0.5) @ gcell s += yp.Line(g, g + d) # 変位ベクトルはどうやってもうまくいかないので、やめる。 s += yp.Size(0.3) s += yp.Color(4) s += yp.Layer(3) s += drawatoms(gatoms, members=matched) print(s) # end of frame
def depolarize(spaceicegraph, cell, draw=None): """ Find a farthest atom (apsis) from the given atom, and make the shortest paths between them. It works much better than depolarize() """ logger = logging.getLogger() #logger.debug(" isZ4: {0}".format(spaceicegraph.isZ4())) #logger.debug(" defects: {0}".format(spaceicegraph.bernal_fowler_defects())) spaceicegraph.vector_check() s = "" # for yaplot # TSL # defect-defect chains defects = [] for node in spaceicegraph.nodes(): if spaceicegraph.degree(node) != 4: assert spaceicegraph.degree(node) < 4 defects.append(node) logger.info(" Non Z4: {0}".format(defects)) if len(defects) > 0: reject_count = 10 while reject_count > 0: net_polar = spaceicegraph.net_polarization() if np.dot(net_polar, net_polar) < 0.05**2: break # without problem while True: orig = defects[random.randint(0, len(defects) - 1)] if spaceicegraph.out_degree(orig) == 2: break while True: dest = defects[random.randint(0, len(defects) - 1)] if spaceicegraph.in_degree(dest) == 2: break path = shortest_path(spaceicegraph, orig, [ dest, ]) if path is None: continue logger.debug(" Dipole moment = {0}".format( spaceicegraph.dipole_moment(path))) new_net_polar = net_polar - spaceicegraph.dipole_moment(path) * 2 if np.linalg.norm(new_net_polar) < np.linalg.norm(net_polar): if draw is not None: s += yp.Size(0.03) s += draw.draw_cell() s += draw.draw_path(path) s += yp.NewPage() spaceicegraph.invert_path(path) net_polar = new_net_polar logger.info( " Net polarization: [{0:.2f} {1:.2f} {2:.2f}]".format( *net_polar)) reject_count = 10 else: logger.debug(" Reject inversion") reject_count -= 1 while True: net_polar = spaceicegraph.net_polarization() logger.info( " Net polarization: [{0:.2f} {1:.2f} {2:.2f}]".format(*net_polar)) if np.dot(net_polar, net_polar) < 0.2**2: break # without problem if -1 <= net_polar[0] <= 1 and -1 <= net_polar[ 1] <= 1 and -1 <= net_polar[2] <= 1: logger.info(" Gave up eliminating the polarization. (2)") break if net_polar[0] > 1.0: logger.debug("Depolarize +X") axis = np.array([+1.0, 0.0, 0.0]) elif net_polar[0] < -1.0: logger.debug("Depolarize -X") axis = np.array([-1.0, 0.0, 0.0]) elif net_polar[1] > 1.0: logger.debug("Depolarize +Y") axis = np.array([0.0, +1.0, 0.0]) elif net_polar[1] < -1.0: logger.debug("Depolarize -Y") axis = np.array([0.0, -1.0, 0.0]) elif net_polar[2] > 1.0: logger.debug("Depolarize +Z") axis = np.array([0.0, 0.0, +1.0]) elif net_polar[2] < -1.0: logger.debug("Depolarize -Z") axis = np.array([0.0, 0.0, -1.0]) cycle = traversing_cycle(spaceicegraph, cell, axis, draw) if cycle is not None: edges = [(cycle[i], cycle[i + 1]) for i in range(len(cycle) - 1)] if len(edges) != len(set(edges)): logger.debug("The cycle is entangled.") else: if draw is not None: s += yp.Size(0.03) s += draw.draw_cell() s += draw.draw_path(cycle) s += yp.NewPage() spaceicegraph.invert_path(cycle) spaceicegraph.vector_check() #logger.debug("isZ4: {0}".format(spaceicegraph.isZ4())) #logger.debug("defects: {0}".format(spaceicegraph.bernal_fowler_defects())) return s
def main(): gro = open(sys.argv[1]) box, atoms = LoadGRO(gro) ratoms = atoms/box cellmat = np.diag(box) page1 = "" page2 = "" page3 = "" page4 = "" page1 += yp.Size(0.05) grid = None while True: line = sys.stdin.readline() #expect *.smatch result of slide-matcher2 if len(line) == 0: break cols = line.split() if len(cols)<7: break # broken line; maybe end of the file. i,j = [int(x) for x in cols[:2]] rad, dx,dy,dz, rmsd = [float(x) for x in cols[2:]] if grid is None: grid = pairlist.determine_grid(cellmat, rad) lastrad = rad p,q,r = pairlist.pairs_fine(ratoms, rad, cellmat, grid, distance=True, raw=True) g = nx.Graph() for k,pq in enumerate(zip(p,q)): p,q = pq g.add_edge(p,q,length=r[k]) else: assert lastrad == rad d = np.array([dx,dy,dz]) if rmsd < 0.09: # 0.09 for hyper ice T # page 1: displacement vectors page1 += yp.Line(atoms[i], atoms[i]+d) page1 += yp.Circle(atoms[j]) # pages 2: displacement vectors (centered) page2 += yp.Size(0.05) page2 += yp.Line(np.zeros(3), d) page2 += yp.Circle(d) page2 += yp.Text(d, "{0} {1}".format(i,j)) # page 3..: matching s = "" s += yp.Size(0.05) s += yp.Layer(1) s += yp.Color(3) for ni in g[i]: s += yp.Circle(atoms[ni]) s += yp.Layer(2) s += yp.Color(4) for nj in g[j]: s += yp.Circle(atoms[nj]-atoms[j]+atoms[i]) page3 += s s = "" s += yp.Size(0.05) s += yp.Layer(1) s += yp.Color(3) for ni in g[i]: s += yp.Circle(atoms[ni]-atoms[i]) s += yp.Layer(2) s += yp.Color(4) for nj in g[j]: s += yp.Circle(atoms[nj]-atoms[j]) page4 += s page4 += yp.NewPage() print(page1) print(page2) print(page3) print(page4)