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 hook2(lattice): logger = getLogger() logger.info("Hook2: Show rings in Yaplot format.") # copied from svg_poly graph = nx.Graph(lattice.graph) #undirected cellmat = lattice.repcell.mat s = "" s += yp.Layer(2) s += yp.Color(0) for i, j in graph.edges(): pi, pj = lattice.reppositions[i], lattice.reppositions[j] d = pj - pi d -= np.floor(d + 0.5) s += yp.Line(pi @ cellmat, (pi + d) @ cellmat) for ring in cr.CountRings(graph, pos=lattice.reppositions).rings_iter( lattice.largestring): deltas = np.zeros((len(ring), 3)) d2 = np.zeros(3) for k, i in enumerate(ring): d = lattice.reppositions[i] - lattice.reppositions[ring[0]] d -= np.floor(d + 0.5) deltas[k] = d comofs = np.sum(deltas, axis=0) / len(ring) deltas -= comofs com = lattice.reppositions[ring[0]] + comofs com -= np.floor(com) # rel to abs com = np.dot(com, cellmat) deltas = np.dot(deltas, cellmat) s += face(com, deltas) print(s) logger.info("Hook2: end.")
def drawbox(origin, box, halfshift=True, diag=False): s = "" if halfshift: center = (box[0] + box[1] + box[2]) / 2 ori = origin - center else: ori = origin for v in (np.zeros(3), box[1], box[2], box[1] + box[2]): s += yp.Line(v + ori, v + ori + box[0]) for v in (np.zeros(3), box[0], box[2], box[0] + box[2]): s += yp.Line(v + ori, v + ori + box[1]) for v in (np.zeros(3), box[0], box[1], box[0] + box[1]): s += yp.Line(v + ori, v + ori + box[2]) if diag: s += yp.Line(ori, ori + box[0] + box[1] + box[2]) return s
def hook1(lattice): lattice.logger.info("Hook1: Draw the cell in Yaplot format.") s = yp.Layer(2) x, y, z = lattice.repcell.mat for p, q, r in ((x, y, z), (y, z, x), (z, x, y)): for a in (np.zeros(3), p, q, p + q): s += yp.Line(a, a + r) print(s, end="") lattice.logger.info("Hook1: end.")
def draw_cell(self): s = yp.Color(2) ex = np.array([1., 0., 0.]) ey = np.array([0., 1., 0.]) ez = np.array([0., 0., 1.]) x = np.dot(ex, self.cell) y = np.dot(ey, self.cell) z = np.dot(ez, self.cell) zero = np.zeros_like(x) for vx in (zero, x): for vy in (zero, y): s += yp.Line(vx + vy, vx + vy + z) for vx in (zero, x): for vz in (zero, z): s += yp.Line(vx + vz, vx + y + vz) for vz in (zero, z): for vy in (zero, y): s += yp.Line(vy + vz, x + vy + vz) return s
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 draw_edge(self, i, j): ci = self.coord[i] # 0..1 cj = self.coord[j] d = cj - ci d -= np.floor(d + 0.5) xi = np.dot(ci, self.cell) xj = np.dot(ci + d, self.cell) if self.has_edge(i, j): return yp.Color(4) + yp.ArrowType(2) + yp.Arrow(xi, xj) elif self.has_edge(j, i): return yp.Color(5) + yp.ArrowType(2) + yp.Arrow(xj, xi) else: return yp.Color(0) + yp.Line(xi, xj)
def yaplot(self): maxcir = 16 maxrad = 6 # 16x6=96 color variations s = "" for cir in range(maxcir): for rad in range(maxrad): angle = cir * 360 / maxcir hue = ((angle - 60 + 360) / 360) % 1.0 bri = rad / (maxrad - 1) sat = sin(angle * pi / 180)**2 logging.debug((angle, sat, bri)) r, g, b = colorsys.hsv_to_rgb(hue, sat, bri) n = cir * maxrad + rad + 3 s += yp.SetPalette(n, int(r * 255), int(g * 255), int(b * 255)) for pair, center, twist in self.iter(): if twist == 0: # not an appropriate pair continue a, b = pair d = self.relcoord[b] - self.relcoord[a] d -= np.floor(d + 0.5) apos = np.dot(self.relcoord[a], self.cell) bpos = apos + np.dot(d, self.cell) cosine = twist.real sine = twist.imag angle = atan2(sine, cosine) * 180 / pi if angle < 0: angle += 360 cir = int(angle * maxcir / 360 + 0.5) # rad is squared. rad = int(abs(twist)**2 * maxrad) if cir > maxcir - 1: cir -= maxcir if rad > maxrad - 1: rad = maxrad - 1 palette = cir * maxrad + rad + 3 # logging.info((abs(twist),rad,cir,palette)) s += yp.Color(palette) s += yp.Line(apos, bpos) s += "# angle {0} rad {1} cir {2} rad {3}\n".format( angle, abs(twist), hue, rad) return s
def draw_cell(voro_cell, box, kind=0): layer = kind + 2 if layer > 30: layer = 30 # draw frame s = yp.Layer(layer) s += yp.Color(0) origin = voro_cell['original'] voro_vertices = voro_cell['vertices'] voro_faces = voro_cell['faces'] g = voro_cell['graph'] for i, j in g.edges(): di = voro_vertices[i] - origin dj = voro_vertices[j] - origin s += yp.Line(origin + di * 0.9, origin + dj * 0.9) # draw faces s += yp.Color(kind + 10) for face in voro_faces: points = [] for point in face['vertices']: d = voro_vertices[point] - origin points.append(d * 0.89 + origin) s += yp.Polygon(points) return s
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 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)