コード例 #1
0
def cell_to_basis(cell):
    if cell is None:
        raise Exception("cell_to_basis: bad cell specification.")

    try:
        return cell.basis
    except AttributeError:
        pass

    if isinstance(cell, dict):
        if 'niggli_matrix' in cell:
            niggli_matrix = FracVector.use(cell['niggli_matrix'])
            if 'orientation' in cell:
                orientation = cell['orientation']
            else:
                orientation = 1
            basis = FracVector.use(
                niggli_to_basis(niggli_matrix, orientation=orientation))
        elif 'a' in cell:
            lengths = FracVector.create((cell['a'], cell['b'], cell['c']))
            cosangles = FracVector.create_cos(
                (cell['a'], cell['b'], cell['c']), degrees=True)
            basis = lengths_and_cosangles_to_conventional_basis(
                lengths, cosangles)
            #niggli_matrix = lengths_cosangles_to_niggli(lengths,cosangles)
            #basis = FracVector.use(niggli_to_basis(niggli_matrix, orientation=1))
    else:
        basis = FracVector.use(cell)

    return basis
コード例 #2
0
def niggli_to_metric(niggli):
    niggli = FracVector.use(niggli)

    m = niggli.noms

    # Since the niggli matrix contains 2*the product of the off diagonal elements, we increase the denominator by cell.denom*2
    return FracVector(
        ((2 * m[0][0], m[1][2], m[1][1]), (m[1][2], 2 * m[0][1], m[1][0]),
         (m[1][1], m[1][0], 2 * m[0][2])), niggli.denom * 2).simplify()
コード例 #3
0
def niggli_scale_to_vol(niggli_matrix, scale):
    niggli_matrix = FracVector.use(niggli_matrix)
    metric = niggli_to_metric(niggli_matrix)
    volsqr = metric.det()
    if volsqr == 0:
        raise Exception("niggli_vol_to_scale: singular cell matrix.")
    det = vectormath.sqrt(float(volsqr))
    if abs(det) < 1e-12:
        raise Exception("niggli_scale_to_vol: singular cell matrix.")
    return (((scale)**3) * det)
コード例 #4
0
ファイル: cell.py プロジェクト: hpleva/httk
    def __init__(self, basis, lattice_system, orientation=1):
        """
        Private constructor, as per httk coding guidelines. Use Cell.create instead.
        """
        self.basis = basis
        self.orientation = orientation
        self.lattice_system = lattice_system
        self.niggli_matrix, self.orientation = basis_to_niggli_and_orientation(basis)

        self.det = basis.det()
        self.inv = basis.inv()
        self._volume = abs(self.det)
        self.metric = niggli_to_metric(self.niggli_matrix)

        self.lengths, self.angles = niggli_to_lengths_and_angles(self.niggli_matrix)

        self.lengths = [FracVector.use(x).simplify() for x in self.lengths]
        self.angles = [FracVector.use(x).simplify() for x in self.angles]
        _dummy, self.cosangles, self.sinangles = niggli_to_lengths_and_trigangles(self.niggli_matrix)

        self.a, self.b, self.c = self.lengths
        self.alpha, self.beta, self.gamma = self.angles
        self.cosalpha, self.cosbeta, self.cosgamma = self.cosangles
        self.sinalpha, self.sinbeta, self.singamma = self.sinangles
コード例 #5
0
def niggli_to_lengths_and_trigangles(niggli_matrix):
    niggli_matrix = FracVector.use(niggli_matrix)

    s11, s22, s33 = niggli_matrix[0][0], niggli_matrix[0][1], niggli_matrix[0][
        2]
    s23, s13, s12 = niggli_matrix[1][0] / 2, niggli_matrix[1][
        1] / 2, niggli_matrix[1][2] / 2

    a, b, c = vectormath.sqrt(s11), vectormath.sqrt(s22), vectormath.sqrt(s33)
    cosalpha, cosbeta, cosgamma = s23 / (b * c), s13 / (c * a), s12 / (a * b)
    sinalpha, sinbeta, singamma = vectormath.sqrt(
        1 - cosalpha), vectormath.sqrt(1 - cosbeta), vectormath.sqrt(1 -
                                                                     cosgamma)

    return [a, b, c], [cosalpha, cosbeta,
                       cosgamma], [sinalpha, sinbeta, singamma]
