示例#1
0
    def test_xyz(self):
        op=SymmOp([[1, -1, 0, 0], [0, -1, 0, 0],
                     [0, 0, -1, 0], [0, 0, 0, 1]])
        s=op.as_xyz_string()
        self.assertEqual(s, 'x-y, -y, -z')
        self.assertEqual(op, SymmOp.from_xyz_string(s))

        op2=SymmOp([[0, -1, 0, 0.5], [1, 0, 0, 0.5],
                      [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
        s2=op2.as_xyz_string()
        self.assertEqual(s2, '-y+1/2, x+1/2, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op2=SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                      [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
        s2=op2.as_xyz_string()
        self.assertEqual(s2, '3x-2y-z+1/2, -x+12/13, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op3=SymmOp.from_xyz_string('3x - 2y - z+1 /2 , -x+12/ 13, z+1/2')
        self.assertEqual(op2, op3)

        # Ensure strings can be read in any order
        op4=SymmOp.from_xyz_string('1 /2 + 3X - 2y - z , 12/ 13-x, z+1/2')
        op5=SymmOp.from_xyz_string('+1 /2 + 3x - 2y - z , 12/ 13-x, +1/2+z')
        self.assertEqual(op4, op3)
        self.assertEqual(op4, op5)
        self.assertEqual(op3, op5)

        self.assertRaises(ValueError, self.op.as_xyz_string)

        o=SymmOp.from_xyz_string('0.5+x, 0.25+y, 0.75+z')
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
        o=SymmOp.from_xyz_string('x + 0.5, y + 0.25, z + 0.75')
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
示例#2
0
    def test_xyz(self):
        op = SymmOp([[1, -1, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0,
                                                                   1]])
        s = op.as_xyz_string()
        self.assertEqual(s, 'x-y, -y, -z')
        self.assertEqual(op, SymmOp.from_xyz_string(s))

        op2 = SymmOp([[0, -1, 0, 0.5], [1, 0, 0, 0.5], [0, 0, 1, 0.5 + 1e-7],
                      [0, 0, 0, 1]])
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, '-y+1/2, x+1/2, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op2 = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                      [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, '3x-2y-z+1/2, -x+12/13, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op3 = SymmOp.from_xyz_string('3x - 2y - z+1 /2 , -x+12/ 13, z+1/2')
        self.assertEqual(op2, op3)

        # Ensure strings can be read in any order
        op4 = SymmOp.from_xyz_string('1 /2 + 3X - 2y - z , 12/ 13-x, z+1/2')
        op5 = SymmOp.from_xyz_string('+1 /2 + 3x - 2y - z , 12/ 13-x, +1/2+z')
        self.assertEqual(op4, op3)
        self.assertEqual(op4, op5)
        self.assertEqual(op3, op5)

        self.assertRaises(ValueError, self.op.as_xyz_string)

        o = SymmOp.from_xyz_string('0.5+x, 0.25+y, 0.75+z')
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
        o = SymmOp.from_xyz_string('x + 0.5, y + 0.25, z + 0.75')
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
示例#3
0
def get_wyckoffs(sg):
    wyckoff_strings = eval(wyckoff_df["0"][sg])
    wyckoffs = []
    for x in wyckoff_strings:
        wyckoffs.append([])
        for y in x:
            wyckoffs[-1].append(SymmOp.from_xyz_string(y))
    return wyckoffs
    def test_xyz(self):
        op = SymmOp([[1, -1, 0, 0], [0, -1, 0, 0],
                     [0, 0, -1, 0], [0, 0, 0, 1]])
        s = op.as_xyz_string()
        self.assertEqual(s, 'x-y, -y, -z')
        self.assertEqual(op, SymmOp.from_xyz_string(s))

        op2 = SymmOp([[0, -1, 0, 0.5], [1, 0, 0, 0.5],
                      [0, 0, 1, 0.5+1e-7], [0, 0, 0, 1]])
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, '-y+1/2, x+1/2, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op2 = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12./13],
                      [0, 0, 1, 0.5+1e-7], [0, 0, 0, 1]])
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, '3x-2y-z+1/2, -x+12/13, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op3 = SymmOp.from_xyz_string('3x - 2y - z+1 /2 , -x+12/ 13, z+1/2')
        self.assertEqual(op2, op3)

        self.assertRaises(ValueError, self.op.as_xyz_string)
示例#5
0
def get_wyckoff_generators(sg):
    '''
    Returns a list of Wyckoff generators for a given space group.
    1st index: index of WP in sg (0 is the WP with largest multiplicity)
    2nd index: a generator for the WP
    '''
    generators_strings = eval(wyckoff_generators_df["0"][sg])
    generators = []
    #Loop over Wyckoff positions
    for wp in generators_strings:
        generators.append([])
        #Loop over points in WP
        for op in wp:
            generators[-1].append(SymmOp.from_xyz_string(op))
    return generators
示例#6
0
    def test_xyz(self):
        op = SymmOp([[1, -1, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]])
        s = op.as_xyz_string()
        self.assertEqual(s, "x-y, -y, -z")
        self.assertEqual(op, SymmOp.from_xyz_string(s))

        op2 = SymmOp(
            [[0, -1, 0, 0.5], [1, 0, 0, 0.5], [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]]
        )
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, "-y+1/2, x+1/2, z+1/2")
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op2 = SymmOp(
            [
                [3, -2, -1, 0.5],
                [-1, 0, 0, 12.0 / 13],
                [0, 0, 1, 0.5 + 1e-7],
                [0, 0, 0, 1],
            ]
        )
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, "3x-2y-z+1/2, -x+12/13, z+1/2")
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op3 = SymmOp.from_xyz_string("3x - 2y - z+1 /2 , -x+12/ 13, z+1/2")
        self.assertEqual(op2, op3)

        # Ensure strings can be read in any order
        op4 = SymmOp.from_xyz_string("1 /2 + 3X - 2y - z , 12/ 13-x, z+1/2")
        op5 = SymmOp.from_xyz_string("+1 /2 + 3x - 2y - z , 12/ 13-x, +1/2+z")
        self.assertEqual(op4, op3)
        self.assertEqual(op4, op5)
        self.assertEqual(op3, op5)

        # TODO: assertWarns not in Python 2.x unittest
        # update PymatgenTest for unittest2?
        # self.assertWarns(UserWarning, self.op.as_xyz_string)

        o = SymmOp.from_xyz_string("0.5+x, 0.25+y, 0.75+z")
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
        o = SymmOp.from_xyz_string("x + 0.5, y + 0.25, z + 0.75")
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
示例#7
0
def get_symmetry(mol, already_oriented=False):
    '''
    Return a list of SymmOps for a molecule's point symmetry
    already_oriented: whether or not the principle axes of mol are already reoriented 
    '''
    pga = PointGroupAnalyzer(mol)
    #Handle linear molecules
    if '*' in pga.sch_symbol:
        if already_oriented == False:
            #Reorient the molecule
            oriented_mol, P = reoriented_molecule(mol)
            pga = PointGroupAnalyzer(oriented_mol)
        pg = pga.get_pointgroup()
        symm_m = []
        for op in pg:
            symm_m.append(op)
        #Add 12-fold  and reflections in place of ininitesimal rotation
        for axis in [[1, 0, 0], [0, 1, 0], [0, 0, 1]]:
            op = SymmOp.from_rotation_and_translation(aa2matrix(axis, pi / 6),
                                                      [0, 0, 0])
            if pga.is_valid_op(op):
                symm_m.append(op)
                #Any molecule with infinitesimal symmetry is linear;
                #Thus, it possess mirror symmetry for any axis perpendicular
                #To the rotational axis. pymatgen does not add this symmetry
                #for all linear molecules - for example, hydrogen
                if axis == [1, 0, 0]:
                    symm_m.append(SymmOp.from_xyz_string('x,-y,z'))
                    symm_m.append(SymmOp.from_xyz_string('x,y,-z'))
                elif axis == [0, 1, 0]:
                    symm_m.append(SymmOp.from_xyz_string('-x,y,z'))
                    symm_m.append(SymmOp.from_xyz_string('x,y,-z'))
                elif axis == [0, 0, 1]:
                    symm_m.append(SymmOp.from_xyz_string('-x,y,z'))
                    symm_m.append(SymmOp.from_xyz_string('x,-y,z'))
                #Generate a full list of SymmOps for the molecule's pointgroup
                symm_m = generate_full_symmops(symm_m, 1e-3)
                break
        #Reorient the SymmOps into mol's original frame
        if not already_oriented:
            new = []
            for op in symm_m:
                new.append(P.inverse * op * P)
            return new
        elif already_oriented:
            return symm_m
    #Handle nonlinear molecules
    else:
        pg = pga.get_pointgroup()
        symm_m = []
        for op in pg:
            symm_m.append(op)
        return symm_m
示例#8
0
def get_wyckoff_symmetry(sg):
    '''
    Returns a list of Wyckoff position site symmetry for a given space group.
    1st index: index of WP in sg (0 is the WP with largest multiplicity)
    2nd index: a point within the WP
    3rd index: a site symmetry SymmOp of the point
    '''
    symmetry_strings = eval(wyckoff_symmetry_df["0"][sg])
    symmetry = []
    #Loop over Wyckoff positions
    for x in symmetry_strings:
        symmetry.append([])
        #Loop over points in WP
        for y in x:
            symmetry[-1].append([])
            #Loop over
            for z in y:
                symmetry[-1][-1].append(SymmOp.from_xyz_string(z))
    return symmetry
示例#9
0
文件: test_all.py 项目: Virts/PyXtal
    def test_inverse(self):
        coord0 = [0.35, 0.1, 0.4]
        coords = np.array([
            [0.350, 0.100, 0.400],
            [0.350, 0.100, 0.000],
            [0.350, 0.100, 0.000],
            [0.350, 0.000, 0.667],
            [0.350, 0.000, 0.250],
            [0.350, 0.350, 0.400],
            [0.350, 0.350, 0.500],
            [0.350, 0.350, 0.000],
            [0.350, 0.350, 0.350],
            [0.100, 0.100, 0.100],
            [0.400, 0.400, 0.400],
            [0.350, 0.000, 0.000],
            [0.000, 0.100, 0.400],
            [0.350, 0.000, 0.400],
        ])
        xyzs = [
            'x,y,z',
            'x,y,0',
            'y,x,0',
            'x,0,2/3',
            '0,x,1/4',
            'x,x,z',
            'x,-x,1/2',
            '2x,x,0',
            '-2x,-0.5x,-x+1/4',
            '-2y,-0.5y,-y+1/4',
            '-2z,-0.5z,-z+1/4',
            '0,0,x',
            '-y/2+1/2,-z,0',
            '-z,-x/2+1/2,0',
        ]

        for i, xyz in enumerate(xyzs):
            op = SymmOp.from_xyz_string(xyz)
            inv_op = get_inverse(op)
            coord1 = op.operate(coord0)
            coord2 = inv_op.operate(coord1)
            self.assertTrue(np.allclose(coord2, coords[i], rtol=1e-2))
示例#10
0
    def test_xyz(self):
        op = SymmOp([[1, -1, 0, 0], [0, -1, 0, 0],
                     [0, 0, -1, 0], [0, 0, 0, 1]])
        s = op.as_xyz_string()
        self.assertEqual(s, 'x-y, -y, -z')
        self.assertEqual(op, SymmOp.from_xyz_string(s))

        op2 = SymmOp([[0, -1, 0, 0.5], [1, 0, 0, 0.5],
                      [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, '-y+1/2, x+1/2, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op2 = SymmOp([[3, -2, -1, 0.5], [-1, 0, 0, 12. / 13],
                      [0, 0, 1, 0.5 + 1e-7], [0, 0, 0, 1]])
        s2 = op2.as_xyz_string()
        self.assertEqual(s2, '3x-2y-z+1/2, -x+12/13, z+1/2')
        self.assertEqual(op2, SymmOp.from_xyz_string(s2))

        op3 = SymmOp.from_xyz_string('3x - 2y - z+1 /2 , -x+12/ 13, z+1/2')
        self.assertEqual(op2, op3)

        # Ensure strings can be read in any order
        op4 = SymmOp.from_xyz_string('1 /2 + 3X - 2y - z , 12/ 13-x, z+1/2')
        op5 = SymmOp.from_xyz_string('+1 /2 + 3x - 2y - z , 12/ 13-x, +1/2+z')
        self.assertEqual(op4, op3)
        self.assertEqual(op4, op5)
        self.assertEqual(op3, op5)

        # TODO: assertWarns not in Python 2.x unittest
        # update PymatgenTest for unittest2?
        # self.assertWarns(UserWarning, self.op.as_xyz_string)
            
        o = SymmOp.from_xyz_string('0.5+x, 0.25+y, 0.75+z')
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
        o = SymmOp.from_xyz_string('x + 0.5, y + 0.25, z + 0.75')
        self.assertArrayAlmostEqual(o.translation_vector, [0.5, 0.25, 0.75])
示例#11
0
def get_wyckoff_symmetry(sg, molecular=False):
    '''
    Returns a list of Wyckoff position site symmetry for a given space group.
    1st index: index of WP in sg (0 is the WP with largest multiplicity)
    2nd index: a point within the WP
    3rd index: a site symmetry SymmOp of the point
    molecular: whether or not to return the Euclidean point symmetry operations
        If True, cuts off translational part of operation, and converts non-orthogonal
        (3-fold and 6-fold rotation) operations to pure rotations
    '''
    P = SymmOp.from_rotation_and_translation(
        [[1, -.5, 0], [0, sqrt(3) / 2, 0], [0, 0, 1]], [0, 0, 0])
    symmetry_strings = eval(wyckoff_symmetry_df["0"][sg])
    symmetry = []
    convert = False
    if molecular is True:
        if sg >= 143 and sg <= 194:
            convert = True
    #Loop over Wyckoff positions
    for x in symmetry_strings:
        symmetry.append([])
        #Loop over points in WP
        for y in x:
            symmetry[-1].append([])
            #Loop over ops
            for z in y:
                op = SymmOp.from_xyz_string(z)
                if convert is True:
                    #Convert non-orthogonal trigonal/hexagonal operations
                    op = P * op * P.inverse
                if molecular is False:
                    symmetry[-1][-1].append(op)
                elif molecular is True:
                    op = SymmOp.from_rotation_and_translation(
                        op.rotation_matrix, [0, 0, 0])
                    symmetry[-1][-1].append(op)
    return symmetry
示例#12
0
def get_wyckoffs(sg, organized=False):
    '''
    Returns a list of Wyckoff positions for a given space group.
    1st index: index of WP in sg (0 is the WP with largest multiplicity)
    2nd index: a SymmOp object in the WP
    '''
    wyckoff_strings = eval(wyckoff_df["0"][sg])
    wyckoffs = []
    for x in wyckoff_strings:
        wyckoffs.append([])
        for y in x:
            wyckoffs[-1].append(SymmOp.from_xyz_string(y))
    if organized:
        wyckoffs_organized = [[]]  #2D Array of WP's organized by multiplicity
        old = len(wyckoffs[0])
        for wp in wyckoffs:
            mult = len(wp)
            if mult != old:
                wyckoffs_organized.append([])
                old = mult
            wyckoffs_organized[-1].append(wp)
        return wyckoffs_organized
    else:
        return wyckoffs
示例#13
0
from structure import *
from pymatgen.core.operations import SymmOp

print("---Site Symmetry for a point in a space group---")
sg = input("Space group Number (1-230): ")
point = input("Point (can have x,y,z variables): ")
gen_pos = get_wyckoff_positions(int(sg))[0][0]
point = SymmOp.from_xyz_string(point)
mylist = site_symm(point, gen_pos)
print("Found symmetry:")
for x in mylist:
    print(x.as_xyz_string())
示例#14
0
文件: cif.py 项目: zulissi/pymatgen
    def get_symops(self, data):
        """
        In order to generate symmetry equivalent positions, the symmetry
        operations are parsed. If the symops are not present, the space
        group symbol is parsed, and symops are generated.
        """
        symops = []
        for symmetry_label in ["_symmetry_equiv_pos_as_xyz",
                               "_symmetry_equiv_pos_as_xyz_",
                               "_space_group_symop_operation_xyz",
                               "_space_group_symop_operation_xyz_"]:
            if data.data.get(symmetry_label):
                xyz = data.data.get(symmetry_label)
                if isinstance(xyz, six.string_types):
                    warnings.warn("A 1-line symmetry op P1 CIF is detected!")
                    xyz = [xyz]
                try:
                    symops = [SymmOp.from_xyz_string(s)
                              for s in xyz]
                    break
                except ValueError:
                    continue
        if not symops:
            # Try to parse symbol
            for symmetry_label in ["_symmetry_space_group_name_H-M",
                                   "_symmetry_space_group_name_H_M",
                                   "_symmetry_space_group_name_H-M_",
                                   "_symmetry_space_group_name_H_M_",
                                   "_space_group_name_Hall",
                                   "_space_group_name_Hall_",
                                   "_space_group_name_H-M_alt",
                                   "_space_group_name_H-M_alt_",
                                   "_symmetry_space_group_name_hall",
                                   "_symmetry_space_group_name_hall_",
                                   "_symmetry_space_group_name_h-m",
                                   "_symmetry_space_group_name_h-m_"]:
                sg = data.data.get(symmetry_label)

                if sg:
                    sg = sub_spgrp(sg)
                    try:
                        spg = space_groups.get(sg)
                        if spg:
                            symops = SpaceGroup(spg).symmetry_ops
                            warnings.warn(
                                "No _symmetry_equiv_pos_as_xyz type key found. "
                                "Spacegroup from %s used." % symmetry_label)
                            break
                    except ValueError:
                        # Ignore any errors
                        pass

                    try:
                        for d in _get_cod_data():
                            if sg == re.sub("\s+", "",
                                            d["hermann_mauguin"]) :
                                xyz = d["symops"]
                                symops = [SymmOp.from_xyz_string(s)
                                          for s in xyz]
                                warnings.warn(
                                    "No _symmetry_equiv_pos_as_xyz type key found. "
                                    "Spacegroup from %s used." % symmetry_label)
                                break
                    except Exception as ex:
                        continue

                    if symops:
                        break
        if not symops:
            # Try to parse International number
            for symmetry_label in ["_space_group_IT_number",
                                   "_space_group_IT_number_",
                                   "_symmetry_Int_Tables_number",
                                   "_symmetry_Int_Tables_number_"]:
                if data.data.get(symmetry_label):
                    try:
                        i = int(str2float(data.data.get(symmetry_label)))
                        symops = SpaceGroup.from_int_number(i).symmetry_ops
                        break
                    except ValueError:
                        continue

        if not symops:
            warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. "
                          "Defaulting to P1.")
            symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']]

        return symops
示例#15
0
def test_modules():
    print("====== Testing functionality for pyXtal version 0.1dev ======")

    global failed_package
    failed_package = False  # Record if errors occur at any level

    reset()

    print("Importing sys...")
    try:
        import sys

        print("Success!")
    except Exception as e:
        fail(e)
        sys.exit(0)

    print("Importing numpy...")
    try:
        import numpy as np

        print("Success!")
    except Exception as e:
        fail(e)
        sys.exit(0)

    I = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])

    print("Importing pymatgen...")
    try:
        import pymatgen

        print("Success!")
    except Exception as e:
        fail(e)
        sys.exit(0)

    try:
        from pymatgen.core.operations import SymmOp
    except Exception as e:
        fail(e)
        sys.exit(0)

    print("Importing pandas...")
    try:
        import pandas

        print("Success!")
    except Exception as e:
        fail(e)
        sys.exit(0)

    print("Importing spglib...")
    try:
        import spglib

        print("Success!")
    except Exception as e:
        fail(e)
        sys.exit(0)

    print("Importing openbabel...")
    try:
        import ase

        print("Success!")
    except:
        print(
            "Error: could not import openbabel. Try reinstalling the package.")

    print("Importing pyxtal...")
    try:
        import pyxtal

        print("Success!")
    except Exception as e:
        fail(e)
        sys.exit(0)

    print("=== Testing modules ===")

    # =====database.element=====
    print("pyxtal.database.element")
    reset()
    try:
        import pyxtal.database.element
    except Exception as e:
        fail(e)

    print("  class Element")
    try:
        from pyxtal.database.element import Element
    except Exception as e:
        fail(e)
    if passed():
        for i in range(1, 95):
            if passed():
                try:
                    ele = Element(i)
                except:
                    fail("Could not access Element # " + str(i))
                try:
                    y = ele.sf
                    y = ele.z
                    y = ele.short_name
                    y = ele.long_name
                    y = ele.valence
                    y = ele.valence_electrons
                    y = ele.covalent_radius
                    y = ele.vdw_radius
                    y = ele.get_all(0)
                except:
                    fail("Could not access attribute for element # " + str(i))
                try:
                    ele.all_z()
                    ele.all_short_names()
                    ele.all_long_names()
                    ele.all_valences()
                    ele.all_valence_electrons()
                    ele.all_covalent_radii()
                    ele.all_vdw_radii()
                except:
                    fail("Could not access class methods")

    check()

    # =====database.hall=====
    print("pyxtal.database.hall")
    reset()
    try:
        import pyxtal.database.hall
    except Exception as e:
        fail(e)

    print("  hall_from_hm")
    try:
        from pyxtal.database.hall import hall_from_hm
    except Exception as e:
        fail(e)

    if passed():
        for i in range(1, 230):
            if passed():
                try:
                    hall_from_hm(i)
                except:
                    fail("Could not access hm # " + str(i))

    check()

    # =====database.collection=====
    print("pyxtal.database.collection")
    reset()
    try:
        import pyxtal.database.collection
    except Exception as e:
        fail(e)

    print("  Collection")
    try:
        from pyxtal.database.collection import Collection
    except Exception as e:
        fail(e)

    if passed():
        for i in range(1, 230):
            if passed():
                try:
                    molecule_collection = Collection("molecules")
                except:
                    fail("Could not access hm # " + str(i))

    check()

    # =====operations=====
    print("pyxtal.operations")
    reset()
    try:
        import pyxtal.operations
    except Exception as e:
        fail(e)

    print("  random_vector")
    try:
        from pyxtal.operations import random_vector
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                random_vector()
        except Exception as e:
            fail(e)

    check()

    print("  angle")
    try:
        from pyxtal.operations import angle
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                v1 = random_vector()
                v2 = random_vector()
                angle(v1, v2)
        except Exception as e:
            fail(e)

    check()

    print("  random_shear_matrix")
    try:
        from pyxtal.operations import random_shear_matrix
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                random_shear_matrix()
        except Exception as e:
            fail(e)

    check()

    print("  is_orthogonal")
    try:
        from pyxtal.operations import is_orthogonal
    except Exception as e:
        fail(e)

    if passed():
        try:
            a = is_orthogonal([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
            b = is_orthogonal([[0, 0, 1], [1, 0, 0], [1, 0, 0]])
            if a is True and b is False:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  aa2matrix")
    try:
        from pyxtal.operations import aa2matrix
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                aa2matrix(1, 1, random=True)
        except Exception as e:
            fail(e)

    check()

    print("  matrix2aa")
    try:
        from pyxtal.operations import matrix2aa
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                m = aa2matrix(1, 1, random=True)
                aa = matrix2aa(m)
        except Exception as e:
            fail(e)

    check()

    print("  rotate_vector")
    try:
        from pyxtal.operations import rotate_vector
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                v1 = random_vector()
                v2 = random_vector()
                rotate_vector(v1, v2)
        except Exception as e:
            fail(e)

    check()

    print("  are_equal")
    try:
        from pyxtal.operations import are_equal
    except Exception as e:
        fail(e)

    if passed():
        try:
            op1 = SymmOp.from_xyz_string("x,y,z")
            op2 = SymmOp.from_xyz_string("x,y,z+1")
            a = are_equal(op1, op2, PBC=[0, 0, 1])
            b = are_equal(op1, op2, PBC=[1, 0, 0])
            if a is True and b is False:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  class OperationAnalyzer")
    try:
        from pyxtal.operations import OperationAnalyzer
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                m = aa2matrix(1, 1, random=True)
                t = random_vector()
                op1 = SymmOp.from_rotation_and_translation(m, t)
                OperationAnalyzer(op1)
        except Exception as e:
            fail(e)

    check()

    print("  class Orientation")
    try:
        from pyxtal.operations import Orientation
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in range(10):
                v1 = random_vector()
                c1 = random_vector()
                o = Orientation.from_constraint(v1, c1)
        except Exception as e:
            fail(e)

    check()

    # =====symmetry=====
    print("pyxtal.symmetry")
    reset()
    try:
        import pyxtal.symmetry
    except Exception as e:
        fail(e)

    print("  get_wyckoffs (may take a moment)")
    try:
        from pyxtal.symmetry import get_wyckoffs
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in [1, 2, 229, 230]:
                get_wyckoffs(i)
                get_wyckoffs(i, organized=True)
        except:
            fail(" Could not access Wyckoff positions for space group # " +
                 str(i))

    check()

    print("  get_wyckoff_symmetry (may take a moment)")
    try:
        from pyxtal.symmetry import get_wyckoff_symmetry
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in [1, 2, 229, 230]:
                get_wyckoff_symmetry(i)
                get_wyckoff_symmetry(i, molecular=True)
        except:
            fail("Could not access Wyckoff symmetry for space group # " +
                 str(i))

    check()

    print("  get_wyckoffs_generators (may take a moment)")
    try:
        from pyxtal.symmetry import get_wyckoff_generators
    except Exception as e:
        fail(e)

    if passed():
        try:
            for i in [1, 2, 229, 230]:
                get_wyckoff_generators(i)
        except:
            fail("Could not access Wyckoff generators for space group # " +
                 str(i))

    check()

    print("  letter_from_index")
    try:
        from pyxtal.symmetry import letter_from_index
    except Exception as e:
        fail(e)

    if passed():
        try:
            if letter_from_index(0, get_wyckoffs(47)) == "A":
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  index_from_letter")
    try:
        from pyxtal.symmetry import index_from_letter
    except Exception as e:
        fail(e)

    if passed():
        try:
            if index_from_letter("A", get_wyckoffs(47)) == 0:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  jk_from_i")
    try:
        from pyxtal.symmetry import jk_from_i
    except Exception as e:
        fail(e)

    if passed():
        try:
            w = get_wyckoffs(2, organized=True)
            j, k = jk_from_i(1, w)
            if j == 1 and k == 0:
                pass
            else:
                print(j, k)
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  i_from_jk")
    try:
        from pyxtal.symmetry import i_from_jk
    except Exception as e:
        fail(e)

    if passed():
        try:
            w = get_wyckoffs(2, organized=True)
            j, k = jk_from_i(1, w)
            i = i_from_jk(j, k, w)
            if i == 1:
                pass
            else:
                print(j, k)
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  ss_string_from_ops")
    try:
        from pyxtal.symmetry import ss_string_from_ops
    except Exception as e:
        fail(e)

    if passed():
        try:
            strings = ["1", "4 . .", "2 3 ."]
            for i, sg in enumerate([1, 75, 195]):
                ops = get_wyckoffs(sg)[0]
                ss_string_from_ops(ops, sg, dim=3)
        except Exception as e:
            fail(e)

    check()

    print("  Wyckoff_position")
    try:
        from pyxtal.symmetry import Wyckoff_position
    except Exception as e:
        fail(e)

    if passed():
        try:
            wp = Wyckoff_position.from_group_and_index(20, 1)
        except Exception as e:
            fail(e)

    check()

    print("  Group")
    try:
        from pyxtal.symmetry import Group
    except Exception as e:
        fail(e)

    if passed():
        try:
            g3 = Group(230)
            g2 = Group(80, dim=2)
            g1 = Group(75, dim=1)
        except Exception as e:
            fail(e)

    check()

    # =====crystal=====
    print("pyxtal.crystal")
    reset()
    try:
        import pyxtal.crystal
    except Exception as e:
        fail(e)

    print("  random_crystal")
    try:
        from pyxtal.crystal import random_crystal
    except Exception as e:
        fail(e)

    if passed():
        try:
            c = random_crystal(1, ["H"], [1], 10.0)
            if c.valid is True:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  random_crystal_2D")
    try:
        from pyxtal.crystal import random_crystal_2D
    except Exception as e:
        fail(e)

    if passed():
        try:
            c = random_crystal_2D(1, ["H"], [1], 10.0)
            if c.valid is True:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    # =====molecule=====
    print("pyxtal.molecule")
    reset()
    try:
        import pyxtal.molecule
    except Exception as e:
        fail(e)

    check()

    print("  Collections")
    try:
        from pyxtal.molecule import mol_from_collection
    except Exception as e:
        fail(e)

    if passed():
        try:
            h2o = mol_from_collection("H2O")
            ch4 = mol_from_collection("CH4")
        except Exception as e:
            fail(e)

    print("  get_inertia_tensor")
    try:
        from pyxtal.molecule import get_inertia_tensor
    except Exception as e:
        fail(e)

    if passed():
        try:
            get_inertia_tensor(h2o)
            get_inertia_tensor(ch4)
        except Exception as e:
            fail(e)

    check()

    print("  get_moment_of_inertia")
    try:
        from pyxtal.molecule import get_moment_of_inertia
    except Exception as e:
        fail(e)

    if passed():
        try:
            v = random_vector()
            get_moment_of_inertia(h2o, v)
            get_moment_of_inertia(ch4, v)
        except Exception as e:
            fail(e)

    check()

    print("  reoriented_molecule")
    try:
        from pyxtal.molecule import reoriented_molecule
    except Exception as e:
        fail(e)

    if passed():
        try:
            reoriented_molecule(h2o)
            reoriented_molecule(ch4)
        except Exception as e:
            fail(e)

    check()

    print("  orientation_in_wyckoff_position")
    try:
        from pyxtal.molecule import orientation_in_wyckoff_position
    except Exception as e:
        fail(e)

    if passed():
        try:
            w = get_wyckoffs(20)
            ws = get_wyckoff_symmetry(20, molecular=True)
            wp = Wyckoff_position.from_group_and_index(20, 1)
            orientation_in_wyckoff_position(h2o, wp)
            orientation_in_wyckoff_position(ch4, wp)
        except Exception as e:
            fail(e)

    check()

    # =====molecular_crystal=====
    print("pyxtal.molecular_crystal")
    reset()
    try:
        import pyxtal.crystal
    except Exception as e:
        fail(e)

    print("  molecular_crystal")
    try:
        from pyxtal.molecular_crystal import molecular_crystal
    except Exception as e:
        fail(e)

    if passed():
        try:
            c = molecular_crystal(1, ["H2O"], [1], 10.0)
            if c.valid is True:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    print("  molecular_crystal_2D")
    try:
        from pyxtal.molecular_crystal import molecular_crystal_2D
    except Exception as e:
        fail(e)

    if passed():
        try:
            c = molecular_crystal_2D(1, ["H2O"], [1], 10.0)
            if c.valid is True:
                pass
            else:
                fail()
        except Exception as e:
            fail(e)

    check()

    end(condition=2)
示例#16
0
    def _get_structure(self, data, primitive):
        """
        Generate structure from part of the cif.
        """
        lengths = [
            str2float(data["_cell_length_" + i]) for i in ["a", "b", "c"]
        ]
        angles = [
            str2float(data["_cell_angle_" + i])
            for i in ["alpha", "beta", "gamma"]
        ]
        lattice = Lattice.from_lengths_and_angles(lengths, angles)
        try:
            sympos = data["_symmetry_equiv_pos_as_xyz"]
        except KeyError:
            try:
                sympos = data["_symmetry_equiv_pos_as_xyz_"]
            except KeyError:
                warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. "
                              "Defaulting to P1.")
                sympos = ['x, y, z']
        self.symmetry_operations = [SymmOp.from_xyz_string(s) for s in sympos]

        def parse_symbol(sym):
            # capitalization conventions are not strictly followed, eg Cu will be CU
            m = re.search("([A-Za-z]*)", sym)
            if m:
                return m.group(1)[:2].capitalize()
            return ""

        try:
            oxi_states = {
                data["_atom_type_symbol"][i]:
                str2float(data["_atom_type_oxidation_number"][i])
                for i in range(len(data["_atom_type_symbol"]))
            }
        except (ValueError, KeyError):
            oxi_states = None

        coord_to_species = OrderedDict()
        for i in range(len(data["_atom_site_label"])):
            symbol = parse_symbol(data["_atom_site_label"][i])

            # make sure symbol was properly parsed from _atom_site_label
            # otherwise get it from _atom_site_type_symbol
            try:
                Element(symbol)
            except KeyError:
                symbol = parse_symbol(data["_atom_site_type_symbol"][i])

            if oxi_states is not None:
                # sometimes the site doesn't have the type_symbol.
                # we then hope the type_symbol can be parsed from the label
                if "_atom_site_type_symbol" in data.data.keys():
                    k = data["_atom_site_type_symbol"][i]
                else:
                    k = symbol
                el = Specie(symbol, oxi_states[k])
            else:
                el = Element(symbol)
            x = str2float(data["_atom_site_fract_x"][i])
            y = str2float(data["_atom_site_fract_y"][i])
            z = str2float(data["_atom_site_fract_z"][i])
            try:
                occu = str2float(data["_atom_site_occupancy"][i])
            except (KeyError, ValueError):
                occu = 1
            if occu > 0:
                coord = (x, y, z)
                if coord not in coord_to_species:
                    coord_to_species[coord] = {el: occu}
                else:
                    coord_to_species[coord][el] = occu

        allspecies = []
        allcoords = []

        for coord, species in coord_to_species.items():
            coords = self._unique_coords(coord)
            allcoords.extend(coords)
            allspecies.extend(len(coords) * [species])

        #rescale occupancies if necessary
        for species in allspecies:
            totaloccu = sum(species.values())
            if 1 < totaloccu <= self._occupancy_tolerance:
                for key, value in six.iteritems(species):
                    species[key] = value / totaloccu

        struct = Structure(lattice, allspecies, allcoords)
        if primitive:
            struct = struct.get_primitive_structure().get_reduced_structure()
        return struct.get_sorted_structure()
示例#17
0
    def get_symops(self, data):
        """
        In order to generate symmetry equivalent positions, the symmetry
        operations are parsed. If the symops are not present, the space
        group symbol is parsed, and symops are generated.
        """
        symops = []
        for symmetry_label in [
                "_symmetry_equiv_pos_as_xyz", "_symmetry_equiv_pos_as_xyz_",
                "_space_group_symop_operation_xyz",
                "_space_group_symop_operation_xyz_"
        ]:
            if data.data.get(symmetry_label):
                xyz = data.data.get(symmetry_label)
                if isinstance(xyz, six.string_types):
                    warnings.warn("A 1-line symmetry op P1 CIF is detected!")
                    xyz = [xyz]
                try:
                    symops = [SymmOp.from_xyz_string(s) for s in xyz]
                    break
                except ValueError:
                    continue
        if not symops:
            # Try to parse symbol
            for symmetry_label in [
                    "_symmetry_space_group_name_H-M",
                    "_symmetry_space_group_name_H_M",
                    "_symmetry_space_group_name_H-M_",
                    "_symmetry_space_group_name_H_M_",
                    "_space_group_name_Hall", "_space_group_name_Hall_",
                    "_space_group_name_H-M_alt", "_space_group_name_H-M_alt_",
                    "_symmetry_space_group_name_hall",
                    "_symmetry_space_group_name_hall_",
                    "_symmetry_space_group_name_h-m",
                    "_symmetry_space_group_name_h-m_"
            ]:
                sg = data.data.get(symmetry_label)

                if sg:
                    sg = sub_spgrp(sg)
                    try:
                        spg = space_groups.get(sg)
                        if spg:
                            symops = SpaceGroup(spg).symmetry_ops
                            warnings.warn(
                                "No _symmetry_equiv_pos_as_xyz type key found. "
                                "Spacegroup from %s used." % symmetry_label)
                            break
                    except ValueError:
                        # Ignore any errors
                        pass

                    try:
                        for d in _get_cod_data():
                            if sg == re.sub(r"\s+", "", d["hermann_mauguin"]):
                                xyz = d["symops"]
                                symops = [
                                    SymmOp.from_xyz_string(s) for s in xyz
                                ]
                                warnings.warn(
                                    "No _symmetry_equiv_pos_as_xyz type key found. "
                                    "Spacegroup from %s used." %
                                    symmetry_label)
                                break
                    except Exception as ex:
                        continue

                    if symops:
                        break
        if not symops:
            # Try to parse International number
            for symmetry_label in [
                    "_space_group_IT_number", "_space_group_IT_number_",
                    "_symmetry_Int_Tables_number",
                    "_symmetry_Int_Tables_number_"
            ]:
                if data.data.get(symmetry_label):
                    try:
                        i = int(str2float(data.data.get(symmetry_label)))
                        symops = SpaceGroup.from_int_number(i).symmetry_ops
                        break
                    except ValueError:
                        continue

        if not symops:
            warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. "
                          "Defaulting to P1.")
            symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']]

        return symops
