Ejemplo n.º 1
0
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.")
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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.")
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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)