示例#1
0
 def test_reciprocal(self):
     '''check calculation of reciprocal lattice.'''
     r1 = self.lattice.reciprocal()
     self.assertEqual((1, 1, 1, 90, 90, 90), r1.abcABG())
     L2 = Lattice(2, 4, 8, 90, 90, 90)
     r2 = L2.reciprocal()
     self.assertEqual((0.5, 0.25, 0.125, 90, 90, 90), r2.abcABG())
     rr2 = r2.reciprocal()
     self.assertTrue(numpy.array_equal(L2.base, rr2.base))
     return
示例#2
0
 def test_is_hexagonal(self):
     p1 = Phase(
         point_group="321",
         structure=Structure(lattice=Lattice(1, 1, 2, 90, 90, 120)),
     )
     p2 = Phase(
         point_group="m-3m",
         structure=Structure(lattice=Lattice(1, 1, 1, 90, 90, 90)),
     )
     assert p1.is_hexagonal
     assert not p2.is_hexagonal
示例#3
0
 def __init__(self,
              central_atom="Cu",
              outer_atoms="Cu",
              shell_distance=2.54,
              num_shells=1,
              anti=False,
              position=[0, 0, 0]):
     """
     Parameters
     ______________
     central_atom: str
         The element of the center atom
     outer_atoms: str or list
         The element of list of elements for the outer atoms of the icosahedron
     shell_distance: float
         The distance from one atom to each successive shell in the cluster.
     num_shells: int
         The number of shells in the icosahedron
     anti: boolean
         If the cluster should be an anti mackay cluster instead of a mackay cluster
     """
     super().__init__(position=position)
     self.initial_atoms = _create_ico(central_atom=central_atom,
                                      outer_atoms=outer_atoms,
                                      shell_distance=shell_distance,
                                      num_shells=num_shells,
                                      anti=anti)
     for i in self.initial_atoms:
         self.append(i)
     self.radius = num_shells * shell_distance
     self.lattice = Lattice(a=1, b=1, c=1, alpha=90, beta=90, gamma=90)
示例#4
0
def _get_phase(data_group):
    """Return phase information from a phase data group in an EMsoft dot
    product file.

    Parameters
    ----------
    data_group : h5py.Group
        HDF5 group with the property data sets.

    Returns
    -------
    name : str
        Phase name.
    point_group : str
        Phase point group.
    structure : diffpy.structure.Structure
        Phase structure.
    """
    name = re.search(r"([A-z0-9]+)",
                     data_group["MaterialName"][:][0].decode()).group(1)
    point_group = re.search(r"\[([A-z0-9]+)\]",
                            data_group["Point Group"][:][0].decode()).group(1)
    lattice = Lattice(*tuple(
        data_group[f"Lattice Constant {i}"][:]
        for i in ["a", "b", "c", "alpha", "beta", "gamma"]))
    structure = Structure(title=name, lattice=lattice)
    return name, point_group, structure
示例#5
0
def get_reciprocal_metric_tensor(lattice: Lattice) -> np.ndarray:
    """Reciprocal metric tensor as defined in EMsoft.

    Parameters
    ----------
    lattice
        Crystal structure lattice.

    Returns
    -------
    np.ndarray
    """
    a, b, c = lattice.abcABG()[:3]
    ca, cb, cg = lattice.ca, lattice.cb, lattice.cg
    sa, sb, sg = lattice.sa, lattice.sb, lattice.sg
    terms_12_21 = a * b * (c ** 2) * (ca * cb - cg)
    terms_13_31 = a * (b ** 2) * c * (cg * ca - cb)
    terms_23_32 = (a ** 2) * b * c * (cb * cg - ca)
    return np.array(
        [
            [(b * c * sa) ** 2, terms_12_21, terms_13_31],
            [terms_12_21, (a * c * sb) ** 2, terms_23_32],
            [terms_13_31, terms_23_32, (a * b * sg) ** 2],
        ]
    ) / np.linalg.det(lattice.metrics)
示例#6
0
    def _parse_lattice(self, block):
        """Obtain lattice parameters from a CifBlock.
        This method updates self.stru.lattice.

        block -- instance of CifBlock

        No return value.
        """
        if '_cell_length_a' not in block: return
        # obtain lattice parameters
        try:
            latpars = (
                leading_float(block['_cell_length_a']),
                leading_float(block['_cell_length_b']),
                leading_float(block['_cell_length_c']),
                leading_float(block['_cell_angle_alpha']),
                leading_float(block['_cell_angle_beta']),
                leading_float(block['_cell_angle_gamma']),
            )
        except KeyError as err:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            emsg = str(err)
            e = StructureFormatError(emsg)
            six.reraise(StructureFormatError, e, exc_traceback)
        self.stru.lattice = Lattice(*latpars)
        return
