예제 #1
0
파일: digraph.py 프로젝트: vitroid/GenIce
def find_apsis(coord, cell, distance, vertex, axis):
    logger = logging.getLogger()
    grid = pl.determine_grid(cell, distance)
    logger.debug("Grid: {0}".format(grid))
    #for Z case
    apsis = coord[vertex] + axis*0.5
    #find the atoms near the apsis
    min_d = 1e99
    min_a = -1
    for i,j,d in pl.pairs_fine_hetero([apsis,], coord, distance, cell, grid, distance=True):
        if d < min_d:
            min_a = j
            min_d = d
    return min_a
예제 #2
0
    def prepare_random_graph(self, fixed):
        if self.pairs is None:
            self.logger.info("  Pairs are not given explicitly.")
            self.logger.info(
                "  Start estimating the bonds according to the pair distances."
            )
            # 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 = [
                v for v in pl.pairlist_fine(self.waters,
                                            self.bondlen,
                                            self.cell.mat,
                                            grid,
                                            distance=False)
            ]
            # Check using a simpler algorithm.
            if self.logger.level <= logging.DEBUG:
                pairs2 = [
                    v for v in pl.pairlist_crude(self.waters,
                                                 self.bondlen,
                                                 self.cell.mat,
                                                 distance=False)
                ]
                self.logger.debug("pairs: {0}".format(len(self.pairs)))
                self.logger.debug("pairs2: {0}".format(len(pairs2)))
                for pair in self.pairs:
                    i, j = pair
                    assert (i, j) in pairs2 or (j, i) in pairs2
                for pair in pairs2:
                    i, j = pair
                    assert (i, j) in self.pairs or (j, i) in self.pairs

        graph = dg.IceGraph()
        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)
        return graph
예제 #3
0
파일: digraph.py 프로젝트: Bjournaux/GenIce
def find_apsis(coord, cell, distance, vertex, axis):
    logger = logging.getLogger()
    grid = pl.determine_grid(cell, distance)
    logger.debug("Grid: {0}".format(grid))
    #for Z case
    apsis = coord[vertex] + axis * 0.5
    #find the atoms near the apsis
    min_d = 1e99
    min_a = -1
    for i, j, d in pl.pairs_fine_hetero([
            apsis,
    ],
                                        coord,
                                        distance,
                                        cell,
                                        grid,
                                        distance=True):
        if d < min_d:
            min_a = j
            min_d = d
    return min_a
예제 #4
0
파일: lattice.py 프로젝트: vitroid/GenIce
    def prepare_random_graph(self, fixed):
        if self.pairs is None:
            self.logger.info("  Pairs are not given explicitly.")
            self.logger.info(
                "  Start estimating the bonds according to the pair distances.")
            # 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 = [v for v in pl.pairs_fine(
                self.waters, self.bondlen, self.cell.mat, grid, distance=False)]
            # Check using a simpler algorithm.
            if self.logger.level <= logging.DEBUG:
                pairs2 = [v for v in pl.pairs_crude(
                    self.waters, self.bondlen, self.cell.mat, distance=False)]
                self.logger.debug("pairs: {0}".format(len(self.pairs)))
                self.logger.debug("pairs2: {0}".format(len(pairs2)))
                for pair in self.pairs:
                    i, j = pair
                    assert (i, j) in pairs2 or (j, i) in pairs2
                for pair in pairs2:
                    i, j = pair
                    assert (i, j) in self.pairs or (j, i) in self.pairs

        graph = dg.IceGraph()
        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)
        return graph
