Пример #1
0
def get_fwrings(code, validation='cross_distance', cutoff=3.15):
    '''
    Function to find all the unique rings in a zeolite framework.

    INPUTS:
    code:       (str) IZA code for the zeolite you are using (i.e. 'CHA')

    OUTPUTS:
    index_paths:    (dictionary) {ring length : indices of atoms in ring}
    label_paths:    (dictionary) {ring length : site labels of atoms in ring}
    trajectories:   (dictionary of atoms objects)  -
                    {ring length : [atoms objects for that size ring]}
    '''

    # First, get some basic info we will need about the framework
    # atoms object, possible ring sizes, and the index of each o-site type
    atoms = framework(code)
    ring_sizes = get_ring_sizes(code)
    osites, omults, oinds = get_osites(code)

    # now we find all the rings associated with each oxygen type in the fw
    # this in theory should find us every possible type of ring in the fw
    paths = []
    for o in oinds:
        paths += get_orings(atoms,
                            o,
                            code,
                            validation=validation,
                            cutoff=cutoff)[1]
    paths = remove_dups(paths)

    # now we want to get the t-site and o-site labels
    repeat = atoms_to_graph(atoms, 0, max(ring_sizes) * 2)[2]
    atoms = atoms.repeat(repeat)
    labels = site_labels(atoms, code)

    # now convert all the paths from index form into site label form
    index_paths = paths
    label_paths = []
    for path in index_paths:
        l = []
        for p in path:
            l.append(labels[p])
        label_paths.append(l)

    # now we want to remove duplicate rings based on the label_paths
    # this will also give us the paths in a conveinent dictionary
    # we will check the labels and geometry to remove duplicates
    index_paths, label_paths = remove_labeled_dups(index_paths, label_paths,
                                                   ring_sizes, atoms)

    # last but not least, let's make an atoms object for each ring type so that
    # we can visualize them later
    # this will be a dictionary of trajectories
    trajectories = dict_to_atoms(index_paths, atoms)

    return index_paths, label_paths, trajectories
Пример #2
0
def site_labels(atoms, code):
    '''
    This function will get the atom site labels (as defined by the IZA) for
    your atoms object. Be sure to remove any adsorbates from your zeolite
    framework before using this function or else it won't work. This function
    will work with T sites that have been exchanged for Al (or any atom).

    atoms: atoms object containing a zeolite you want labels for

    code: the zeolite framework code of your atoms object (i.e. 'CHA')
    '''

    tdict = label_tsites(atoms, code)
    odict = label_osites(atoms, code)
    all_labels = {**tdict, **odict}

    z = framework(code)
    zcell = z.cell.cellpar()[:3]
    acell = atoms.cell.cellpar()[:3]
    repeat = []
    for zc, ac in zip(zcell, acell):
        repeat.append(int(round(ac / zc)))
    z = z.repeat(repeat)

    zo_inds = [atom.index for atom in z if atom.symbol == 'O']
    zt_inds = [atom.index for atom in z if atom.symbol != 'O']

    #z.set_tags(z_inds)
    poszo = z[zo_inds].get_scaled_positions()
    poszt = z[zt_inds].get_scaled_positions()

    scaledp = atoms.get_scaled_positions()

    Dict = {}
    for a in atoms:
        pa = scaledp[a.index]
        sym = a.symbol
        if sym == 'O':
            diffp = poszo - pa
            mags = []
            for d in diffp:
                mags.append(np.linalg.norm(d))
            ind = mags.index(min(mags))
            ind = zo_inds[ind]
            label = all_labels[ind]

        if sym != 'O':
            diffp = poszt - pa
            mags = []
            for d in diffp:
                mags.append(np.linalg.norm(d))
            ind = mags.index(min(mags))
            ind = zt_inds[ind]
            label = all_labels[ind]
        Dict[a.index] = label

    return Dict
Пример #3
0
def get_tsites(code):
    from zse.collections import get_tsites
    z = framework(code)
    tsites, tmult = get_tsites(code)
    tinds = [atom.index for atom in z if atom.symbol != 'O']
    index = 0
    first_ts = []
    for i, m in enumerate(tmult):
        first_ts.append(tinds[index])
        index += m
    return tsites, tmult, first_ts
Пример #4
0
def get_osites(code):
    from zse.collections import get_osites
    z = framework(code)
    osites, omult = get_osites(code)
    oinds = [atom.index for atom in z if atom.symbol == 'O']
    index = 0
    first_os = []
    for i, m in enumerate(omult):
        first_os.append(oinds[index])
        index += m
    return osites, omult, first_os