示例#18
0
    def __init__(self, int_symbol):
        """
        Initializes a Space Group from its full or abbreviated international
        symbol. Only standard settings are supported.

        Args:
            int_symbol (str): Full International (e.g., "P2/m2/m2/m") or
                Hermann-Mauguin Symbol ("Pmmm") or abbreviated symbol. The
                notation is a LaTeX-like string, with screw axes being
                represented by an underscore. For example, "P6_3/mmc". Note
                that for rhomohedral cells, the hexagonal setting can be
                accessed by adding a "H", e.g., "R-3mH".
        """
        gen_matrices = get_symm_data("generator_matrices")
        # POINT_GROUP_ENC = SYMM_DATA["point_group_encoding"]
        sgencoding = get_symm_data("space_group_encoding")
        abbrev_sg_mapping = get_symm_data("abbreviated_spacegroup_symbols")
        translations = {k: Fraction(v) for k, v in get_symm_data(
            "translations").items()}
        full_sg_mapping = {
             v["full_symbol"]: k
             for k, v in get_symm_data("space_group_encoding").items()}

        int_symbol = re.sub(" ", "", int_symbol)
        if int_symbol in abbrev_sg_mapping:
            int_symbol = abbrev_sg_mapping[int_symbol]
        elif int_symbol in full_sg_mapping:
            int_symbol = full_sg_mapping[int_symbol]

        for spg in SpaceGroup.SYMM_OPS:
            if re.sub(" ", "", spg["hermann_mauguin"]) == int_symbol or re.sub(":", "", re.sub(" ", "", spg["universal_h_m"])) == int_symbol:
                ops = [SymmOp.from_xyz_string(s) for s in spg["symops"]]
                self.symbol = re.sub(":", "",
                                     re.sub(" ", "", spg["universal_h_m"]))
                if int_symbol in sgencoding:
                    self.full_symbol = sgencoding[int_symbol]["full_symbol"]
                    self.point_group = sgencoding[int_symbol]["point_group"]
                else:
                    self.full_symbol = re.sub(" ", "",
                                              spg["universal_h_m"])
                    self.point_group = spg["schoenflies"]
                self.int_number = spg["number"]
                self.order = len(ops)
                self._symmetry_ops = ops
                break
        else:
            if int_symbol not in sgencoding:
                raise ValueError("Bad international symbol %s" % int_symbol)

            data = sgencoding[int_symbol]

            self.symbol = int_symbol
            # TODO: Support different origin choices.
            enc = list(data["enc"])
            inversion = int(enc.pop(0))
            ngen = int(enc.pop(0))
            symm_ops = [np.eye(4)]
            if inversion:
                symm_ops.append(np.array(
                    [[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0],
                     [0, 0, 0, 1]]))
            for i in range(ngen):
                m = np.eye(4)
                m[:3, :3] = gen_matrices[enc.pop(0)]
                m[0, 3] = translations[enc.pop(0)]
                m[1, 3] = translations[enc.pop(0)]
                m[2, 3] = translations[enc.pop(0)]
                symm_ops.append(m)
            self.generators = symm_ops
            self.full_symbol = data["full_symbol"]
            self.int_number = data["int_number"]
            self.order = data["order"]

            self._symmetry_ops = None
