Ejemplo n.º 1
0
 def __get_unitcell(self):
     """Wrapper to get the unit cell from different structure classes"""
     from javelin.unitcell import UnitCell
     try:  # javelin structure
         return self.structure.unitcell
     except AttributeError:
         try:  # diffpy structure
             return UnitCell(self.structure.lattice.abcABG())
         except AttributeError:
             try:  # ASE structure
                 from ase.geometry import cell_to_cellpar
                 return UnitCell(cell_to_cellpar(self.structure.cell))
             except (ImportError, AttributeError) as e:
                 print(e)
                 raise ValueError("Unable to get unit cell from structure")
Ejemplo n.º 2
0
def test_hex():
    from javelin.unitcell import UnitCell
    positions = [[0, 1, 0], [1, 1, 0], [1, 0, 0], [0, -1, 0], [-1, -1, 0],
                 [-1, 0, 0]]
    symbols = ['C'] * 6
    unitcell = (1.4, 1.4, 1, 90, 90, 120)

    hex_cell = Structure(unitcell=UnitCell(unitcell),
                         symbols=symbols,
                         positions=positions)

    assert hex_cell.number_of_atoms == 6
    assert_array_equal(hex_cell.element, ['C', 'C', 'C', 'C', 'C', 'C'])
    assert_array_equal(hex_cell.get_atom_symbols(), ['C'])
    assert_array_equal(hex_cell.get_atom_count(), 6)
    assert_array_equal(hex_cell.get_chemical_symbols(),
                       ['C', 'C', 'C', 'C', 'C', 'C'])
    assert_array_equal(hex_cell.get_atom_Zs(), [6])
    assert_array_equal(hex_cell.get_atomic_numbers(), [6, 6, 6, 6, 6, 6])
    assert_array_equal(hex_cell.x, [0, 1, 1, 0, -1, -1])
    assert_array_equal(hex_cell.y, [1, 1, 0, -1, -1, 0])
    assert_array_equal(hex_cell.z, [0, 0, 0, 0, 0, 0])
    assert_array_equal(hex_cell.xyz, positions)
    assert_array_equal(hex_cell.get_scaled_positions(), positions)
    real_positions = [[0, 1.4, 0], [1.21243557, 0.7, 0], [1.21243557, -0.7, 0],
                      [0, -1.4, 0], [-1.21243557, -0.7, 0],
                      [-1.21243557, 0.7, 0]]
    assert_array_almost_equal(hex_cell.xyz_cartn, real_positions)
    assert_array_almost_equal(hex_cell.get_positions(), real_positions)
    assert_array_almost_equal(hex_cell.unitcell.cell, unitcell)
Ejemplo n.º 3
0
def test_UnitCell_exceptions():
    unitcell = UnitCell()

    with pytest.raises(ValueError):
        unitcell.cell = (1, 2)

    with pytest.raises(ValueError):
        unitcell.cell = (1, 2, 3, 4, 5)

    with pytest.raises(TypeError):
        unitcell.cell = "foobor"

    with pytest.raises(ValueError):
        UnitCell(1, 1, 1, 90, 90, 200)

    with pytest.raises(ValueError):
        UnitCell(1, 1, 1, 360, 90, 90)