コード例 #6
0
def scaling_to_volume(basis, scaling):
    volume = None
    if isinstance(scaling, dict):
        if 'volume' in scaling:
            volume = scaling['volume']
        elif 'scale' in scaling:
            scale = scaling['scale']
    elif scaling > 0:
        scale = scaling
    else:
        volume = -scaling

    if volume is None:
        scale = FracVector.use(scale)
        volume = scale_to_vol(basis, scale)

    return volume
コード例 #7
0
def niggli_to_lengths_and_angles(niggli_matrix):
    niggli_matrix = FracVector.use(niggli_matrix)

    pi = niggli_matrix.pi()

    s11, s22, s33 = niggli_matrix[0][0], niggli_matrix[0][1], niggli_matrix[0][
        2]
    s23, s13, s12 = niggli_matrix[1][0] / 2, niggli_matrix[1][
        1] / 2, niggli_matrix[1][2] / 2

    a, b, c = vectormath.sqrt(s11), vectormath.sqrt(s22), vectormath.sqrt(s33)
    alpha, beta, gamma = vectormath.acos(
        s23 / (b * c)) * 180 / pi, vectormath.acos(
            s13 / (c * a)) * 180 / pi, vectormath.acos(s12 /
                                                       (a * b)) * 180 / pi

    return [a, b, c], [alpha, beta, gamma]
コード例 #8
0
def basis_to_niggli_and_orientation(basis):
    basis = FracVector.use(basis)

    A = basis.noms
    det = basis.det()
    if det == 0:
        raise Exception("basis_to_niggli: singular cell matrix.")

    if det > 0:
        orientation = 1
    else:
        orientation = -1

    s11 = A[0][0] * A[0][0] + A[0][1] * A[0][1] + A[0][2] * A[0][2]
    s22 = A[1][0] * A[1][0] + A[1][1] * A[1][1] + A[1][2] * A[1][2]
    s33 = A[2][0] * A[2][0] + A[2][1] * A[2][1] + A[2][2] * A[2][2]

    s23 = A[1][0] * A[2][0] + A[1][1] * A[2][1] + A[1][2] * A[2][2]
    s13 = A[0][0] * A[2][0] + A[0][1] * A[2][1] + A[0][2] * A[2][2]
    s12 = A[0][0] * A[1][0] + A[0][1] * A[1][1] + A[0][2] * A[1][2]

    new = FracVector.create(((s11, s22, s33), (2 * s23, 2 * s13, 2 * s12)),
                            denom=basis.denom**2).simplify()
    return new, orientation