示例#19
0
文件: groups.py 项目: albalu/pymatgen
    def __init__(self, int_symbol):
        """
        Initializes a Space Group from its full or abbreviated international
        symbol. Only standard settings are supported.

        Args:
            int_symbol (str): Full International (e.g., "P2/m2/m2/m") or
                Hermann-Mauguin Symbol ("Pmmm") or abbreviated symbol. The
                notation is a LaTeX-like string, with screw axes being
                represented by an underscore. For example, "P6_3/mmc".
                Alternative settings can be access by adding a ":identifier".
                For example, the hexagonal setting  for rhombohedral cells can be
                accessed by adding a ":H", e.g., "R-3m:H". To find out all
                possible settings for a spacegroup, use the get_settings
                classmethod. Alternative origin choices can be indicated by a
                translation vector, e.g., 'Fm-3m(a-1/4,b-1/4,c-1/4)'.
        """

        int_symbol = re.sub(r" ", "", int_symbol)
        if int_symbol in SpaceGroup.abbrev_sg_mapping:
            int_symbol = SpaceGroup.abbrev_sg_mapping[int_symbol]
        elif int_symbol in SpaceGroup.full_sg_mapping:
            int_symbol = SpaceGroup.full_sg_mapping[int_symbol]

        for spg in SpaceGroup.SYMM_OPS:
            if int_symbol in [spg["hermann_mauguin"], spg["universal_h_m"]]:
                ops = [SymmOp.from_xyz_string(s) for s in spg["symops"]]
                self.symbol = re.sub(r":", "",
                                     re.sub(r" ", "", spg["universal_h_m"]))
                if int_symbol in SpaceGroup.sgencoding:
                    self.full_symbol = SpaceGroup.sgencoding[int_symbol]["full_symbol"]
                    self.point_group = SpaceGroup.sgencoding[int_symbol]["point_group"]
                else:
                    self.full_symbol = re.sub(r" ", "",
                                              spg["universal_h_m"])
                    self.point_group = spg["schoenflies"]
                self.int_number = spg["number"]
                self.order = len(ops)
                self._symmetry_ops = ops
                break
        else:
            if int_symbol not in SpaceGroup.sgencoding:
                raise ValueError("Bad international symbol %s" % int_symbol)

            data = SpaceGroup.sgencoding[int_symbol]

            self.symbol = int_symbol
            # TODO: Support different origin choices.
            enc = list(data["enc"])
            inversion = int(enc.pop(0))
            ngen = int(enc.pop(0))
            symm_ops = [np.eye(4)]
            if inversion:
                symm_ops.append(np.array(
                    [[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0],
                     [0, 0, 0, 1]]))
            for i in range(ngen):
                m = np.eye(4)
                m[:3, :3] = SpaceGroup.gen_matrices[enc.pop(0)]
                m[0, 3] = SpaceGroup.translations[enc.pop(0)]
                m[1, 3] = SpaceGroup.translations[enc.pop(0)]
                m[2, 3] = SpaceGroup.translations[enc.pop(0)]
                symm_ops.append(m)
            self.generators = symm_ops
            self.full_symbol = data["full_symbol"]
            self.int_number = data["int_number"]
            self.order = data["order"]

            self._symmetry_ops = None