示例#7
0
 def test__set_lattice(self):
     """check Structure._set_lattice()
     """
     lat = Lattice()
     self.stru.lattice = lat
     self.assertEqual(2 * [lat], [a.lattice for a in self.stru])
     return
示例#8
0
def nisph20():
    from diffpy.structure import Lattice, loadStructure
    from diffpy.structure.tests.testutils import datafile
    from diffpy.structure.expansion.makeellipsoid import makeSphere
    ni = loadStructure(datafile('Ni.stru'), 'pdffit')
    sph = makeSphere(ni, 20 / 2.0)
    sph.placeInLattice(Lattice())
    return sph
示例#9
0
def nickel_phase():
    return Phase(
        name="nickel",
        space_group=225,
        structure=Structure(
            lattice=Lattice(3.5236, 3.5236, 3.5236, 90, 90, 90),
            atoms=[Atom(xyz=[0, 0, 0], atype="Ni", Uisoequiv=0.006332)],
        ),
    )
示例#10
0
    def parseLines(self, lines):
        """Parse list of lines in DISCUS format.

        Return PDFFitStructure instance or raise StructureFormatError.
        """
        self.lines = lines
        ilines = self._linesIterator()
        self.stru = PDFFitStructure()
        record_parsers = {
            "cell" : self._parse_cell,
            "format" : self._parse_format,
            "generator" : self._parse_not_implemented,
            "molecule" : self._parse_not_implemented,
            "ncell" : self._parse_ncell,
            "spcgr" : self._parse_spcgr,
            "symmetry" : self._parse_not_implemented,
            "title" : self._parse_title,
            "shape" : self._parse_shape,
        }
        try:
            # parse header
            for self.line in ilines:
                words = self.line.split()
                if not words or words[0][0] == '#': continue
                if words[0] == 'atoms':             break
                rp = record_parsers.get(words[0], self._parse_unknown_record)
                rp(words)
            # check if cell has been defined
            if not self.cell_read:
                emsg = "%d: unit cell not defined" % self.nl
                raise StructureFormatError(emsg)
            # parse atoms
            for self.line in ilines:
                words = self.line.replace(',', ' ').split()
                if not words or words[0][0] == '#': continue
                self._parse_atom(words)
            # self consistency check
            exp_natoms = reduce(lambda x,y : x*y, self.stru.pdffit['ncell'])
            # only check if ncell record exists
            if self.ncell_read and exp_natoms != len(self.stru):
                emsg = 'Expected %d atoms, read %d.' % \
                    (exp_natoms, len(self.stru))
                raise StructureFormatError(emsg)
            # take care of superlattice
            if self.stru.pdffit['ncell'][:3] != [1,1,1]:
                latpars = list(self.stru.lattice.abcABG())
                superlatpars = [ latpars[i]*self.stru.pdffit['ncell'][i]
                                 for i in range(3) ] + latpars[3:]
                superlattice = Lattice(*superlatpars)
                self.stru.placeInLattice(superlattice)
                self.stru.pdffit['ncell'] = [1, 1, 1, exp_natoms]
        except (ValueError, IndexError):
            exc_type, exc_value, exc_traceback = sys.exc_info()
            emsg = "%d: file is not in DISCUS format" % self.nl
            e = StructureFormatError(emsg)
            six.reraise(StructureFormatError, e, exc_traceback)
        return self.stru
示例#11
0
 def test__get_lattice(self):
     """check Structure._get_lattice()
     """
     lat = Lattice()
     stru = Structure()
     self.assertEqual((1, 1, 1, 90, 90, 90), stru.lattice.abcABG())
     stru2 = Structure(lattice=lat)
     self.assertTrue(lat is stru2.lattice)
     return
示例#12
0
 def __init__(self, dimensions=(20, 20, 20)):
     """Initializes the simulation cube in nm
     Parameters
     --------------
     dimensions: tuple
         The dimensions of the cube to simulate.
     """
     self.clusters = []
     self.lattice = Lattice(a=1, b=1, c=1, alpha=90, beta=90, gamma=90)
     self.dimensions = np.array(dimensions)