Ejemplo n.º 4
0
def read_mantid_MDHisto(filename):
    """Read the saved MDHisto from from Mantid and returns an xarray.DataArray object"""
    import h5py
    import numpy as np
    import xarray as xr
    from javelin.unitcell import UnitCell
    with h5py.File(filename, "r") as f:
        if ('SaveMDVersion' not in f['MDHistoWorkspace'].attrs
                or f['MDHistoWorkspace'].attrs['SaveMDVersion'] < 2):
            raise RuntimeError("Cannot open " + filename +
                               ", must be saved by SaveMD Version 2")

        path = 'MDHistoWorkspace/data/'
        if path + 'signal' not in f:
            raise RuntimeError("Cannot open " + path + 'signal in ' + filename)

        signal = f[path + 'signal']
        data = np.array(signal)

        if 'axes' not in signal.attrs:
            print("Can't find axes")
            return xr.DataArray(data)
        axes = signal.attrs['axes'].decode().split(":")

        dims_list = []
        coords_list = []
        for a in axes:
            dims_list.append(a)
            axis = np.array(f[path + a])
            axis = (
                (axis + np.roll(axis, -1))[:-1]) / 2  # Hack: Need bin centers
            coords_list.append(np.array(axis))

        data_set = xr.DataArray(data, dims=dims_list, coords=coords_list)

        # Get lattice constants
        oriented_lattice = 'MDHistoWorkspace/experiment0/sample/oriented_lattice'
        if oriented_lattice in f:
            lattice = f[oriented_lattice]
            data_set.attrs['unit_cell'] = UnitCell(
                lattice['unit_cell_a'][0], lattice['unit_cell_b'][0],
                lattice['unit_cell_c'][0], lattice['unit_cell_alpha'][0],
                lattice['unit_cell_beta'][0], lattice['unit_cell_gamma'][0])

        # Get projection matrix
        W_MATRIX = 'MDHistoWorkspace/experiment0/logs/W_MATRIX/value'
        if W_MATRIX in f:
            data_set.attrs['projection_matrix'] = np.array(
                f[W_MATRIX]).reshape(3, 3)

    return data_set
Ejemplo n.º 5
0
    def __init__(self, symbols=None, numbers=None, unitcell=1, ncells=None,
                 positions=None, rotations=False, translations=False, magnetic_moments=False):

        if positions is not None:
            numberOfAtoms = len(positions)
        else:
            numberOfAtoms = 0

        if ncells is not None:
            ncells = np.asarray(ncells)

        if ncells is not None and positions is not None and ncells.prod() != numberOfAtoms:
            raise ValueError("Product of ncells values doesn't equal length of positions")

        if isinstance(unitcell, UnitCell):
            self.unitcell = unitcell
        else:
            self.unitcell = UnitCell(unitcell)

        miindex = get_miindex(numberOfAtoms, ncells)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z'])

        if numbers is not None or symbols is not None:
            self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=numbers, symbol=symbols)

        positions = np.asarray(positions)
        self.atoms[['x', 'y', 'z']] = positions

        if rotations:
            self.rotations = DataFrame(index=miindex.droplevel(3),
                                       columns=['w', 'x', 'y', 'z'])
        else:
            self.rotations = None

        if translations:
            self.translations = DataFrame(index=miindex.droplevel(3),
                                          columns=['x', 'y', 'z'])
        else:
            self.translations = None

        if magnetic_moments:
            self.magmons = DataFrame(index=miindex,
                                     columns=['spinx', 'spiny', 'spinz'])
        else:
            self.magmons = None
Ejemplo n.º 6
0
def test_save_load_xarray_to_HDF5_with_metadata(tmpdir):
    import xarray as xr
    from javelin.unitcell import UnitCell

    filename = tmpdir.join('test_file.h5')
    test_array = xr.DataArray([1, 2, 3])
    test_array.attrs['unit_cell'] = UnitCell(5)

    # Test save
    io.save_xarray_to_HDF5(test_array, str(filename))
    assert len(tmpdir.listdir()) == 1

    # Test load
    test_data = io.load_HDF5_to_xarray(str(filename))
    assert_array_equal(test_data.values, [1, 2, 3])
    assert isinstance(test_data.attrs['unit_cell'], UnitCell)
    assert test_data.attrs['unit_cell'].a == 5
Ejemplo n.º 7
0
def test_UnitCell_cell_setter():
    unitcell = UnitCell()

    unitcell.cell = 7
    assert unitcell.cell == (7, 7, 7, 90, 90, 90)
    assert_almost_equal(unitcell.volume, 343)
    assert_array_almost_equal(unitcell.G, [[49, 0, 0], [0, 49, 0], [0, 0, 49]])

    unitcell.cell = 4, 5, 6
    assert unitcell.cell == (4, 5, 6, 90, 90, 90)
    unitcell.cell = [6, 5, 4]
    assert unitcell.cell == (6, 5, 4, 90, 90, 90)
    unitcell.cell = (6, 4, 5)
    assert unitcell.cell == (6, 4, 5, 90, 90, 90)
    unitcell.cell = 7, 6, 5, 120, 90, 45
    assert_array_almost_equal(unitcell.cell, (7, 6, 5, 120, 90, 45))