示例#20
0
from pymatgen import Structure
from pymatgen import symmetry
from pymatgen.ext.matproj import MPRester
from pymatgen.io.cif import CifWriter
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.core.operations import SymmOp
from IPython.display import Image
with MPRester("izD7mJmnjhUOKyWGtZ") as m:

    # Structure for material id
    structure = m.get_structure_by_material_id("mp-27869")
    w = CifWriter(structure)
    w.write_file('mp-27869.cif')
    sGP = SpacegroupAnalyzer(structure)
    print("2ème élément de symétrie (Ci:0 0 0):")
    Op1 = SymmOp.from_xyz_string("-x, -y, -z")
    print("Effet sur P1 #2:")
    Eff1 = Op1.operate((0, 0, 1 / 2))
    print(Eff1)
    display(Image(filename='sym1.jpg'))
    print("4ème élément de symétrie (3-bar axis:y,-x+y,-z):")
    Op2 = SymmOp.from_xyz_string("y,-x+y,-z")
    print("Effet sur BaO1 #4:")
    Eff2 = Op2.operate((0, 0, 0.24))
    print(Eff2)
    display(Image(filename='sym2.jpg'))
    print("5ème élément de symétrie (3-bar axis:-x+y,-x,z):")
    Op3 = SymmOp.from_xyz_string("-x+y,-x,z")
    print("Effet sur BaO6 #5:")
    Eff3 = Op3.operate((0.67, 0.33, 0.57))
    print(Eff3)