コード例 #9
0
ファイル: cell.py プロジェクト: hpleva/httk
    def create(cls, cell=None, basis=None, metric=None, niggli_matrix=None,
               a=None, b=None, c=None, alpha=None, beta=None, gamma=None,
               lengths=None, angles=None, cosangles=None, scale=None,
               scaling=None, volume=None, periodicity=None,
               nonperiodic_vecs=None, orientation=1, hall=None,
               lattice_system=None, eps=0):
        """
        Create a new cell object,

        cell: any one of the following:

          - a 3x3 array with (in rows) the three basis vectors of the cell (a non-periodic system should conventionally use an identity matrix)

          - a dict with a single key 'niggli_matrix' with a 3x2 array with the Niggli Matrix representation of the cell

          - a dict with 6 keys, 'a', 'b', 'c', 'alpha', 'beta', 'gamma' giving the cell parameters as floats

        scaling: free form input parsed for a scale.
            positive value = multiply basis vectors by this value
            negative value = rescale basis vectors so that cell volume becomes abs(value).

        scale: set to non-None to multiply all cell vectors with this factor

        volume: set to non-None if the basis vectors only give directions, and the volume of the cell should be this value (overrides scale)

        periodicity: free form input parsed for periodicity
            sequence: True/False for each basis vector being periodic
            integer: number of non-periodic basis vectors

        hall: giving the hall symbol makes it possible to determine the lattice system without numerical inaccuracy

        lattice_system: any one of: 'cubic', 'hexagonal', 'tetragonal', 'orthorhombic', 'trigonal', 'triclinic', 'monoclinic', 'unknown'
        """
        #print("Create cell:",cell,basis,angles, lengths,cosangles,a,b,c,alpha,beta,gamma)

        if cell is not None:
            return Cell.use(cell)

        if basis is not None:
            basis = FracVector.use(basis)

        if angles is None and not (alpha is None or beta is None or gamma is None):
            angles = [alpha, beta, gamma]

        if lengths is None and not (a is None or b is None or c is None):
            lengths = [a, b, c]

        if cosangles is None and angles is not None:
            cosangles = angles_to_cosangles(angles)

        if basis is None and lengths is not None and cosangles is not None:
            if hall is not None:
                lattice_system = lattice_system_from_hall(hall)
            else:
                lattice_system = lattice_system_from_lengths_and_cosangles(lengths, cosangles)
            basis = lengths_and_cosangles_to_conventional_basis(lengths, cosangles, lattice_system, orientation=orientation, eps=eps)

        if niggli_matrix is not None:
            niggli_matrix = FracVector.use(niggli_matrix)

        if niggli_matrix is None and basis is not None:
            niggli_matrix, orientation = basis_to_niggli_and_orientation(basis)

        #if niggli_matrix is None and lengths is not None and cosangles is not None:
        #    niggli_matrix = lengths_and_cosangles_to_niggli(lengths, cosangles)
        #    niggli_matrix = FracVector.use(niggli_matrix)

        #if niggli_matrix is None and lengths is not None and angles is not None:
        #    niggli_matrix = lengths_and_angles_to_niggli(lengths, angles)
        #    niggli_matrix = FracVector.use(niggli_matrix)

        #if niggli_matrix is None and not (a is None or b is None or c is None or alpha is None or beta is None or gamma is None):
        #    niggli_matrix = lengths_and_angles_to_niggli([a, b, c], [alpha, beta, gamma])
        #    niggli_matrix = FracVector.use(niggli_matrix)

        if basis is None:
            raise Exception("cell.create: Not enough information to specify a cell given.")

        if scaling is None and scale is not None:
            scaling = scale

        if scaling is not None and volume is not None:
            raise Exception("Cell.create: cannot specify both scaling and volume!")

        if volume is not None:
            scaling = vol_to_scale(basis, volume)

        if scaling is not None:
            scaling = FracVector.use(scaling)
            basis = (basis*scaling).simplify()

        # Determination of the lattice system can only be made approximately, so it is recommended
        # that it is given to the constructor if possible

        if (lattice_system is None or lattice_system == 'unknown') and hall is not None:
            lattice_system = lattice_system_from_hall(hall)

        if lattice_system is None or lattice_system == 'unknown':
            lattice_system = lattice_system_from_niggli(niggli_matrix)

        if basis is None:
            basis = FracVector.use(niggli_to_conventional_basis(niggli_matrix, lattice_system, orientation=orientation))

        return cls(basis, lattice_system, orientation)
コード例 #10
0
ファイル: cell.py プロジェクト: hpleva/httk
 def coords_cartesian_to_reduced(self, coords):
     coords = FracVector.use(coords)
     return coords*self.inv
コード例 #11
0
ファイル: cell.py プロジェクト: hpleva/httk
 def coords_reduced_to_cartesian(self, coords):
     coords = FracVector.use(coords)
     return coords*self.basis