示例#13
0
 def test_placeInLattice(self):
     """check Structure.placeInLattice() -- conversion of coordinates
     """
     stru = self.stru
     new_lattice = Lattice(.5, .5, .5, 90, 90, 60)
     stru.placeInLattice(new_lattice)
     a0 = stru[0]
     self.assertTrue(numpy.allclose(a0.xyz, [0.0, 0.0, 0.0]))
     a1 = stru[1]
     self.assertTrue(numpy.allclose(a1.xyz, [2.0, 0.0, 2.0]))
def _dummyAtomWithBiso(crystal, biso):
    from numpy import degrees
    from diffpy.structure import Lattice, Atom
    lattice = Lattice(crystal.a, crystal.b, crystal.c,
                      degrees(crystal.alpha),
                      degrees(crystal.beta),
                      degrees(crystal.gamma))
    a = Atom('X', anisotropy=False, lattice=lattice)
    a.Bisoequiv = biso
    return a
示例#15
0
 def test_writeStr_xyz(self):
     """check string representation of normal xyz file"""
     stru = self.stru
     stru.title = "test of writeStr"
     stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0)
     stru[:] = [Atom('H', [1., 1., 1.]), Atom('Cl', [3., 2., 1.])]
     s1 = stru.writeStr(self.format)
     s1 = re.sub('[ \t]+', ' ', s1)
     s0 = "2\n%s\nH 1 2 3\nCl 3 4 3\n" % stru.title
     self.assertEqual(s1, s0)
     return
示例#16
0
 def test___repr__(self):
     """Test representation of DiffpyStructureParSet objects.
     """
     lat = Lattice(3, 3, 2, 90, 90, 90)
     atom = Atom("C", [0, 0.2, 0.5])
     stru = Structure([atom], lattice=lat)
     dsps = DiffpyStructureParSet("dsps", stru)
     self.assertEqual(repr(stru), repr(dsps))
     self.assertEqual(repr(lat), repr(dsps.lattice))
     self.assertEqual(repr(atom), repr(dsps.atoms[0]))
     return
示例#17
0
def ferrite_phase():
    return Phase(
        name="ferrite",
        space_group=229,
        structure=Structure(
            lattice=Lattice(2.8665, 2.8665, 2.8665, 90, 90, 90),
            atoms=[
                Atom(xyz=[0, 0, 0], atype="Fe", Uisoequiv=0.006332),
                Atom(xyz=[0.5, 0.5, 0.5], atype="Fe", Uisoequiv=0.006332),
            ],
        ),
    )
示例#18
0
 def test___init__(self):
     '''Check Lattice.__init__ processing of arguments.
     '''
     self.assertRaises(ValueError, Lattice,
                       self.lattice, c=4)
     self.assertRaises(ValueError, Lattice,
                       base=self.lattice.base,
                       baserot=self.lattice.baserot)
     self.assertRaises(ValueError, Lattice, 1, 2, 3)
     self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90)
     L0 = self.lattice
     L0.setLatBase(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]]))
     L1 = Lattice(L0)
     self.assertTrue(numpy.array_equal(L0.base, L1.base))
     L2 = Lattice(base=L0.base)
     self.assertTrue(numpy.array_equal(L0.base, L2.base))
     self.assertTrue(numpy.array_equal(L0.isotropicunit, L2.isotropicunit))
     L3 = Lattice(*L0.abcABG(), baserot=L0.baserot)
     self.assertTrue(numpy.allclose(L0.base, L3.base))
     self.assertTrue(numpy.allclose(L0.isotropicunit, L3.isotropicunit))
     return
示例#19
0
    def test_load_emsoft(
        self,
        temp_emsoft_h5ebsd_file,
        map_shape,
        step_sizes,
        example_rot,
        n_top_matches,
        refined,
    ):
        xmap = load(temp_emsoft_h5ebsd_file.filename, refined=refined)

        assert xmap.shape == map_shape
        assert (xmap.dy, xmap.dx) == step_sizes
        if refined:
            n_top_matches = 1
        assert xmap.rotations_per_point == n_top_matches

        # Properties
        expected_props = [
            "AvDotProductMap",
            "CI",
            "CIMap",
            "IQ",
            "IQMap",
            "ISM",
            "ISMap",
            "KAM",
            "OSM",
            "TopDotProductList",
            "TopMatchIndices",
        ]
        if refined:
            expected_props += ["RefinedDotProducts"]
        actual_props = list(xmap.prop.keys())
        actual_props.sort()
        expected_props.sort()
        assert actual_props == expected_props

        assert xmap.phases["austenite"].structure == Structure(
            title="austenite",
            lattice=Lattice(a=3.595,
                            b=3.595,
                            c=3.595,
                            alpha=90,
                            beta=90,
                            gamma=90),
        )

        # Ensure Euler angles in degrees are read correctly from file
        if not refined:
            assert np.rad2deg(xmap.rotations.to_euler().min()) >= 150
            assert np.rad2deg(xmap.rotations.to_euler().max()) <= 160