示例#21
0
文件: cif.py 项目: shyamd/pymatgen
    def get_symops(self, data):
        """
        In order to generate symmetry equivalent positions, the symmetry
        operations are parsed. If the symops are not present, the space
        group symbol is parsed, and symops are generated.
        """
        symops = []
        for symmetry_label in ["_symmetry_equiv_pos_as_xyz",
                               "_symmetry_equiv_pos_as_xyz_",
                               "_space_group_symop_operation_xyz",
                               "_space_group_symop_operation_xyz_"]:
            if data.data.get(symmetry_label):
                try:
                    symops = [SymmOp.from_xyz_string(s)
                              for s in data.data.get(symmetry_label)]
                    break
                except ValueError:
                    continue
        if not symops:
            # Try to parse symbol
            for symmetry_label in ["_symmetry_space_group_name_H-M",
                                   "_symmetry_space_group_name_H_M",
                                   "_symmetry_space_group_name_H-M_",
                                   "_symmetry_space_group_name_H_M_",
                                   "_space_group_name_Hall",
                                   "_space_group_name_Hall_",
                                   "_space_group_name_H-M_alt",
                                   "_space_group_name_H-M_alt_",
                                   "_symmetry_space_group_name_hall",
                                   "_symmetry_space_group_name_hall_",
                                   "_symmetry_space_group_name_h-m",
                                   "_symmetry_space_group_name_h-m_"]:

                if data.data.get(symmetry_label):
                    try:
                        spg = space_groups.get(sub_spgrp(
                                        data.data.get(symmetry_label)))
                        if spg:
                            symops = SpaceGroup(spg).symmetry_ops
                            break
                    except ValueError:
                        continue
        if not symops:
            # Try to parse International number
            for symmetry_label in ["_space_group_IT_number",
                                   "_space_group_IT_number_",
                                   "_symmetry_Int_Tables_number",
                                   "_symmetry_Int_Tables_number_"]:
                if data.data.get(symmetry_label):
                    try:
                        i = int(str2float(data.data.get(symmetry_label)))
                        symops = SpaceGroup.from_int_number(i).symmetry_ops
                        break
                    except ValueError:
                        continue

        if not symops:
            warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. "
                          "Defaulting to P1.")
            symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']]

        return symops