Ejemplo n.º 8
0
def test_UnitCell_exceptions():
    unitcell = UnitCell()

    with pytest.raises(ValueError):
        unitcell.cell = (1, 2)

    with pytest.raises(ValueError):
        unitcell.cell = (1, 2, 3, 4, 5)

    with pytest.raises(TypeError):
        unitcell.cell = "foobor"

    with pytest.raises(ValueError):
        UnitCell(1, 1, 1, 90, 90, 200)

    with pytest.raises(ValueError):
        UnitCell(1, 1, 1, 360, 90, 90)
Ejemplo n.º 9
0
def test_UnitCell_cell_setter():
    unitcell = UnitCell()

    unitcell.cell = 7
    assert unitcell.cell == (7, 7, 7, 90, 90, 90)
    assert_almost_equal(unitcell.volume, 343)
    assert_array_almost_equal(unitcell.G, [[49, 0, 0],
                                           [0, 49, 0],
                                           [0, 0, 49]])

    unitcell.cell = 4, 5, 6
    assert unitcell.cell == (4, 5, 6, 90, 90, 90)
    unitcell.cell = [6, 5, 4]
    assert unitcell.cell == (6, 5, 4, 90, 90, 90)
    unitcell.cell = (6, 4, 5)
    assert unitcell.cell == (6, 4, 5, 90, 90, 90)
    unitcell.cell = 7, 6, 5, 120, 90, 45
    assert_array_almost_equal(unitcell.cell,
                              (7, 6, 5, 120, 90, 45))
Ejemplo n.º 10
0
class Structure(object):
    """
    Structure class

    :param symbols: atoms symbols to initialize structure
    :type symbols: list
    :param numbers: atomic numbers to initialize structure
    :type numbers: list
    """
    def __init__(self, symbols=None, numbers=None, unitcell=1, ncells=None,
                 positions=None, rotations=False, translations=False, magnetic_moments=False):

        if positions is not None:
            numberOfAtoms = len(positions)
        else:
            numberOfAtoms = 0

        if ncells is not None:
            ncells = np.asarray(ncells)

        if ncells is not None and positions is not None and ncells.prod() != numberOfAtoms:
            raise ValueError("Product of ncells values doesn't equal length of positions")

        if isinstance(unitcell, UnitCell):
            self.unitcell = unitcell
        else:
            self.unitcell = UnitCell(unitcell)

        miindex = get_miindex(numberOfAtoms, ncells)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z'])

        if numbers is not None or symbols is not None:
            self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=numbers, symbol=symbols)

        positions = np.asarray(positions)
        self.atoms[['x', 'y', 'z']] = positions

        if rotations:
            self.rotations = DataFrame(index=miindex.droplevel(3),
                                       columns=['w', 'x', 'y', 'z'])
        else:
            self.rotations = None

        if translations:
            self.translations = DataFrame(index=miindex.droplevel(3),
                                          columns=['x', 'y', 'z'])
        else:
            self.translations = None

        if magnetic_moments:
            self.magmons = DataFrame(index=miindex,
                                     columns=['spinx', 'spiny', 'spinz'])
        else:
            self.magmons = None

    @property
    def number_of_atoms(self):
        return len(self.atoms)

    @property
    def element(self):
        return self.atoms.symbol.values

    @property
    def xyz(self):
        return self.atoms[['x', 'y', 'z']].values

    @property
    def x(self):
        return self.atoms.x.values

    @property
    def y(self):
        return self.atoms.y.values

    @property
    def z(self):
        return self.atoms.z.values

    @property
    def xyz_cartn(self):
        return self.unitcell.cartesian(self.atoms[['x', 'y', 'z']].values +
                                       np.asarray([self.atoms.index.get_level_values(0).values,
                                                   self.atoms.index.get_level_values(1).values,
                                                   self.atoms.index.get_level_values(2).values]).T)

    def get_atom_symbols(self):
        return self.atoms.symbol.unique()

    def get_atom_Zs(self):
        return self.atoms.Z.unique()

    def get_atom_count(self):
        return self.atoms.symbol.value_counts()

    def get_atomic_numbers(self):
        return self.atoms.Z.values

    def get_chemical_symbols(self):
        return self.atoms.symbol.values

    def get_scaled_positions(self):
        return (self.atoms[['x', 'y', 'z']].values +
                np.asarray([self.atoms.index.get_level_values(0).values,
                            self.atoms.index.get_level_values(1).values,
                            self.atoms.index.get_level_values(2).values]).T)

    def get_positions(self):
        return self.xyz_cartn

    def get_magnetic_moments(self):
        return self.magmons.values

    def add_atom(self, i=0, j=0, k=0, site=0, Z=None, symbol=None, position=None):
        Z, symbol = get_atomic_number_symbol([Z], [symbol])
        if position is None:
            raise ValueError("position not provided")

        self.atoms.loc[i, j, k, site] = [Z[0], symbol[0],
                                         position[0], position[1], position[2]]

        if self.rotations is not None:
            self.rotations[i, j, k] = [1, 0, 0, 0]

        if self.translations is not None:
            self.translations[i, j, k] = [0, 0, 0]

    def rattle(self, scale=0.001, seed=None):
        """Randomly move all atoms by a normal distbution with a standard
        deviation given by scale.

        :param scale: standard deviation
        :type scale: float
        :param scale: seed for random number generator
        :type scale: int
        """
        rs = np.random.RandomState(seed)
        self.atoms[['x', 'y', 'z']] += rs.normal(scale=scale, size=self.xyz.shape)

    def repeat(self, rep):
        """Repeat the cells a number of time along each dimension

        *rep* argument should be either three value like *(1,2,3)* or
        a single value *r* equivalent to *(r,r,r)*."""

        if isinstance(rep, int):
            rep = np.array((rep, rep, rep, 1))
        else:
            rep = np.append(rep, 1)

        ncells = np.array(self.atoms.index.max()) + 1

        x = np.tile(np.reshape(self.x, ncells), rep).flatten()
        y = np.tile(np.reshape(self.y, ncells), rep).flatten()
        z = np.tile(np.reshape(self.z, ncells), rep).flatten()
        Z = np.tile(np.reshape(self.get_atomic_numbers(), ncells), rep).flatten()

        miindex = get_miindex(0, ncells * rep)

        self.atoms = DataFrame(index=miindex,
                               columns=['Z', 'symbol',
                                        'x', 'y', 'z'])

        self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=Z)

        self.atoms.x = x
        self.atoms.y = y
        self.atoms.z = z

    def reindex(self, ncells):
        self.atoms.set_index(get_miindex(ncells=ncells), inplace=True)
