Exemple #1
0
def toWater(coord, cell):
    logger = logging.getLogger()
    dmin = shortest_distance(coord, cell) * 1.4
    grid = pl.determine_grid(cell, dmin)
    pairs = pl.pairs_fine(coord, dmin, cell, grid, distance=False)
    for vtet, dtet in tetrahedra(pairs, dmin, coord, cell):
        p = dtet[0] + (dtet[1] + dtet[2] + dtet[3]) / 4
        p -= np.floor(p)
        yield p
def toWater(coord, cell, tolerance=1.4):
    """
    cell: cell matrix (first row == a)
    coord: relative coord of the cage position
    """
    logger = logging.getLogger()
    dmin = shortest_distance(coord, cell) * tolerance
    grid = pl.determine_grid(cell, dmin)
    pairs = pl.pairs_fine(coord, dmin, cell, grid, distance=False)
    for vtet, dtet in tetrahedra(pairs, dmin, coord, cell):
        p = dtet[0] + (dtet[1] + dtet[2] + dtet[3]) / 4
        p -= np.floor(p)
        yield p
Exemple #3
0
    def __init__(
            self,
            lat,
            argv,
            density=0,
            rep=(1, 1, 1),
            cations=dict(),
            anions=dict(),
            spot_guests=dict(),
            spot_groups=dict(),
            asis=False,
    ):

        self.logger = getLogger()
        self.rep = rep
        self.asis = asis
        self.cations = cations
        self.anions = anions
        self.spot_guests = spot_guests
        self.spot_groups = spot_groups
        # Show the document of the module

        try:
            self.doc = lat.__doc__.splitlines()
        except BaseException:
            self.doc = []

        self.doc.append("")
        self.doc.append("Command line: {0}".format(" ".join(argv)))

        for line in self.doc:
            self.logger.info("  " + line)
        # ================================================================
        # rotmatrices (analice)
        #
        try:
            self.rotmatrices = lat.rotmat
        except BaseException:
            self.logger.info("No rotmatrices in lattice")
            self.rotmatrices = None
        # ================================================================
        # waters: positions of water molecules
        #
        self.waters = put_in_array(lat.waters)
        self.logger.debug("Waters: {0}".format(len(self.waters)))
        self.waters = self.waters.reshape((self.waters.size // 3, 3))

        # ================================================================
        # cell: cell dimension
        #   see parse_cell for syntax.
        #
        self.cell = Cell(lat.cell)

        # ================================================================
        # coord: "relative" or "absolute"
        #   Inside genice, molecular positions are always treated as "relative"
        #
        if lat.coord == "absolute":
            self.waters = self.cell.abs2rel(self.waters)

        self.waters = np.array([w - np.floor(w) for w in self.waters])

        # ================================================================
        # pairs: specify the pairs of molecules that are connected.
        #   Bond orientation will be shuffled later
        #   unless it is "fixed".
        #
        self.pairs = None

        try:
            self.pairs = parse_pairs(lat.pairs)
        except AttributeError:
            self.logger.info("HB connectivity is not defined.")

        # ================================================================
        # bondlen: specify the bond length threshold.
        #   This is used when "pairs" are not specified.
        #   It is applied to the original positions of molecules (before density setting).
        #
        nmol = self.waters.shape[0]  # nmol in a unit cell
        volume = self.cell.volume()  # volume of a unit cell in nm**3
        self.bondlen = None

        try:
            self.bondlen = lat.bondlen
            self.logger.info("Bond length (specified): {0}".format(
                self.bondlen))
        except AttributeError:
            self.logger.debug("  Estimating the bond threshold length...")
            # assume that the particles distribute homogeneously.
            rc = (volume / nmol)**(1 / 3) * 1.5
            grid = pl.determine_grid(self.cell.mat, rc)
            p = pl.pairs_fine(self.waters,
                              rc,
                              self.cell.mat,
                              grid,
                              distance=False)
            self.bondlen = 1.1 * shortest_distance(
                self.waters, self.cell, pairs=p)
            self.logger.info("Bond length (estim.): {0}".format(self.bondlen))

        # Set density
        mass = 18  # water
        NB = 6.022e23
        density0 = mass * nmol / (NB * volume * 1e-21)

        if density <= 0:
            try:
                self.density = lat.density
            except AttributeError:
                self.logger.info(
                    "Density is not specified. Assume the density from lattice."
                )
                dmin = shortest_distance(self.waters, self.cell)
                self.logger.info(
                    "Closest pair distance: {0} (should be around 0.276 nm)".
                    format(dmin))
                self.density = density0 / (0.276 / dmin)**3
                # self.density = density0
        else:
            self.density = density

        self.logger.info("Target Density: {0}".format(self.density))
        self.logger.info("Original Density: {0}".format(density0))

        # scale the cell according to the (specified) density
        ratio = (density0 / self.density)**(1.0 / 3.0)
        self.cell.scale(ratio)

        if self.bondlen is not None:
            self.bondlen *= ratio
        self.logger.info("Bond length (scaled, nm): {0}".format(self.bondlen))

        # ================================================================
        # double_network: True or False
        #   This is a special option for ices VI and VII that have
        #   interpenetrating double network.
        #   GenIce's fast depolarization algorithm fails in some case.
        #
        try:
            self.double_network = lat.double_network
        except AttributeError:
            self.double_network = False

        # ================================================================
        # cages: positions of the centers of cages
        #   In fractional coordinate.
        #
        self.cagepos = None
        self.cagetype = None

        if "cages" in lat.__dict__:
            self.cagepos, self.cagetype = parse_cages(lat.cages)
            self.logger.warn(
                "Use of 'cages' in a lattice-plugin is deprecated.")
        elif "cagepos" in lat.__dict__:
            # pre-parsed data
            self.cagepos, self.cagetype = np.array(lat.cagepos), lat.cagetype

        # ================================================================
        # fixed: specify the bonds whose directions are fixed.
        #   you can specify them in pairs at a time.
        #   You can also leave it undefined.
        #
        self.fixed = []
        try:
            self.fixed = parse_pairs(lat.fixed)
            self.logger.info("Orientations of some edges are fixed.")
        except AttributeError:
            pass

        if "dopeIonsToUnitCell" in lat.__dict__:
            self.dopeIonsToUnitCell = lat.dopeIonsToUnitCell
        else:
            self.dopeIonsToUnitCell = None
        self.dopants = set()

        # if asis, make pairs to be fixed.
        if self.asis and len(self.fixed) == 0:
            self.fixed = self.pairs

        # filled cages
        self.filled_cages = set()

        # groups info
        self.groups = defaultdict(dict)

        # groups for the semi-guest
        # experimental; there are many variation of semi-guest inclusion.
        self.groups_placer = {
            "Bu-": butyl,
            "Butyl-": butyl,
            "Pentyl-": pentyl,
            "Propyl-": propyl,
            "2,2-dimethylpropyl-": _2_2_dimethylpropyl,
            "2,3-dimethylbutyl-": _2_3_dimethylbutyl,
            "3,3-dimethylbutyl-": _3_3_dimethylbutyl,
            "3-methylbutyl-": _3_methylbutyl,
            "Ethyl-": ethyl
        }
Exemple #4
0
    def prepare_random_graph(self, fixed):

        if self.pairs is None:
            self.logger.info("  Pairs are not given explicitly.")
            self.logger.info(
                "  Estimating the bonds according to the pair distances.")

            self.logger.debug("Bondlen: {0}".format(self.bondlen))
            # make bonded pairs according to the pair distance.
            # make before replicating them.
            grid = pl.determine_grid(self.cell.mat, self.bondlen)
            assert np.product(
                grid
            ) > 0, "Too thin unit cell. Consider use of --rep option if the cell was made by cif2ice."
            self.pairs = pl.pairs_fine(self.waters,
                                       self.bondlen,
                                       self.cell.mat,
                                       grid,
                                       distance=False)

            # self.pairs = [v for v in zip(j0,j1)]
            # Check using a simpler algorithm.
            # Do not use it for normal debug because it is too slow
            if False:  # self.logger.level <= logging.DEBUG:
                pairs1 = self.pairs
                pairs2 = [
                    v for v in pl.pairs_crude(self.waters,
                                              self.bondlen,
                                              self.cell.mat,
                                              distance=False)
                ]
                self.logger.debug("pairs1: {0}".format(len(pairs1)))
                self.logger.debug("pairs2: {0}".format(len(pairs2)))
                for pair in pairs1:
                    i, j = pair
                    assert (i, j) in pairs2 or (j, i) in pairs2
                for pair in pairs2:
                    i, j = pair
                    assert (i, j) in pairs1 or (j, i) in pairs1

        graph = dg.IceGraph()
        if fixed is not None:
            for i, j in fixed:
                graph.add_edge(i, j, fixed=True)

        # Fixed pairs are default.
        for pair in self.pairs:
            i, j = pair

            if graph.has_edge(i, j) or graph.has_edge(j, i):
                pass
            else:
                if random.randint(0, 1) == 0:
                    graph.add_edge(i, j, fixed=False)
                else:
                    graph.add_edge(j, i, fixed=False)

        self.logger.info("  Number of water nodes: {0}".format(
            graph.number_of_nodes()))

        return graph
Exemple #5
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)
def hook1(lattice):
    lattice.logger.info("Hook1: Output sidewalls of water nanotubes in dtc-like ice in yaplot format.")
    cellmat = lattice.repcell.mat
    zoom = 100


    axes = np.array([(1/8, 1/4), (5/8, 1/4), (3/8, 3/4), (7/8, 3/4)])
    # max distance from the axis to the water monolayer
    maxd = cellmat[0,0] / 4
    radius = maxd - 0.276/2 # approx. radius of the water monolayer
    plusd = maxd + 0.276    # second shell

    grid = pl.determine_grid(cellmat, 0.3)
    pairs = [(i,j) for i,j in pl.pairs_fine(lattice.reppositions, 0.3, cellmat, grid, distance=False)]
    logger.debug(("PAIRS",len(pairs),cellmat,grid))
    sx, sy = int(cellmat[2,2]*zoom),int(4*7*radius*zoom)
    size = (sx//4*4, sy//4*4)
    image = Image.new("RGB", size, '#fff')
    draw  = ImageDraw.Draw(image, "RGBA")

    for j, axis in enumerate(axes):
        dots = dict()
        dots2 = dict()
        for i, rpos in enumerate(lattice.reppositions):
            rd = np.zeros(3)
            rd[:2] = rpos[:2] - axis
            rd -= np.floor(rd+0.5)
            D = rd @ cellmat
            if D@D < maxd**2:
                a = atan2(D[1], D[0])+3.5
                z = (rpos @ cellmat)[2]
                c = a*radius
                dot = np.array([z,c+j*7*radius])
                #atom = rpos@cellmat
                dots[i] = dot
            elif D@D < plusd**2:
                a = atan2(D[1], D[0])+3.5
                z = (rpos @ cellmat)[2]
                c = a*radius
                dot = np.array([z,c+j*7*radius])
                #atom = rpos@cellmat
                dots2[i] = dot
        alldots = {**dots, **dots2}
        for p in dots2:
            r = 0.04
            tl = dots2[p] - r
            br = dots2[p] + r
            tl *= zoom
            br *= zoom
            draw.ellipse([int(x) for x in [tl[0], tl[1], br[0], br[1]]], fill='#f00')
        for p,q in pairs:
            if p in alldots and q in alldots and (p in dots2 or q in dots2):
                pd = alldots[p] * zoom
                qd = alldots[q] * zoom
                D = pd-qd
                if D@D < zoom**2:
                    draw.line([int(x) for x in [pd[0], pd[1], qd[0], qd[1]]], fill='#f00', width=2)
        for p in dots:
            r = 0.05
            tl = dots[p] - r
            br = dots[p] + r
            tl *= zoom
            br *= zoom
            draw.ellipse([int(x) for x in [tl[0], tl[1], br[0], br[1]]], fill='#000')
        for p,q in pairs:
            if p in dots and q in dots:
                pd = dots[p] * zoom
                qd = dots[q] * zoom
                D = pd-qd
                if D@D < zoom**2:
                    draw.line([int(x) for x in [pd[0], pd[1], qd[0], qd[1]]], fill='#000', width=3)
    imgByteArr = io.BytesIO()
    tn_image = image.resize((image.width//2, image.height//2), Image.LANCZOS)
    tn_image.save(imgByteArr, format='PNG')
    imgByteArr = imgByteArr.getvalue()
    sys.stdout.buffer.write(imgByteArr)
    lattice.logger.info("Hook1: end.")
Exemple #7
0
def hook7(lattice):
    global options
    logger = getLogger()
    atomtypes = options["atomtypes"]

    logger.info("Hook7: Output radial distribution functions.")
    logger.info("  Total number of atoms: {0}".format(len(lattice.atoms)))
    binw = 0.003
    nbin = int(options["range"] / binw)
    cellmat = lattice.repcell.mat
    rpos = defaultdict(list)
    for atom in lattice.atoms:
        resno, resname, atomname, position, order = atom
        alias = atomname
        if len(atomtypes):
            if atomname in atomtypes:
                alias = atomtypes[atomname]
            else:
                continue
        rpos[alias].append(lattice.repcell.abs2rel(position))
    rdf = []
    rdfname = []
    volume = np.linalg.det(lattice.repcell.mat)
    grid = pl.determine_grid(cellmat, binw * nbin)
    logger.info("  {0}".format(rpos.keys()))
    for atomname in rpos:
        ra = rpos[atomname] = np.array(rpos[atomname])
        na = ra.shape[0]
        logger.info("  Pair {0}-{0}".format(atomname))
        i, j, delta = pl.pairs_fine(ra,
                                    binw * nbin,
                                    cellmat,
                                    grid,
                                    distance=True,
                                    raw=True)
        delta = np.floor(delta / binw)
        hist = dict(zip(*np.unique(delta, return_counts=True)))
        rdfname.append((atomname, atomname))
        rdf.append(hist2rdf(hist, volume, (na, ), binw, nbin))
    for a, b in it.combinations(rpos, 2):
        ra = rpos[a]
        rb = rpos[b]
        na = ra.shape[0]
        nb = rb.shape[0]
        logger.info("  Pair {0}-{1}".format(a, b))
        i, j, delta = pl.pairs_fine_hetero(ra,
                                           rb,
                                           binw * nbin,
                                           cellmat,
                                           grid,
                                           distance=True,
                                           raw=True)
        delta = np.floor(delta / binw)
        hist = dict(zip(*np.unique(delta, return_counts=True)))
        rdfname.append((a, b))
        rdf.append(hist2rdf(hist, volume, (na, nb), binw, nbin))
    if options["json"]:
        D = dict()
        D["r"] = [i * binw for i in range(1, nbin)]
        for i, pair in enumerate(rdfname):
            name = "{0}--{1}".format(*pair)
            D[name] = [x for x in rdf[i]]
        print(json.dumps(D, indent=2, sort_keys=True))
    else:
        print("# r/nm ",
              "\t".join(["{0}-{1}".format(*name) for name in rdfname]))
        for i in range(1, nbin):
            values = [i * binw] + [r[i] for r in rdf]
            print("\t".join(["{0:.3f}".format(v) for v in values]))
    logger.info("Hook7: end.")
Exemple #8
0
def main():
    logging.basicConfig(level=logging.INFO,
                        format="%(asctime)s %(levelname)s %(message)s")
    logger = logging.getLogger()
    gro = open(sys.argv[1])
    unitinfo = open(sys.argv[2])
    logger.info("Loading {0}".format(sys.argv[1]))
    box, atoms = LoadGRO(gro)
    ratoms = atoms/box
    cellmat = np.diag(box)
    celli = np.linalg.inv(cellmat)
    a,b,c = loadBOX9(unitinfo)
    unitcell = np.vstack((a,b,c))
    # print(unitcell)
    uniti = np.linalg.inv(unitcell)
    D = np.linalg.norm((a+b+c)/2)+0.3 # diag of the half cell.
    grid = pl.determine_grid(cellmat, D)
    # print(grid)
    logger.info("Making the neighbor list.")
    z = pl.pairs_fine(ratoms, D, cellmat, grid, distance=False)
    g = nx.Graph(list(z))
    logger.info("Reading smatch file.")
    matched = defaultdict(list)
    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:]]
        # d = np.array([dx,dy,dz])
        # dL = np.linalg.norm(d)
        if rmsd < 0.085: # 0.08 for T144
            # 距離によらず、よく一致したペアのラベルを保存しておく。
            matched[i].append(j)
            matched[j].append(i)
    # 一番いろんなところと似ていた原子kをさがす。
    #上位10個について、それぞれ周辺原子分布を作り、平行移動して重ねる。
    # うまくいくかどうかはわからない。
    logger.info("Overlaying atomic configurations.")
    order = sorted(matched, key=lambda x:len(matched[x]), reverse=True)
    logger.info([len(matched[x]) for x in order[:10]])
    gridsize = (32,32,12)
    sumgrid = None
    accum = 0
    for k in order[:10]:
        matched[k].append(k) # add itself
        kL = len(matched[k])
        logger.info("Champion: {0} with {1} neighbors.".format(k, kL))
        grid = distribute(gridsize, matched[k], ratoms, cellmat, uniti, g)
        sumgrid = slid_add(sumgrid, grid)
        accum += kL
    logger.info("{0} configurations collected.".format(accum))
    # ここである程度対称性を整えてから出力するとあとが楽。
    print("@GRID")
    print(*gridsize)
    for i in range(gridsize[0]):
        for j in range(gridsize[1]):
            for k in range(gridsize[2]):
                print(sumgrid[i,j,k] / accum)
    logger.info("Done.")