示例#22
0
    def get_symops(self, data):
        """
        In order to generate symmetry equivalent positions, the symmetry
        operations are parsed. If the symops are not present, the space
        group symbol is parsed, and symops are generated.
        """
        symops = []
        for symmetry_label in [
                "_symmetry_equiv_pos_as_xyz", "_symmetry_equiv_pos_as_xyz_",
                "_space_group_symop_operation_xyz",
                "_space_group_symop_operation_xyz_"
        ]:
            if data.data.get(symmetry_label):
                try:
                    symops = [
                        SymmOp.from_xyz_string(s)
                        for s in data.data.get(symmetry_label)
                    ]
                    break
                except ValueError:
                    continue
        if not symops:
            # Try to parse symbol
            for symmetry_label in [
                    "_symmetry_space_group_name_H-M",
                    "_symmetry_space_group_name_H_M",
                    "_symmetry_space_group_name_H-M_",
                    "_symmetry_space_group_name_H_M_",
                    "_space_group_name_Hall", "_space_group_name_Hall_",
                    "_space_group_name_H-M_alt", "_space_group_name_H-M_alt_",
                    "_symmetry_space_group_name_hall",
                    "_symmetry_space_group_name_hall_",
                    "_symmetry_space_group_name_h-m",
                    "_symmetry_space_group_name_h-m_"
            ]:

                if data.data.get(symmetry_label):
                    try:
                        spg = space_groups.get(
                            sub_spgrp(data.data.get(symmetry_label)))
                        if spg:
                            symops = SpaceGroup(spg).symmetry_ops
                            break
                    except ValueError:
                        continue
        if not symops:
            # Try to parse International number
            for symmetry_label in [
                    "_space_group_IT_number", "_space_group_IT_number_",
                    "_symmetry_Int_Tables_number",
                    "_symmetry_Int_Tables_number_"
            ]:
                if data.data.get(symmetry_label):
                    try:
                        symops = SpaceGroup.from_int_number(
                            str2float(
                                data.data.get(symmetry_label))).symmetry_ops
                        break
                    except ValueError:
                        continue

        if not symops:
            warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. "
                          "Defaulting to P1.")
            symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']]

        return symops