Ejemplo n.º 11
0
def test_UnitCell_init():
    from numpy import pi
    unitcell = UnitCell()
    assert unitcell.cell == (1, 1, 1, 90, 90, 90)
    assert unitcell.reciprocalCell == (1, 1, 1, 90, 90, 90)
    assert unitcell.d(1, 0, 0) == 1
    assert unitcell.dstar(1, 0, 0) == 1
    assert unitcell.recAngle(1, 0, 0, 1, 0, 0) == 0
    assert unitcell.recAngle(1, 0, 0, 0, 1, 0, degrees=True) == 90
    assert_almost_equal(unitcell.recAngle(0, 1, 0, 0, 1, 1), pi/4)
    assert_almost_equal(unitcell.recAngle(0, 1, 0, 0, 1, 1, degrees=True), 45)
    assert unitcell.volume == 1
    assert unitcell.reciprocalVolume == 1
    assert_array_equal(unitcell.G, [[1, 0, 0],
                                    [0, 1, 0],
                                    [0, 0, 1]])
    assert_array_equal(unitcell.B, [[1, 0, 0],
                                    [0, 1, 0],
                                    [0, 0, 1]])
    assert_array_equal(unitcell.Binv, [[1, 0, 0],
                                       [0, 1, 0],
                                       [0, 0, 1]])

    unitcell = UnitCell(5)
    assert unitcell.cell == (5, 5, 5, 90, 90, 90)
    assert_array_almost_equal(unitcell.reciprocalCell, (0.2, 0.2, 0.2, 90, 90, 90))
    assert_almost_equal(unitcell.volume, 125)
    assert_almost_equal(unitcell.reciprocalVolume, 0.008)
    assert_array_almost_equal(unitcell.G, [[25, 0, 0],
                                           [0, 25, 0],
                                           [0, 0, 25]])
    assert_array_almost_equal(unitcell.B, [[0.2, 0, 0],
                                           [0, 0.2, 0],
                                           [0, 0, 0.2]])
    assert_array_almost_equal(unitcell.Binv, [[5, 0, 0],
                                              [0, 5, 0],
                                              [0, 0, 5]])

    unitcell = UnitCell(1, 2, 3)
    assert unitcell.cell == (1, 2, 3, 90, 90, 90)
    assert_array_almost_equal(unitcell.reciprocalCell, (1, 0.5, 0.333333, 90, 90, 90))
    assert unitcell.volume == 6
    assert_almost_equal(unitcell.reciprocalVolume, 0.1666667)
    assert_array_almost_equal(unitcell.G, [[1, 0, 0],
                                           [0, 4, 0],
                                           [0, 0, 9]])

    unitcell = UnitCell(4, 5, 6, 90, 90, 120)
    assert unitcell.d(1, 0, 0) == 3.4641016151377548
    assert unitcell.d(0, 1, 0) == 4.3301270189221936
    assert unitcell.d(0, 0, 1) == 6
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 1, 0, 0), 0)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 1, 0, 0, degrees=True), 0, decimal=5)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 1, 0), pi/3)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 1, 0, degrees=True), 60)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 0, 1), pi/2)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 0, 1, degrees=True), 90)
    assert_array_almost_equal(unitcell.cell,
                              (4, 5, 6, 90, 90, 120))
    assert_array_almost_equal(unitcell.reciprocalCell,
                              (0.288675, 0.2309401, 0.1666667, 90, 90, 60))
    assert_almost_equal(unitcell.volume, 103.9230485)
    assert_almost_equal(unitcell.reciprocalVolume, 0.0096225)
    assert_array_almost_equal(unitcell.G, [[16, -10, 0],
                                           [-10, 25, 0],
                                           [0,    0, 36]])
    assert_array_almost_equal(unitcell.B, [[0.288675, 0.11547, 0],
                                           [0,        0.2,     0],
                                           [0,        0,       0.166667]])

    assert_array_almost_equal(unitcell.Binv, [[3.464101, -2, 0],
                                              [0,         5, 0],
                                              [0,         0, 6]])

    assert_array_almost_equal(unitcell.cartesian([1, 0, 0]), [[3.464102, -2, 0]])
    assert_array_almost_equal(unitcell.cartesian([[1,   0,   0],
                                                  [0.1, 0.3, 0.5]]), [[3.464102, -2, 0],
                                                                      [0.34641, 1.3, 3]])
    assert_array_almost_equal(unitcell.fractional([3.464102, -2, 0]), [[1, 0, 0]])
    assert_array_almost_equal(unitcell.fractional([[0, 5, 0],
                                                   [0, 0, 3]]), [[0, 1, 0],
                                                                 [0, 0, 0.5]])

    # test __eq__
    assert unitcell != UnitCell()
    assert unitcell != UnitCell(5)
    assert unitcell == UnitCell(4, 5, 6, 90, 90, 120)
    assert unitcell != UnitCell(6, 5, 4, 120, 90, 90)

    unitcell = UnitCell([5, 6, 7, 89, 92, 121])
    assert unitcell.cell == (5, 6, 7, 89, 92, 121)
    assert_array_almost_equal(unitcell.reciprocalCell,
                              (0.233433, 0.194439, 0.142944, 89.965076, 88.267509, 59.014511))
    assert_almost_equal(unitcell.volume, 179.8954455)
    assert_almost_equal(unitcell.reciprocalVolume, 0.0055587844)
    assert_array_almost_equal(unitcell.G, [[25, -15.45114225, -1.22148238],
                                           [-15.45114225, 36, 0.73300107],
                                           [-1.22148238, 0.73300107, 49]])
    # Test __str__
    assert str(unitcell) == '(5.0, 6.0, 7.0, 89.0, 92.0, 121.0)'