Пример #5
0
def label_tsites(atoms, code):

    z = framework(code)
    tsites, tmult, first = get_tsites(code)
    tinds = [atom.index for atom in z if atom.symbol != 'O']

    zcell = z.cell.cellpar()[:3]
    acell = atoms.cell.cellpar()[:3]
    repeat = []
    for zc, ac in zip(zcell, acell):
        repeat.append(int(round(ac / zc)))
    z = z.repeat(repeat)
    tinds = [atom.index for atom in z if atom.symbol != 'O']

    rp = np.prod(repeat)
    Dict = {}
    j = 0
    for i in range(rp):
        for s, t in enumerate(tsites):
            for q in range(tmult[s]):
                Dict[tinds[j]] = t
                j += 1

    return Dict
Пример #6
0
def label_osites(atoms, code):

    z = framework(code)
    osites, omult, first = get_osites(code)

    zcell = z.get_cell_lengths_and_angles()[:3]
    acell = atoms.get_cell_lengths_and_angles()[:3]
    repeat = []
    for zc, ac in zip(zcell, acell):
        repeat.append(int(round(ac / zc)))

    z = z.repeat(repeat)
    oinds = [atom.index for atom in z if atom.symbol == 'O']

    rp = np.prod(repeat)
    Dict = {}
    j = 0
    for i in range(rp):
        for s, t in enumerate(osites):
            for q in range(omult[s]):
                Dict[oinds[j]] = t
                j += 1

    return Dict
Пример #7
0
def get_unique_trings(code, ring_size):
    z = framework(code)
    pr = get_fwrings(code)
    tsites, tmult = get_tsites(code)
    tinds = [atom.index for atom in z if atom.symbol != 'O']
    index = 0
    firstts = []
    for i, m in enumerate(tmult):
        firstts.append(tinds[index])
        index += m
    allrings = []
    for f in firstts:
        c, r, ringatoms, repeat = tring_driver(z, f, pr, delete=False)
        for ring in r:
            allrings.append(ring)
    tinds = [atom.index for atom in ringatoms if atom.symbol != 'O']
    rp = np.prod(repeat)
    Dict = {}
    j = 0
    for i in range(rp):
        for s, t in enumerate(tsites):
            for q in range(tmult[s]):
                Dict[tinds[j]] = t
                j += 1
    ring_tsites = []
    for ring in allrings:
        tmp = []
        for i in ring:
            if ringatoms[i].symbol != 'O':
                tmp.append(Dict[i])
        ring_tsites.append(tmp)
    desired_rings_tsites = []
    desired_rings_full = []
    for i, r in enumerate(ring_tsites):
        if len(r) == ring_size:
            desired_rings_tsites.append(r)
            desired_rings_full.append(allrings[i])
    unique_tsites = []
    unique_full = []
    d = []
    for i in range(len(desired_rings_tsites)):
        for j in range((i + 1), len(desired_rings_tsites)):
            if i != j:
                st1 = ' '.join(map(str, desired_rings_tsites[i]))
                st2 = ' '.join(map(str, desired_rings_tsites[j]))
                st2_2 = ' '.join(map(str, reversed(desired_rings_tsites[j])))
                # st1 = set(desired_rings_tsites[i])
                # st2 = set(desired_rings_tsites[j])
                # if st1 == st2:
                if st2 in st1 + ' ' + st1 or st2_2 in st1 + ' ' + st1:
                    d.append(int(j))
    for i in range(len(desired_rings_tsites)):
        if i not in d:
            unique_tsites.append(desired_rings_tsites[i])
            unique_full.append(desired_rings_full[i])

    traj = []
    com = ringatoms.get_center_of_mass()
    for ring in unique_full:
        keepers = []
        atoms = ringatoms.copy()
        for i in ring:
            if i not in keepers:
                keepers.append(i)
        d = [atom.index for atom in atoms if atom.index not in keepers]
        del atoms[d]
        position = atoms[0].position
        trans = com - position
        atoms.translate(trans)
        atoms.wrap()
        traj += [atoms]

    return traj, unique_tsites