示例#23
0
def get_symmop(data):
    symops = []
    for symmetry_label in [
            "_symmetry_equiv_pos_as_xyz", "_symmetry_equiv_pos_as_xyz_",
            "_space_group_symop_operation_xyz",
            "_space_group_symop_operation_xyz_"
    ]:
        if data.get(symmetry_label):
            xyz = data.get(symmetry_label)
            if isinstance(xyz, str):
                msg = "A 1-line symmetry op P1 CIF is detected!"
                warnings.warn(msg)
                xyz = [xyz]
            try:
                symops = [SymmOp.from_xyz_string(s) for s in xyz]
                break
            except ValueError:
                continue
    if not symops:
        # Try to parse symbol
        for symmetry_label in [
                "_symmetry_space_group_name_H-M",
                "_symmetry_space_group_name_H_M",
                "_symmetry_space_group_name_H-M_",
                "_symmetry_space_group_name_H_M_", "_space_group_name_Hall",
                "_space_group_name_Hall_", "_space_group_name_H-M_alt",
                "_space_group_name_H-M_alt_",
                "_symmetry_space_group_name_hall",
                "_symmetry_space_group_name_hall_",
                "_symmetry_space_group_name_h-m",
                "_symmetry_space_group_name_h-m_"
        ]:
            sg = data.get(symmetry_label)

            if sg:
                sg = sub_spgrp(sg)
                try:
                    spg = space_groups.get(sg)
                    if spg:
                        symops = SpaceGroup(spg).symmetry_ops
                        msg = "No _symmetry_equiv_pos_as_xyz type key found. " \
                              "Spacegroup from %s used." % symmetry_label
                        warnings.warn(msg)
                        break
                except ValueError:
                    # Ignore any errors
                    pass

                try:
                    for d in _get_cod_data():
                        if sg == re.sub(r"\s+", "", d["hermann_mauguin"]):
                            xyz = d["symops"]
                            symops = [SymmOp.from_xyz_string(s) for s in xyz]
                            msg = "No _symmetry_equiv_pos_as_xyz type key found. " \
                                  "Spacegroup from %s used." % symmetry_label
                            warnings.warn(msg)
                            break
                except Exception:
                    continue

                if symops:
                    break
    if not symops:
        # Try to parse International number
        for symmetry_label in [
                "_space_group_IT_number", "_space_group_IT_number_",
                "_symmetry_Int_Tables_number", "_symmetry_Int_Tables_number_"
        ]:
            if data.get(symmetry_label):
                try:
                    i = int(braket2float(data.get(symmetry_label)))
                    symops = SpaceGroup.from_int_number(i).symmetry_ops
                    break
                except ValueError:
                    continue

    if not symops:
        msg = "No _symmetry_equiv_pos_as_xyz type key found. " \
              "Defaulting to P1."
        warnings.warn(msg)
        symops = [SymmOp.from_xyz_string(s) for s in ['x', 'y', 'z']]

    return symops