Ejemplo n.º 12
0
    def __init__(self,
                 symbols=None,
                 numbers=None,
                 unitcell=1,
                 ncells=None,
                 positions=None,
                 rotations=False,
                 translations=False,
                 magnetic_moments=False):

        if positions is not None:
            numberOfAtoms = len(positions)
        else:
            numberOfAtoms = 0

        if ncells is not None:
            ncells = np.asarray(ncells)

        if ncells is not None and positions is not None and ncells.prod(
        ) != numberOfAtoms:
            raise ValueError(
                "Product of ncells values doesn't equal length of positions")

        if isinstance(unitcell, UnitCell):
            self.unitcell = unitcell
        else:
            self.unitcell = UnitCell(unitcell)

        miindex = get_miindex(numberOfAtoms, ncells)

        self.atoms = DataFrame(index=miindex,
                               columns=[
                                   'Z', 'symbol', 'x', 'y', 'z', 'cartn_x',
                                   'cartn_y', 'cartn_z'
                               ])

        if numbers is not None or symbols is not None:
            self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(
                Z=numbers, symbol=symbols)

        positions = np.asarray(positions)
        self.atoms[['x', 'y', 'z']] = positions

        if rotations:
            self.rotations = DataFrame(index=miindex.droplevel(3),
                                       columns=['w', 'x', 'y', 'z'])
        else:
            self.rotations = None

        if translations:
            self.translations = DataFrame(index=miindex.droplevel(3),
                                          columns=['x', 'y', 'z'])
        else:
            self.translations = None

        if magnetic_moments:
            self.magmons = DataFrame(index=miindex,
                                     columns=['spinx', 'spiny', 'spinz'])
        else:
            self.magmons = None

        self._recalculate_cartn()