示例#20
0
 def setUp(self):
     self.stru = Structure(
         [Atom('C', [0, 0, 0]), Atom('C', [1, 1, 1])],
         lattice=Lattice(1, 1, 1, 90, 90, 120))
     if not self._loaded_structures:
         self._loaded_structures.update([
             ('cdse', Structure(filename=cdsefile)),
             ('tei', Structure(filename=teifile)),
             ('pbte', Structure(filename=pbtefile)),
         ])
     self.__dict__.update(self._loaded_structures)
     self.places = 12
     return
示例#21
0
def silicon_carbide_phase():
    """Silicon Carbide 4H polytype (hexagonal, space group 186)."""
    return Phase(
        space_group=186,
        structure=Structure(
            lattice=Lattice(3.073, 3.073, 10.053, 90, 90, 120),
            atoms=[
                Atom(atype="Si", xyz=[0, 0, 0]),
                Atom(atype="Si", xyz=[0.33, 0.667, 0.25]),
                Atom(atype="C", xyz=[0, 0, 0.188]),
                Atom(atype="C", xyz=[0.333, 0.667, 0.438]),
            ],
        ),
    )
示例#22
0
 def test_write_xyz(self):
     """check writing of normal xyz file"""
     stru = self.stru
     stru.title = "test of writeStr"
     stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0)
     stru[:] = [Atom('H', [1., 1., 1.]), Atom('Cl', [3., 2., 1.])]
     filename = self.mktmpfile()
     stru.write(filename, self.format)
     with open(filename) as fp:
         f_s = fp.read()
     f_s = re.sub('[ \t]+', ' ', f_s)
     s_s = "2\n%s\nH 1 2 3\nCl 3 4 3\n" % stru.title
     self.assertEqual(f_s, s_s)
     return
示例#23
0
 def test_latpar_properties(self):
     '''check assignment to a, b, c, alpha, beta, gamma.
     '''
     lat = self.lattice
     lat.a = 2
     lat.b = 4
     lat.c = 6
     lat.alpha = 80
     lat.beta = 100
     lat.gamma = 120
     lat1 = Lattice(2, 4, 6, 80, 100, 120)
     self.assertAlmostEqual(-0.5, lat.cg, self.places)
     self.assertTrue(numpy.array_equal(lat1.base, lat.base))
     return
示例#24
0
 def test_writeStr_rawxyz(self):
     """check writing of normal xyz file"""
     stru = self.stru
     stru.title = "test of writeStr"
     stru.lattice = Lattice(1.0, 2.0, 3.0, 90.0, 90.0, 90.0)
     # plain version
     stru[:] = [Atom('H', [1., 1., 1.])]
     s1 = stru.writeStr(self.format)
     s1 = re.sub('[ \t]+', ' ', s1)
     s0 = "H 1 2 3\n"
     # brutal raw version
     stru[0].element = ""
     s1 = stru.writeStr(self.format)
     s0 = "1 2 3\n"
     self.assertEqual(s1, s0)
     return
示例#25
0
    def test_load_emsoft(
        self,
        temp_emsoft_h5ebsd_file,
        map_shape,
        step_sizes,
        example_rot,
        n_top_matches,
        refined,
    ):
        cm = load(temp_emsoft_h5ebsd_file.filename, refined=refined)

        assert cm.shape == map_shape
        assert (cm.dy, cm.dx) == step_sizes
        if refined:
            n_top_matches = 1
        assert cm.rotations_per_point == n_top_matches

        # Properties
        expected_props = [
            "AvDotProductMap",
            "CI",
            "CIMap",
            "IQ",
            "IQMap",
            "ISM",
            "ISMap",
            "KAM",
            "OSM",
            "TopDotProductList",
            "TopMatchIndices",
        ]
        if refined:
            expected_props += ["RefinedDotProducts"]
        actual_props = list(cm.prop.keys())
        actual_props.sort()
        expected_props.sort()
        assert actual_props == expected_props

        assert cm.phases["austenite"].structure == Structure(
            title="austenite",
            lattice=Lattice(a=3.595,
                            b=3.595,
                            c=3.595,
                            alpha=90,
                            beta=90,
                            gamma=90),
        )