예제 #5
0
파일: gromacs.py 프로젝트: vitroid/GenIce
def argparser(arg):
    global waters, cell, celltype, coord, density, pairs
    # additional for analice
    global rotmat
    logger = logging.getLogger()
    args = arg.split(":")
    assert 0 < len(args) <= 3, __doc__
    if len(args) == 1:
        O = "Ow"
        H = "Hw"
    elif len(args) == 2:
        O = args[1]
        H = None
    else:
        O = args[1]
        H = args[2]
    filename = args[0]

    file = open(filename)
    file.readline()
    natom = int(file.readline())
    hatoms = []
    waters = []
    for i in range(natom):
        line = file.readline()
        # resid = int(line[0:5])
        # resna = line[5:10]
        atomname = line[10:15].replace(' ', '')
        # atomid = int(line[15:20])
        pos = np.array([float(x) for x in line[20:].split()[:3]]) #drop velocity
        if atomname == O:
            waters.append(pos)
        elif H is not None and re.fullmatch(H, atomname):
            hatoms.append(pos)
        else:
            logger.info("Skip {0}".format(atomname))
    c = [float(x) for x in file.readline().split()]
    if len(c) == 3:
        cell = np.array([[c[0],0.,0.],
                         [0.,c[1],0.],
                         [0.,0.,c[2]]])
    else:
        cell = np.array([[c[0],c[3],c[4]],
                         [c[5],c[1],c[6]],
                         [c[7],c[8],c[2]]])
    celltype = 'triclinic'
    coord = 'absolute'
    density = len(waters) / (np.linalg.det(cell)*1e-21) * 18 / 6.022e23

    if len(hatoms) > 0:
        celli = np.linalg.inv(cell)
        # relative coord
        rh = [np.dot(x, celli) for x in hatoms]
        ro = [np.dot(x, celli) for x in waters]
        # rotmatrices for analice
        rotmat = []
        for i in range(len(waters)):
            o = waters[i]
            h0, h1 = hatoms[i*2:i*2+2]
            h0 -= o
            h1 -= o
            y = h1 - h0
            y /= np.linalg.norm(y)
            z = h0+h1
            z /= np.linalg.norm(z)
            x = np.cross(y,z)
            rotmat.append(np.vstack([x,y,z]))
        grid = pl.determine_grid(cell, 0.245)
        # remove intramolecular OHs
        pairs = []
        for o,h in pl.pairs_fine_hetero(ro, rh, 0.245, cell, grid, distance=False):
            if h == o*2 or h == o*2+1:
                # adjust oxygen positions
                dh = rh[h] - ro[o]
                dh -= np.floor(dh + 0.5)
                waters[o] += np.dot(dh, cell)*1./16.
            else:
                # register a new intermolecular pair
                pairs.append((h//2, o))
        logger.debug("  # of pairs: {0} {1}".format(len(pairs),len(waters)))
예제 #6
0
def generate_ice(lattice_type, density=-1, seed=1000, rep=(1, 1, 1), stage=3):
    logger = logging.getLogger()
    logger.info("Ice type: {0}".format(lattice_type))
    lat = safe_import("lattice", lattice_type)
    #Show the document of the module
    try:
        for line in lat.__doc__.splitlines():
            logger.info("!!! {0}".format(line))
    except:
        pass
    lat.waters = load_numbers(lat.waters)
    logger.debug("Waters: {0}".format(len(lat.waters)))
    lat.waters = lat.waters.reshape((lat.waters.size // 3, 3))
    #prepare cell transformation matrix
    if lat.celltype == "rect":
        if type(lat.cell) is str:
            lat.cell = np.fromstring(lat.cell, sep=" ")
        elif type(lat.cell) is list:
            lat.cell = np.array(lat.cell)
        lat.cell = np.diag(lat.cell)
    elif lat.celltype == "monoclinic":
        if type(lat.cell) is str:
            lat.cell = np.fromstring(lat.cell, sep=" ")
        elif type(lat.cell) is list:
            lat.cell = np.array(lat.cell)
        beta = lat.cell[3] * math.pi / 180.
        lat.cell = np.array(
            ((lat.cell[0] * 1.0, lat.cell[1] * 0.0,
              lat.cell[2] * math.cos(beta)),
             (lat.cell[0] * 0.0, lat.cell[1] * 1.0,
              lat.cell[2] * 0.0), (lat.cell[0] * 0.0, lat.cell[1] * 0.0,
                                   lat.cell[2] * math.sin(beta))))
        lat.cell = lat.cell.transpose(
        )  #all the vector calculations are done in transposed manner.
    elif lat.celltype == "triclinic":
        """
        Put the vectors like following:
        cell = "ax 0 0 bx by 0 cx cy cz"
        when you define a unit cell in Lattice/
        
        """
        if type(lat.cell) is str:
            lat.cell = np.fromstring(lat.cell, sep=" ")
            logger.debug(lat.cell)
        elif type(lat.cell) is list:
            lat.cell = np.array(lat.cell)
        lat.cell = np.reshape(lat.cell, (3, 3))
        #assert lat.cell[0,1] == 0 and lat.cell[0,2] == 0 and lat.cell[1,2] == 0
    else:
        logger.error("unknown cell type: {0}".format(lat.celltype))
        sys.exit(1)

    #express molecular positions in the coordinate relative to the cell
    if lat.coord == "absolute":
        lat.waters = np.dot(
            lat.waters,
            np.linalg.inv(lat.cell),
        )
        lat.waters = np.array(lat.waters)
    random.seed(seed)
    np.random.seed(seed)

    #Prearranged network topology information (if available)
    pairs = None
    bondlen = None
    try:
        if type(lat.pairs) is str:
            lines = lat.pairs.split("\n")
            pairs = set()
            for line in lines:
                columns = line.split()
                if len(columns) == 2:
                    i, j = [int(x) for x in columns]
                    pairs.add(frozenset([i, j]))
        elif type(lat.pairs) is list:
            pairs = set()
            for pair in pairs:
                pairs.add(frozenset(pair))
    except AttributeError:
        logger.info("Graph is not defined.")

    #Bond length threshold
    try:
        bondlen = lat.bondlen
    except AttributeError:
        logger.info("Bond length is not defined.")

    #set density
    if density < 0:
        density = lat.density

    #scale the cell according to the (specified) density
    mass = 18  #water
    NB = 6.022e23
    nmol = lat.waters.shape[0]  #nmol in a unit cell
    volume = np.linalg.det(lat.cell)  #volume of a unit cell in nm**3
    d = mass * nmol / (NB * volume * 1e-21)
    ratio = (d / density)**(1.0 / 3.0)
    lat.cell *= ratio
    if bondlen is not None:
        bondlen *= ratio

    if True:
        logger.info("Start placing the bonds.")
        if pairs is None:
            logger.info("  Pairs are not given explicitly.")
            logger.info(
                "  Start estimating the bonds according to the pair distances."
            )
            #make bonded pairs according to the pair distance.
            #make before replicating them.
            grid = pl.determine_grid(lat.cell, bondlen)
            pairs = pl.pairlist_fine(lat.waters,
                                     bondlen,
                                     lat.cell,
                                     grid,
                                     distance=False)
            if logger.level <= logging.DEBUG:
                pairs2 = pl.pairlist_crude(lat.waters,
                                           bondlen,
                                           lat.cell,
                                           distance=False)
                logger.debug("pairs: {0}".format(len(pairs)))
                logger.debug("pairs2: {0}".format(len(pairs2)))
                for pair in pairs:
                    i, j = pair
                    assert (i, j) in pairs2 or (j, i) in pairs2
                for pair in pairs2:
                    i, j = pair
                    assert (i, j) in pairs or (j, i) in pairs
            logger.info("  End estimating the bonds.")

        shuffled_pairs = []
        for pair in pairs:
            i, j = pair
            if random.randint(0, 1) == 0:
                i, j = j, i
            shuffled_pairs.append((i, j))

        graph = dg.IceGraph()
        graph.register_pairs(shuffled_pairs)
        logger.info("End placing the bonds.")

    #replicate water molecules to make a repeated cell
    reppositions = replicate(lat.waters, rep)

    #scale the cell
    for d in range(3):
        lat.cell[:, d] *= rep[d]

    result = {
        "positions": reppositions,
        "cell": lat.cell,
        "celltype": lat.celltype,
        "bondlen": bondlen
    }
    if stage == 0:
        return result
        #return reppositions, None, None, lat.cell, lat.celltype, bondlen

    #replicate the graph
    #This also shuffles the bond directions
    graph = replicate_graph(graph, lat.waters, rep)

    result["graph"] = graph
    if stage == 1:
        return result

    #Test
    undir = graph.to_undirected()
    for node in range(undir.number_of_nodes()):
        if node not in undir:
            logger.debug("z=0 at {0}".format(node))
        else:
            z = len(undir.neighbors(node))
            if z != 4:
                logger.debug("z={0} at {1}".format(z, node))

    if graph.number_of_edges() != len(reppositions) * 2:
        logger.info(
            "Inconsistent number of HBs {0} for number of molecules {1}.".
            format(graph.number_of_edges(), len(reppositions)))
        return result

    #make them obey the ice rule
    logger.info("Start making the bonds obey the ice rules.")
    graph.purge_ice_defects()
    logger.info("End making the bonds obey the ice rules.")
    if stage == 2:
        result["graph"] = graph
        return result

    #Rearrange HBs to purge the total dipole moment.
    logger.info("Start depolarization.")
    double_net_test = True
    try:
        if lat.double_network:
            double_net_test = (rep[0] % 2 == 0) and (rep[1] % 2
                                                     == 0) and (rep[2] % 2
                                                                == 0)
    except:
        pass  #just ignore.
    if not double_net_test:
        logger.error(
            "In making the ice structure having the double network (e.g. ices 6 and 7), all the repetition numbers (--rep) must be even."
        )
        sys.exit(1)
    spacegraph = dg.SpaceIceGraph(graph, coord=reppositions)
    draw = dg.YaplotDraw(reppositions, lat.cell, data=spacegraph)
    yapresult = dg.depolarize(spacegraph, lat.cell, draw=draw)
    logger.info("End depolarization.")
    #determine the orientations of the water molecules based on edge directions.
    rotmatrices = orientations(reppositions, spacegraph, lat.cell)
    result["rotmatrices"] = rotmatrices
    result["graph"] = spacegraph
    result["yaplot"] = yapresult
    if stage == 3:
        return result
예제 #7
0
파일: gromacs.py 프로젝트: Bjournaux/GenIce
def argparser(arg):
    global waters, cell, celltype, coord, density, pairs
    # additional for analice
    global rotmat
    logger = logging.getLogger()
    args = arg.split(":")
    assert 0 < len(args) <= 3, __doc__
    if len(args) == 1:
        O = "Ow"
        H = "Hw"
    elif len(args) == 2:
        O = args[1]
        H = None
    else:
        O = args[1]
        H = args[2]
    filename = args[0]

    file = open(filename)
    file.readline()
    natom = int(file.readline())
    hatoms = []
    waters = []
    for i in range(natom):
        line = file.readline()
        # resid = int(line[0:5])
        # resna = line[5:10]
        atomname = line[10:15].replace(' ', '')
        # atomid = int(line[15:20])
        pos = np.array([float(x)
                        for x in line[20:].split()[:3]])  #drop velocity
        if atomname == O:
            waters.append(pos)
        elif H is not None and re.fullmatch(H, atomname):
            hatoms.append(pos)
        else:
            logger.info("Skip {0}".format(atomname))
    c = [float(x) for x in file.readline().split()]
    if len(c) == 3:
        cell = np.array([[c[0], 0., 0.], [0., c[1], 0.], [0., 0., c[2]]])
    else:
        cell = np.array([[c[0], c[3], c[4]], [c[5], c[1], c[6]],
                         [c[7], c[8], c[2]]])
    celltype = 'triclinic'
    coord = 'absolute'
    density = len(waters) / (np.linalg.det(cell) * 1e-21) * 18 / 6.022e23

    if len(hatoms) > 0:
        celli = np.linalg.inv(cell)
        # relative coord
        rh = [np.dot(x, celli) for x in hatoms]
        ro = [np.dot(x, celli) for x in waters]
        # rotmatrices for analice
        rotmat = []
        for i in range(len(waters)):
            o = waters[i]
            h0, h1 = hatoms[i * 2:i * 2 + 2]
            h0 -= o
            h1 -= o
            y = h1 - h0
            y /= np.linalg.norm(y)
            z = h0 + h1
            z /= np.linalg.norm(z)
            x = np.cross(y, z)
            rotmat.append(np.vstack([x, y, z]))
        grid = pl.determine_grid(cell, 0.245)
        # remove intramolecular OHs
        pairs = []
        for o, h in pl.pairs_fine_hetero(ro,
                                         rh,
                                         0.245,
                                         cell,
                                         grid,
                                         distance=False):
            if h == o * 2 or h == o * 2 + 1:
                # adjust oxygen positions
                dh = rh[h] - ro[o]
                dh -= np.floor(dh + 0.5)
                waters[o] += np.dot(dh, cell) * 1. / 16.
            else:
                # register a new intermolecular pair
                pairs.append((h // 2, o))
        logger.debug("  # of pairs: {0} {1}".format(len(pairs), len(waters)))