示例#24
0
    def __init__(self, int_symbol):
        """
        Initializes a Space Group from its full or abbreviated international
        symbol. Only standard settings are supported.

        Args:
            int_symbol (str): Full International (e.g., "P2/m2/m2/m") or
                Hermann-Mauguin Symbol ("Pmmm") or abbreviated symbol. The
                notation is a LaTeX-like string, with screw axes being
                represented by an underscore. For example, "P6_3/mmc".
                Alternative settings can be access by adding a ":identifier".
                For example, the hexagonal setting  for rhombohedral cells can be
                accessed by adding a ":H", e.g., "R-3m:H". To find out all
                possible settings for a spacegroup, use the get_settings
                classmethod. Alternative origin choices can be indicated by a
                translation vector, e.g., 'Fm-3m(a-1/4,b-1/4,c-1/4)'.
        """

        int_symbol = re.sub(r" ", "", int_symbol)
        if int_symbol in SpaceGroup.abbrev_sg_mapping:
            int_symbol = SpaceGroup.abbrev_sg_mapping[int_symbol]
        elif int_symbol in SpaceGroup.full_sg_mapping:
            int_symbol = SpaceGroup.full_sg_mapping[int_symbol]

        for spg in SpaceGroup.SYMM_OPS:
            if int_symbol in [spg["hermann_mauguin"], spg["universal_h_m"]]:
                ops = [SymmOp.from_xyz_string(s) for s in spg["symops"]]
                self.symbol = re.sub(r":", "",
                                     re.sub(r" ", "", spg["universal_h_m"]))
                if int_symbol in SpaceGroup.sgencoding:
                    self.full_symbol = SpaceGroup.sgencoding[int_symbol][
                        "full_symbol"]
                    self.point_group = SpaceGroup.sgencoding[int_symbol][
                        "point_group"]
                else:
                    self.full_symbol = re.sub(r" ", "", spg["universal_h_m"])
                    self.point_group = spg["schoenflies"]
                self.int_number = spg["number"]
                self.order = len(ops)
                self._symmetry_ops = ops
                break
        else:
            if int_symbol not in SpaceGroup.sgencoding:
                raise ValueError("Bad international symbol %s" % int_symbol)

            data = SpaceGroup.sgencoding[int_symbol]

            self.symbol = int_symbol
            # TODO: Support different origin choices.
            enc = list(data["enc"])
            inversion = int(enc.pop(0))
            ngen = int(enc.pop(0))
            symm_ops = [np.eye(4)]
            if inversion:
                symm_ops.append(
                    np.array([[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0],
                              [0, 0, 0, 1]]))
            for i in range(ngen):
                m = np.eye(4)
                m[:3, :3] = SpaceGroup.gen_matrices[enc.pop(0)]
                m[0, 3] = SpaceGroup.translations[enc.pop(0)]
                m[1, 3] = SpaceGroup.translations[enc.pop(0)]
                m[2, 3] = SpaceGroup.translations[enc.pop(0)]
                symm_ops.append(m)
            self.generators = symm_ops
            self.full_symbol = data["full_symbol"]
            self.point_group = data["point_group"]
            self.int_number = data["int_number"]
            self.order = data["order"]

            self._symmetry_ops = None
示例#25
0
    def _get_structure(self, data, primitive):
        """
        Generate structure from part of the cif.
        """
        lengths = [str2float(data["_cell_length_" + i])
                   for i in ["a", "b", "c"]]
        angles = [str2float(data["_cell_angle_" + i])
                  for i in ["alpha", "beta", "gamma"]]
        lattice = Lattice.from_lengths_and_angles(lengths, angles)
        try:
            sympos = data["_symmetry_equiv_pos_as_xyz"]
        except KeyError:
            try:
                sympos = data["_symmetry_equiv_pos_as_xyz_"]
            except KeyError:
                warnings.warn("No _symmetry_equiv_pos_as_xyz type key found. "
                              "Defaulting to P1.")
                sympos = ['x, y, z']
        self.symmetry_operations = [SymmOp.from_xyz_string(s) for s in sympos]

        def parse_symbol(sym):
            m = re.search("([A-Z][a-z]*)", sym)
            if m:
                return m.group(1)
            return ""

        try:
            oxi_states = {
                data["_atom_type_symbol"][i]:
                str2float(data["_atom_type_oxidation_number"][i])
                for i in range(len(data["_atom_type_symbol"]))}
        except (ValueError, KeyError):
            oxi_states = None

        coord_to_species = OrderedDict()

        for i in range(len(data["_atom_site_type_symbol"])):
            symbol = parse_symbol(data["_atom_site_type_symbol"][i])
            if oxi_states is not None:
                el = Specie(symbol,
                            oxi_states[data["_atom_site_type_symbol"][i]])
            else:
                el = Element(symbol)
            x = str2float(data["_atom_site_fract_x"][i])
            y = str2float(data["_atom_site_fract_y"][i])
            z = str2float(data["_atom_site_fract_z"][i])
            try:
                occu = str2float(data["_atom_site_occupancy"][i])
            except (KeyError, ValueError):
                occu = 1
            if occu > 0:
                coord = (x, y, z)
                if coord not in coord_to_species:
                    coord_to_species[coord] = {el: occu}
                else:
                    coord_to_species[coord][el] = occu

        allspecies = []
        allcoords = []

        for coord, species in coord_to_species.items():
            coords = self._unique_coords(coord)
            allcoords.extend(coords)
            allspecies.extend(len(coords) * [species])

        #rescale occupancies if necessary
        for species in allspecies:
            totaloccu = sum(species.values())
            if 1 < totaloccu <= self._occupancy_tolerance:
                for key, value in six.iteritems(species):
                    species[key] = value / totaloccu

        struct = Structure(lattice, allspecies, allcoords)
        if primitive:
            struct = struct.get_primitive_structure().get_reduced_structure()
        return struct.get_sorted_structure()