Ejemplo n.º 13
0
class Structure(object):
    """
    Structure class

    :param symbols: atoms symbols to initialize structure
    :type symbols: list
    :param numbers: atomic numbers to initialize structure
    :type numbers: list
    """
    def __init__(self,
                 symbols=None,
                 numbers=None,
                 unitcell=1,
                 ncells=None,
                 positions=None,
                 rotations=False,
                 translations=False,
                 magnetic_moments=False):

        if positions is not None:
            numberOfAtoms = len(positions)
        else:
            numberOfAtoms = 0

        if ncells is not None:
            ncells = np.asarray(ncells)

        if ncells is not None and positions is not None and ncells.prod(
        ) != numberOfAtoms:
            raise ValueError(
                "Product of ncells values doesn't equal length of positions")

        if isinstance(unitcell, UnitCell):
            self.unitcell = unitcell
        else:
            self.unitcell = UnitCell(unitcell)

        miindex = get_miindex(numberOfAtoms, ncells)

        self.atoms = DataFrame(index=miindex,
                               columns=[
                                   'Z', 'symbol', 'x', 'y', 'z', 'cartn_x',
                                   'cartn_y', 'cartn_z'
                               ])

        if numbers is not None or symbols is not None:
            self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(
                Z=numbers, symbol=symbols)

        positions = np.asarray(positions)
        self.atoms[['x', 'y', 'z']] = positions

        if rotations:
            self.rotations = DataFrame(index=miindex.droplevel(3),
                                       columns=['w', 'x', 'y', 'z'])
        else:
            self.rotations = None

        if translations:
            self.translations = DataFrame(index=miindex.droplevel(3),
                                          columns=['x', 'y', 'z'])
        else:
            self.translations = None

        if magnetic_moments:
            self.magmons = DataFrame(index=miindex,
                                     columns=['spinx', 'spiny', 'spinz'])
        else:
            self.magmons = None

        self._recalculate_cartn()

    @property
    def number_of_atoms(self):
        return len(self.atoms)

    @property
    def element(self):
        return self.atoms.symbol.values

    @property
    def xyz(self):
        return self.atoms[['x', 'y', 'z']].values

    @property
    def x(self):
        return self.atoms.x.values

    @property
    def y(self):
        return self.atoms.y.values

    @property
    def z(self):
        return self.atoms.z.values

    @property
    def xyz_cartn(self):
        return self.atoms[['cartn_x', 'cartn_y', 'cartn_z']].values

    def get_atom_symbols(self):
        return self.atoms.symbol.unique()

    def get_atom_Zs(self):
        return self.atoms.Z.unique()

    def get_atom_count(self):
        return self.atoms.symbol.value_counts()

    def get_atomic_numbers(self):
        return self.atoms.Z.values

    def get_chemical_symbols(self):
        return self.atoms.symbol.values

    def get_scaled_positions(self):
        return (self.atoms[['x', 'y', 'z']].values + np.asarray([
            self.atoms.index.get_level_values(0).values,
            self.atoms.index.get_level_values(1).values,
            self.atoms.index.get_level_values(2).values
        ]).T)

    def get_positions(self):
        return self.xyz_cartn

    def get_magnetic_moments(self):
        return self.magmons.values

    def add_atom(self,
                 i=0,
                 j=0,
                 k=0,
                 site=0,
                 Z=None,
                 symbol=None,
                 position=None):
        Z, symbol = get_atomic_number_symbol([Z], [symbol])
        if position is None:
            raise ValueError("position not provided")

        cartn = self.unitcell.cartesian(position)[0]

        self.atoms.loc[i, j, k, site] = [
            Z[0], symbol[0], position[0], position[1], position[2], cartn[0],
            cartn[1], cartn[2]
        ]

        if self.rotations is not None:
            self.rotations[i, j, k] = [1, 0, 0, 0]

        if self.translations is not None:
            self.translations[i, j, k] = [0, 0, 0]

    def repeat(self, rep):
        """Repeat the cells a number of time along each dimension

        *rep* argument should be either three value like *(1,2,3)* or
        a single value *r* equivalent to *(r,r,r)*."""

        if isinstance(rep, int):
            rep = np.array((rep, rep, rep, 1))
        else:
            rep = np.append(rep, 1)

        ncells = np.array(self.atoms.index.max()) + 1

        x = np.tile(np.reshape(self.x, ncells), rep).flatten()
        y = np.tile(np.reshape(self.y, ncells), rep).flatten()
        z = np.tile(np.reshape(self.z, ncells), rep).flatten()
        Z = np.tile(np.reshape(self.get_atomic_numbers(), ncells),
                    rep).flatten()

        miindex = get_miindex(0, ncells * rep)

        self.atoms = DataFrame(index=miindex,
                               columns=[
                                   'Z', 'symbol', 'x', 'y', 'z', 'cartn_x',
                                   'cartn_y', 'cartn_z'
                               ])

        self.atoms.Z, self.atoms.symbol = get_atomic_number_symbol(Z=Z)

        self.atoms.x = x
        self.atoms.y = y
        self.atoms.z = z

        self._recalculate_cartn()

    def reindex(self, ncells):
        self.atoms.set_index(get_miindex(ncells=ncells), inplace=True)
        self._recalculate_cartn()

    def _recalculate_cartn(self):
        self.atoms[['cartn_x', 'cartn_y',
                    'cartn_z']] = self.unitcell.cartesian(
                        self.atoms[['x', 'y', 'z']].values + np.asarray([
                            self.atoms.index.get_level_values(0).values,
                            self.atoms.index.get_level_values(1).values,
                            self.atoms.index.get_level_values(2).values
                        ]).T)