Пример #8
0
def get_all_rings(code):
    '''
    For developmental testing only.
    '''
    z = framework(code)
    pr = get_fwrings(code)
    tsites, tmult, first = get_tsites(code)
    tinds = [atom.index for atom in z if atom.symbol != 'O']
    index = 0
    firstts = []
    for i, m in enumerate(tmult):
        firstts.append(tinds[index])
        index += m
    allrings = []
    for f in firstts:
        c, r, ringatoms, repeat = all_trings(z, f, pr, delete=False)
        for ring in r:
            allrings.append(ring)
    tinds = [atom.index for atom in ringatoms if atom.symbol != 'O']
    rp = np.prod(repeat)
    Dict = {}
    j = 0
    for i in range(rp):
        for s, t in enumerate(tsites):
            for q in range(tmult[s]):
                Dict[tinds[j]] = t
                j += 1
    ring_tsites = []
    for ring in allrings:
        tmp = []
        for i in ring:
            if ringatoms[i].symbol != 'O':
                tmp.append(Dict[i])
        ring_tsites.append(tmp)
    unique_tsites = {}
    unique_full = {}
    for i, r in enumerate(ring_tsites):
        length = len(r)
        if length not in unique_tsites:
            unique_tsites[length] = [r]
            unique_full[length] = [allrings[i]]
        else:
            unique_tsites[length].append(r)
            unique_full[length].append(allrings[i])
    trajectories = {}
    com = ringatoms.get_center_of_mass()
    for length in pr:
        ring_tlist = unique_tsites[length]
        ring_full = unique_full[length]
        d = []
        for i in range(len(ring_tlist)):
            for j in range((i + 1), len(ring_tlist)):
                st1 = ' '.join(map(str, ring_tlist[i]))
                st2 = ' '.join(map(str, ring_tlist[j]))
                st2_2 = ' '.join(map(str, reversed(ring_tlist[j])))
                if st2 in st1 + ' ' + st1 or st2_2 in st1 + ' ' + st1:
                    d.append(int(j))
        tmp1 = []
        tmp2 = []
        for i in range(len(ring_tlist)):
            if i not in d:
                tmp1.append(ring_tlist[i])
                tmp2.append(ring_full[i])
        unique_tsites[length] = tmp1
        unique_full[length] = tmp2
        traj = []
        for ring in tmp2:
            keepers = []
            atoms = ringatoms.copy()
            for i in ring:
                if i not in keepers:
                    keepers.append(i)
            d = [atom.index for atom in atoms if atom.index not in keepers]
            del atoms[d]
            position = atoms[0].position
            trans = com - position
            atoms.translate(trans)
            atoms.wrap()
            traj += [atoms]
        trajectories[length] = traj

    return unique_tsites, unique_full, trajectories
Пример #9
0
def get_vertex_symbols(code, index):
    '''
    Function to find all the the shortest rings connecting each
    oxygen-oxygen pair associated with a T-site

    INPUTS:
    code:       (str) IZA code for the zeolite you are using (i.e. 'CHA')
    index:      (integer) index of the T-site that you want to classify

    OUTPUTS:
    vertex_symbols: (dictionary) keys are the O-site labels, and values are the
                    indices of the atoms connecting those oxygens
    trajectory:     (ASE atoms objects) that include the rings for each
                    oxygen-oxygen pair
    '''

    # get the possible rings of this framework from the IZA
    # the maximum ring size determines how many times to repeat the unit cell
    ring_sizes = get_ring_sizes(code) * 2
    max_ring = max(ring_sizes)

    # get an atoms object of the framework
    atoms = framework(code)

    # repeat the unit cell so it is large enough to capture the max ring size
    # also turn this new larger unit cell into a graph
    G, large_atoms, repeat = atoms_to_graph(atoms, index, max_ring)
    index = [atom.index for atom in large_atoms if atom.tag == index][0]

    # get the T-site and O-site labels for each atom in the framework
    atoms = atoms.repeat(repeat)
    labels = site_labels(atoms, code)

    # get each o-o pair for the T-site
    vertices = get_vertices(G, index)

    # set up a dictionary to stare results
    vertex_symbols = {}

    # got through each o-o pair and find the shortest paths
    traj = []
    for i, v in enumerate(vertices):
        o1 = v[0]
        o2 = v[1]
        v_label = '{0}-{1}'.format(labels[large_atoms[o1].tag],
                                   labels[large_atoms[o2].tag])

        # this finds the shortest path between the two
        path, l = shortest_valid_path(G, o1, o2, index)
        # this finds all valid paths of that length between the two
        paths = [p for p in all_paths(G, o1, o2, index, l)]
        traj += [paths_to_atoms(large_atoms, paths)]
        tmp_paths = []
        for p in paths:
            temp = []
            for x in p:
                temp.append(large_atoms[x].tag)
            tmp_paths.append(temp)
        vertex_symbols['{0}:{1}'.format(
            i + 1, v_label)] = [path for path in tmp_paths]

    return vertex_symbols, traj