示例#26
0
 def __copy__(self, target=None):
     '''Create a deep copy of this instance.
     target   -- optional target instance for copying, useful for
                 copying a derived class.  Defaults to new instance
                 of the same type as self.
     Return a duplicate instance of this object.
     '''
     if target is None:
         target = Cluster()
     elif target is self:
         return target
     # copy attributes as appropriate:
     target.title = self.title
     target.lattice = Lattice(self.lattice)
     target.pdffit = copymod.deepcopy(self.pdffit)
     # copy all atoms to the target
     target[:] = self
     return target
示例#27
0
def dict2lattice(dictionary):
    """Get a :class:`diffpy.structure.Lattice` object from a dictionary.

    Parameters
    ----------
    dictionary : dict
        Dictionary with lattice information.

    Returns
    -------
    Lattice
    """
    dictionary = copy.deepcopy(dictionary)
    lattice_dict = {
        k: v
        for k, v in zip(["a", "b", "c", "alpha", "beta", "gamma"], dictionary["abcABG"])
    }
    lattice_dict["baserot"] = dictionary["baserot"]
    return Lattice(**lattice_dict)
示例#28
0
def get_direct_structure_matrix(lattice: Lattice) -> np.ndarray:
    """Direct structure matrix as defined in EMsoft.

    Parameters
    ----------
    lattice
        Crystal structure lattice.

    Returns
    -------
    """
    a, b, c = lattice.abcABG()[:3]
    ca, cb, cg = lattice.ca, lattice.cb, lattice.cg
    sa, sb, sg = lattice.sa, lattice.sb, lattice.sg
    return np.array([
        [a, b * cg, c * cb],
        [0, b * sg, -c * (cb * cg - ca) / sg],
        [0, 0, lattice.volume / (a * b * sg)],
    ])
class TestCrystallographicMatrices:
    @pytest.mark.parametrize(
        "lattice, desired_matrix",
        [
            (Lattice(3.52, 3.52, 3.52, 90, 90, 90), np.eye(3) / 3.52),
            (
                Lattice(3.52, 3.52, 10.5, 90, 90, 120),
                np.array([[0.284, 0, 0], [0.164, 0.328, 0], [0, 0, 0.095]]),
            ),
        ],
    )
    def test_reciprocal_structure_matrix(self, lattice, desired_matrix):
        assert np.allclose(
            get_reciprocal_structure_matrix(lattice), desired_matrix, atol=1e-3
        )

    @pytest.mark.parametrize(
        "lattice, desired_matrix",
        [
            (Lattice(3.52, 3.52, 3.52, 90, 90, 90), np.eye(3) * 3.52),
            (
                Lattice(3.52, 3.52, 10.5, 90, 90, 120),
                np.array([[3.52, -1.76, 0], [0, 3.048, 0], [0, 0, 10.5]]),
            ),
        ],
    )
    def test_direct_structure_matrix(self, lattice, desired_matrix):
        assert np.allclose(
            get_direct_structure_matrix(lattice), desired_matrix, atol=1e-3
        )

    @pytest.mark.parametrize(
        "lattice, desired_matrix",
        [
            (Lattice(3.52, 3.52, 3.52, 90, 90, 90), np.eye(3) * 0.080),
            (
                Lattice(3.52, 3.52, 10.5, 90, 90, 120),
                np.array(
                    [[0.107, 0.053, -0], [0.053, 0.107, -0], [-0, -0, 0.009]]
                ),
            ),
        ],
    )
    def test_reciprocal_metric_tensor(self, lattice, desired_matrix):
        recip_metrics = get_reciprocal_metric_tensor(lattice)
        assert np.allclose(
            recip_metrics, lattice.reciprocal().metrics, atol=1e-3
        )
        assert np.allclose(recip_metrics, desired_matrix, atol=1e-3)