Ejemplo n.º 14
0
def test_UnitCell_init():
    from numpy import pi
    unitcell = UnitCell()
    assert unitcell.cell == (1, 1, 1, 90, 90, 90)
    assert unitcell.reciprocalCell == (1, 1, 1, 90, 90, 90)
    assert unitcell.d(1, 0, 0) == 1
    assert unitcell.dstar(1, 0, 0) == 1
    assert unitcell.recAngle(1, 0, 0, 1, 0, 0) == 0
    assert unitcell.recAngle(1, 0, 0, 0, 1, 0, degrees=True) == 90
    assert_almost_equal(unitcell.recAngle(0, 1, 0, 0, 1, 1), pi / 4)
    assert_almost_equal(unitcell.recAngle(0, 1, 0, 0, 1, 1, degrees=True), 45)
    assert unitcell.volume == 1
    assert unitcell.reciprocalVolume == 1
    assert_array_equal(unitcell.G, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    assert_array_equal(unitcell.B, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    assert_array_equal(unitcell.Binv, [[1, 0, 0], [0, 1, 0], [0, 0, 1]])

    unitcell = UnitCell(5)
    assert unitcell.cell == (5, 5, 5, 90, 90, 90)
    assert_array_almost_equal(unitcell.reciprocalCell,
                              (0.2, 0.2, 0.2, 90, 90, 90))
    assert_almost_equal(unitcell.volume, 125)
    assert_almost_equal(unitcell.reciprocalVolume, 0.008)
    assert_array_almost_equal(unitcell.G, [[25, 0, 0], [0, 25, 0], [0, 0, 25]])
    assert_array_almost_equal(unitcell.B,
                              [[0.2, 0, 0], [0, 0.2, 0], [0, 0, 0.2]])
    assert_array_almost_equal(unitcell.Binv, [[5, 0, 0], [0, 5, 0], [0, 0, 5]])

    unitcell = UnitCell(1, 2, 3)
    assert unitcell.cell == (1, 2, 3, 90, 90, 90)
    assert_array_almost_equal(unitcell.reciprocalCell,
                              (1, 0.5, 0.333333, 90, 90, 90))
    assert unitcell.volume == 6
    assert_almost_equal(unitcell.reciprocalVolume, 0.1666667)
    assert_array_almost_equal(unitcell.G, [[1, 0, 0], [0, 4, 0], [0, 0, 9]])

    unitcell = UnitCell(4, 5, 6, 90, 90, 120)
    assert unitcell.d(1, 0, 0) == 3.4641016151377548
    assert unitcell.d(0, 1, 0) == 4.3301270189221936
    assert unitcell.d(0, 0, 1) == 6
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 1, 0, 0), 0)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 1, 0, 0, degrees=True),
                        0,
                        decimal=5)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 1, 0), pi / 3)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 1, 0, degrees=True), 60)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 0, 1), pi / 2)
    assert_almost_equal(unitcell.recAngle(1, 0, 0, 0, 0, 1, degrees=True), 90)
    assert_array_almost_equal(unitcell.cell, (4, 5, 6, 90, 90, 120))
    assert_array_almost_equal(unitcell.reciprocalCell,
                              (0.288675, 0.2309401, 0.1666667, 90, 90, 60))
    assert_almost_equal(unitcell.volume, 103.9230485)
    assert_almost_equal(unitcell.reciprocalVolume, 0.0096225)
    assert_array_almost_equal(unitcell.G,
                              [[16, -10, 0], [-10, 25, 0], [0, 0, 36]])
    assert_array_almost_equal(
        unitcell.B, [[0.288675, 0.11547, 0], [0, 0.2, 0], [0, 0, 0.166667]])

    assert_array_almost_equal(unitcell.Binv,
                              [[3.464101, -2, 0], [0, 5, 0], [0, 0, 6]])

    assert_array_almost_equal(unitcell.cartesian([1, 0, 0]),
                              [[3.464102, -2, 0]])
    assert_array_almost_equal(unitcell.cartesian([[1, 0, 0], [0.1, 0.3, 0.5]]),
                              [[3.464102, -2, 0], [0.34641, 1.3, 3]])
    assert_array_almost_equal(unitcell.fractional([3.464102, -2, 0]),
                              [[1, 0, 0]])
    assert_array_almost_equal(unitcell.fractional([[0, 5, 0], [0, 0, 3]]),
                              [[0, 1, 0], [0, 0, 0.5]])

    # test __eq__
    assert unitcell != UnitCell()
    assert unitcell != UnitCell(5)
    assert unitcell == UnitCell(4, 5, 6, 90, 90, 120)
    assert unitcell != UnitCell(6, 5, 4, 120, 90, 90)

    unitcell = UnitCell([5, 6, 7, 89, 92, 121])
    assert unitcell.cell == (5, 6, 7, 89, 92, 121)
    assert_array_almost_equal(
        unitcell.reciprocalCell,
        (0.233433, 0.194439, 0.142944, 89.965076, 88.267509, 59.014511))
    assert_almost_equal(unitcell.volume, 179.8954455)
    assert_almost_equal(unitcell.reciprocalVolume, 0.0055587844)
    assert_array_almost_equal(
        unitcell.G,
        [[25, -15.45114225, -1.22148238], [-15.45114225, 36, 0.73300107],
         [-1.22148238, 0.73300107, 49]])
    # Test __str__
    assert str(unitcell) == '(5.0, 6.0, 7.0, 89.0, 92.0, 121.0)'