示例#30
0
 def test___init__(self):
     """check Structure.__init__()
     """
     atoms = [Atom('C', [0, 0, 0]), Atom('C', [0.5, 0.5, 0.5])]
     self.assertRaises(ValueError, Structure, atoms, filename=teifile)
     self.assertRaises(ValueError,
                       Structure,
                       lattice=Lattice(),
                       filename=teifile)
     self.assertRaises(ValueError,
                       Structure,
                       title='test',
                       filename=teifile)
     stru1 = Structure(title='my title')
     self.assertEqual('my title', stru1.title)
     stru2a = Structure(atoms)
     stru2b = Structure(iter(atoms))
     stru2c = Structure(a for a in atoms)
     s2a = str(stru2a)
     self.assertEqual(s2a, str(stru2b))
     self.assertEqual(s2a, str(stru2c))
     return
示例#31
0
 def setUp(self):
     self.lattice = Lattice()
     self.places = 12
     return
示例#32
0
class TestLattice(unittest.TestCase):
    """test methods of Lattice class"""

    def setUp(self):
        self.lattice = Lattice()
        self.places = 12
        return


    def test___init__(self):
        '''Check Lattice.__init__ processing of arguments.
        '''
        self.assertRaises(ValueError, Lattice,
                          self.lattice, c=4)
        self.assertRaises(ValueError, Lattice,
                          base=self.lattice.base,
                          baserot=self.lattice.baserot)
        self.assertRaises(ValueError, Lattice, 1, 2, 3)
        self.assertRaises(ValueError, Lattice, 1, 2, 3, 80, 90)
        L0 = self.lattice
        L0.setLatBase(L0.cartesian([[1, 1, 0], [0, 1, 1], [1, 0, 1]]))
        L1 = Lattice(L0)
        self.assertTrue(numpy.array_equal(L0.base, L1.base))
        L2 = Lattice(base=L0.base)
        self.assertTrue(numpy.array_equal(L0.base, L2.base))
        self.assertTrue(numpy.array_equal(L0.isotropicunit, L2.isotropicunit))
        L3 = Lattice(*L0.abcABG(), baserot=L0.baserot)
        self.assertTrue(numpy.allclose(L0.base, L3.base))
        self.assertTrue(numpy.allclose(L0.isotropicunit, L3.isotropicunit))
        return


    def test_setLatPar(self):
        """check calculation of standard unit cell vectors"""
        from numpy import dot
        from math import radians, sqrt, cos
        norm = lambda x : sqrt(sum([xi**2 for xi in x]))
        cosd = lambda x : cos(radians(x))
        self.lattice.setLatPar(1.0, 2.0, 3.0, 80, 100, 120)
        base = self.lattice.base
        self.assertAlmostEqual(1.0, norm(base[0]), self.places)
        self.assertAlmostEqual(2.0, norm(base[1]), self.places)
        self.assertAlmostEqual(3.0, norm(base[2]), self.places)
        self.assertAlmostEqual(cosd(80.0),
                dot(base[1],base[2])/(2*3), self.places)
        self.assertAlmostEqual(cosd(100.0),
                dot(base[0],base[2])/(1*3), self.places)
        self.assertAlmostEqual(cosd(120.0),
                dot(base[0],base[1])/(1*2), self.places)
        return


    def test_latpar_properties(self):
        '''check assignment to a, b, c, alpha, beta, gamma.
        '''
        lat = self.lattice
        lat.a = 2
        lat.b = 4
        lat.c = 6
        lat.alpha = 80
        lat.beta = 100
        lat.gamma = 120
        lat1 = Lattice(2, 4, 6, 80, 100, 120)
        self.assertAlmostEqual(-0.5, lat.cg, self.places)
        self.assertTrue(numpy.array_equal(lat1.base, lat.base))
        return


    def test_readonly_properties(self):
        '''Check that read-only properties are indeed such.
        '''
        lat = self.lattice
        lat.b = 2
        lat.c = 6
        self.assertEqual(1.0, lat.unitvolume)
        self.assertRaises(AttributeError, setattr,
                          lat, 'unitvolume', 3.33)
        self.assertEqual(12, lat.volume)
        self.assertRaises(AttributeError, setattr,
                          lat, 'volume', 3.33)
        self.assertEqual(0.0, lat.ca)
        self.assertRaises(AttributeError, setattr,
                lat, 'ca', 3.33)
        self.assertEqual(0.0, lat.cb)
        self.assertRaises(AttributeError, setattr,
                lat, 'cb', 3.33)
        self.assertEqual(0.0, lat.cg)
        self.assertRaises(AttributeError, setattr,
                lat, 'cg', 3.33)
        self.assertEqual(1.0, lat.sa)
        self.assertRaises(AttributeError, setattr,
                lat, 'sa', 3.33)
        self.assertEqual(1.0, lat.sb)
        self.assertRaises(AttributeError, setattr,
                lat, 'sb', 3.33)
        self.assertEqual(1.0, lat.sg)
        self.assertRaises(AttributeError, setattr,
                lat, 'sg', 3.33)
        self.assertEqual(1.0, lat.ar)
        self.assertRaises(AttributeError, setattr,
                lat, 'ar', 3.33)
        self.assertEqual(0.5, lat.br)
        self.assertRaises(AttributeError, setattr,
                lat, 'br', 3.33)
        self.assertAlmostEqual(1.0/6, lat.cr, self.places)
        self.assertRaises(AttributeError, setattr,
                lat, 'cr', 3.33)
        self.assertEqual(90.0, lat.alphar)
        self.assertRaises(AttributeError, setattr,
                lat, 'alphar', 3.33)
        self.assertEqual(90.0, lat.betar)
        self.assertRaises(AttributeError, setattr,
                lat, 'betar', 3.33)
        self.assertEqual(90.0, lat.gammar)
        self.assertRaises(AttributeError, setattr,
                lat, 'gammar', 3.33)
        self.assertEqual(0.0, lat.car)
        self.assertRaises(AttributeError, setattr,
                lat, 'car', 3.33)
        self.assertEqual(0.0, lat.cbr)
        self.assertRaises(AttributeError, setattr,
                lat, 'cbr', 3.33)
        self.assertEqual(0.0, lat.cgr)
        self.assertRaises(AttributeError, setattr,
                lat, 'cgr', 3.33)
        self.assertEqual(1.0, lat.sar)
        self.assertRaises(AttributeError, setattr,
                lat, 'sar', 3.33)
        self.assertEqual(1.0, lat.sbr)
        self.assertRaises(AttributeError, setattr,
                lat, 'sbr', 3.33)
        self.assertEqual(1.0, lat.sgr)
        self.assertRaises(AttributeError, setattr,
                lat, 'sgr', 3.33)
        return


    def test_setLatBase(self):
        """check calculation of unit cell rotation"""
        base = numpy.array([[1.0,  1.0,  0.0],
                            [0.0,  1.0,  1.0],
                            [1.0,  0.0,  1.0]])
        self.lattice.setLatBase(base)
        self.assertAlmostEqual(self.lattice.a, numpy.sqrt(2.0), self.places)
        self.assertAlmostEqual(self.lattice.b, numpy.sqrt(2.0), self.places)
        self.assertAlmostEqual(self.lattice.c, numpy.sqrt(2.0), self.places)
        self.assertAlmostEqual(self.lattice.alpha, 60.0, self.places)
        self.assertAlmostEqual(self.lattice.beta, 60.0, self.places)
        self.assertAlmostEqual(self.lattice.gamma, 60.0, self.places)
        detR0 = numalg.det(self.lattice.baserot)
        self.assertAlmostEqual(detR0, 1.0, self.places)
        # try if rotation matrix works
        self.assertEqual(numpy.all(base == self.lattice.base), True)
        self.lattice.setLatPar(alpha=44, beta=66, gamma=88)
        self.assertNotEqual(numpy.all(base == self.lattice.base), True)
        self.lattice.setLatPar(alpha=60, beta=60, gamma=60)
        self.assertTrue(numpy.allclose(base[0], self.lattice.base[0]))
        self.assertTrue(numpy.allclose(base[1], self.lattice.base[1]))
        self.assertTrue(numpy.allclose(base[2], self.lattice.base[2]))
        # try base checking
        self.assertRaises(LatticeError, self.lattice.setLatBase,
                [[1, 0, 0], [1,0,0], [0,0,1]])
        self.assertRaises(LatticeError, self.lattice.setLatBase,
                [[1, 0, 0], [0,0,1], [0,1,0]])
        return


    def test_reciprocal(self):
        '''check calculation of reciprocal lattice.'''
        r1 = self.lattice.reciprocal()
        self.assertEqual((1, 1, 1, 90, 90, 90), r1.abcABG())
        L2 = Lattice(2, 4, 8, 90, 90, 90)
        r2 = L2.reciprocal()
        self.assertEqual((0.5, 0.25, 0.125, 90, 90, 90), r2.abcABG())
        rr2 = r2.reciprocal()
        self.assertTrue(numpy.array_equal(L2.base, rr2.base))
        return


    def test_dot(self):
        '''check dot product of lattice vectors.'''
        L = self.lattice
        L.setLatPar(gamma=120)
        self.assertAlmostEqual(-0.5, L.dot([1, 0, 0], [0, 1, 0]), self.places)
        va5 = numpy.tile([1.0, 0.0, 0.0], (5, 1))
        vb5 = numpy.tile([0.0, 1.0, 0.0], (5, 1))
        self.assertTrue(numpy.array_equal(5 * [-0.5], L.dot(va5, vb5)))
        self.assertTrue(numpy.array_equal(5 * [-0.5], L.dot(va5[0], vb5)))
        self.assertTrue(numpy.array_equal(5 * [-0.5], L.dot(va5, vb5[0])))
        return


    def test_norm(self):
        '''check norm of a lattice vector.'''
        self.assertEqual(1, self.lattice.norm([1, 0, 0]))
        u = numpy.array([[3, 4, 0], [1, 1, 1]])
        self.assertTrue(numpy.allclose([5, 3**0.5], self.lattice.norm(u)))
        self.lattice.setLatPar(gamma=120)
        self.assertAlmostEqual(1, self.lattice.norm([1, 1, 0]), self.places)
        return


    def test_rnorm(self):
        '''check norm of a reciprocal vector.'''
        L = self.lattice
        L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
        r = L.reciprocal()
        hkl = [0.5, 0.3, 0.2]
        self.assertAlmostEqual(r.norm(hkl), L.rnorm(hkl), self.places)
        hkl5 = numpy.tile(hkl, (5, 1))
        self.assertTrue(numpy.allclose(5 * [r.norm(hkl)], L.rnorm(hkl5)))
        return


    def test_dist(self):
        '''check dist function for distance between lattice points.'''
        L = self.lattice
        L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
        u = [0.1, 0.3, 0.7]
        v = [0.3, 0.7, 0.7]
        d0 = numalg.norm(L.cartesian(numpy.array(u) - v))
        self.assertAlmostEqual(d0, L.dist(u, v), self.places)
        self.assertAlmostEqual(d0, L.dist(v, u), self.places)
        u5 = numpy.tile(u, (5, 1))
        v5 = numpy.tile(v, (5, 1))
        self.assertTrue(numpy.allclose(5 * [d0], L.dist(u, v5)))
        self.assertTrue(numpy.allclose(5 * [d0], L.dist(u5, v)))
        self.assertTrue(numpy.allclose(5 * [d0], L.dist(v5, u5)))
        return


    def test_angle(self):
        '''check angle calculation between lattice vectors.'''
        from math import degrees, acos
        L = self.lattice
        L.setLatPar(1, 1.5, 2.3, 80, 95, 115)
        u = [0.1, 0.3, 0.7]
        v = [0.3, 0.7, 0.7]
        uc = L.cartesian(u)
        vc = L.cartesian(v)
        a0 = degrees(acos(numpy.dot(uc, vc) /
                          (numalg.norm(uc) * numalg.norm(vc))))
        self.assertAlmostEqual(a0, L.angle(u, v), self.places)
        self.assertAlmostEqual(a0, L.angle(v, u), self.places)
        u5 = numpy.tile(u, (5, 1))
        v5 = numpy.tile(v, (5, 1))
        self.assertTrue(numpy.allclose(5 * [a0], L.angle(u, v5)))
        self.assertTrue(numpy.allclose(5 * [a0], L.angle(u5, v)))
        self.assertTrue(numpy.allclose(5 * [a0], L.angle(v5, u5)))
        return



    def test_repr(self):
        """check string representation of this lattice"""
        r = repr(self.lattice)
        self.assertEqual(r, "Lattice()")
        self.lattice.setLatPar(1, 2, 3, 10, 20, 30)
        r = repr(self.lattice)
        r0 = "Lattice(a=1, b=2, c=3, alpha=10, beta=20, gamma=30)"
        self.assertEqual(r, r0)
        base = [[1.0,  1.0,  0.0],
                [0.0,  2.0,  2.0],
                [3.0,  0.0,  3.0]]
        self.lattice.setLatBase(base)
        r = repr(self.lattice)
        self.assertEqual(r, "Lattice(base=%r)" % self.lattice.base)