示例#1
0
    def __init__(self,
                 pmin=None,
                 pmax=None,
                 xmin=0,
                 ymin=0,
                 zmin=0,
                 xmax=1,
                 ymax=1,
                 zmax=1):
        super().__init__()
        self._pmin = Point()
        self._pmax = Point()

        if pmin is None:
            pmin = [xmin, ymin, zmin]
        self.pmin = pmin

        if pmax is None:
            pmax = [xmax, ymax, zmax]
        self.pmax = pmax

        # assert self.pmin <= self.pmax
        assert np.all(np.less_equal(self.pmin, self.pmax))

        self.points.extend([self.pmin, self.pmax])
        self.fmtstr = "pmin={pmin!r}, pmax={pmax!r}"
示例#2
0
def test6():
    p2 = Point(np.zeros(3), nd=2)
    p3 = Point(np.zeros(2), nd=3)
    assert_equal(p2, Point(np.zeros(2)))
    assert_equal(p3, Point(np.zeros(3)))
    assert_true(len(p2) == 2)
    assert_true(len(p3) == 3)
示例#3
0
def test_parallelepiped():
    r = Parallelepiped()
    assert_is_instance(r, Parallelepiped)
    assert_equal(r.o, Point([0, 0, 0]))
    assert_true(np.allclose(r.measure, 1.0))
    assert_equal(r.centroid, Point([1, 1, 0.5]))
    assert_true(r.contains([0.5, 0.5, 0.5]))
    assert_false(r.contains([0, 0, 1]))
    assert_is_instance(r.centroid, Point)
示例#4
0
def test_cone():
    r = Cone()
    assert_is_instance(r, Cone)
    assert_true(np.allclose(r.measure, 2 * np.pi / 3))
    assert_equal(r.p1, Point(np.zeros(3)))
    assert_equal(r.p2, Point([0, 0, 2]))
    assert_true(r.contains([0, 0, 1]))
    assert_false(r.contains([0, 0, 2.1]))
    assert_is_instance(r.centroid, Point)
    assert_is_instance(r.axis, Vector)
示例#5
0
    def generate(self):
        """Generate structure data."""

        super().generate()

        if self.L0 is not None and self.fix_Lz:
            Lz_cutoff = 10 * self.L0 + 1
            region_bounds = Cuboid(pmin=Point([-np.inf, -np.inf, 0]),
                                   pmax=Point([np.inf, np.inf, Lz_cutoff]))
            self.atoms.clip_bounds(region_bounds)
示例#6
0
def test_triangle():
    r = Triangle()
    assert_is_instance(r, Triangle)
    assert_equal(r.centroid, Point([1 / 3, 1 / 3]))
    assert_true(np.allclose(r.measure, 0.5))
    assert_equal(r.p1, Point(nd=2))
    assert_equal(r.p2, Point([0, 1]))
    assert_equal(r.p3, Point([1, 0]))
    assert_true(r.contains([0.25, 0.25]))
    assert_false(r.contains([1, 1]))
    assert_is_instance(r.centroid, Point)
示例#7
0
def test_cylinder():
    r = Cylinder()
    assert_is_instance(r, Cylinder)
    assert_true(np.allclose(r.measure, 2 * np.pi))
    assert_equal(r.p1, Point([0, 0, -1]))
    assert_equal(r.p2, Point([0, 0, 1]))
    assert_true(r.contains([0, 0, 0]))
    assert_false(r.contains([1.1, 0, 0]))
    assert_equal(r.centroid, Point())
    r.p2 = [0, 0, 2]
    assert_equal(r.centroid, Point([0, 0, 0.5]))
    assert_is_instance(r.centroid, Point)
    assert_is_instance(r.axis, Vector)
示例#8
0
def test1():
    p = Point()
    assert_true(np.allclose(p, np.zeros(3)))

    p = Point([0, 0, 0], dtype=float)
    assert_true(np.allclose(p, np.zeros(3)))

    p = Point(np.ones(3))
    assert_true(np.allclose(p, np.ones(3)))

    p = Point([None, None, None])
    assert_true(np.allclose(p, np.zeros(3)))

    p = Point(np.arange(10))
    assert_true(np.allclose(p, np.arange(10)))
示例#9
0
def test1():
    print('generating graphene structure')
    graphene = GrapheneGenerator(armchair_edge_length=5, zigzag_edge_length=5)
    lattice = graphene.lattice
    print('graphene.bounds:\n{}'.format(graphene.bounds))
    print('graphene.centroid:\n{}'.format(graphene.centroid))
    print('graphene.lattice:\n{}'.format(lattice))
    print('graphene.lattice.a1:\n{}'.format(lattice.a1))
    print('graphene.lattice.a2:\n{}'.format(lattice.a2))
    print('graphene.lattice.a3:\n{}'.format(lattice.a3))
    print('graphene.lattice.orientation_matrix:\n{}'.format(
        lattice.orientation_matrix))
    print('rotating graphene')
    graphene.rotate(angle=-np.pi / 2, axis='x')
    print('graphene.bounds:\n{}'.format(graphene.bounds))
    print('graphene.centroid:\n{}'.format(graphene.centroid))
    print('graphene.lattice:\n{}'.format(lattice))
    print('graphene.lattice.a1:\n{}'.format(lattice.a1))
    print('graphene.lattice.a2:\n{}'.format(lattice.a2))
    print('graphene.lattice.a3:\n{}'.format(lattice.a3))
    print('graphene.lattice.orientation_matrix:\n{}'.format(
        lattice.orientation_matrix))

    assert_true(np.allclose(lattice.angles, 3 * [90.0]))
    lattice_region = Cuboid(pmax=lattice.lengths)

    # lattice_region = Parallelepiped(u=lattice.a * xhat,
    #                                 v=lattice.b * yhat,
    #                                 w=lattice.c * zhat)
    assert_equal(lattice_region.a, lattice.a)
    assert_equal(lattice_region.b, lattice.b)
    assert_equal(lattice_region.c, lattice.c)
    print('lattice_region:\n{}'.format(lattice_region))
    print('lattice_region.centroid:\n{}'.format(lattice_region.centroid))

    print('\nrotating lattice_region')
    lattice_region.rotate(transform_matrix=lattice.orientation_matrix)
    # assert_equal(lattice_region.a, lattice.a)
    # assert_equal(lattice_region.b, lattice.b)
    # assert_equal(lattice_region.c, lattice.c)
    print('lattice_region:\n{}'.format(lattice_region))
    print('lattice_region.centroid:\n{}'.format(lattice_region.centroid))

    print('\ncentering lattice_region on graphene centroid')
    tvec = Vector(Point(graphene.centroid) - lattice_region.centroid)
    lattice_region.translate(tvec)
    # assert_equal(lattice_region.a, lattice.a)
    # assert_equal(lattice_region.b, lattice.b)
    # assert_equal(lattice_region.c, lattice.c)
    print('lattice_region:\n{}'.format(lattice_region))
    print('lattice_region.centroid:\n{}'.format(lattice_region.centroid))

    bounding_box = generate_bounding_box(from_lattice=lattice,
                                         center=graphene.centroid,
                                         verbose=True)
    print('bounding_box:\n{}'.format(bounding_box))
    assert_equal(bounding_box, lattice_region)
    print('lattice_region.lengths: {}, {}, {}'.format(lattice_region.a,
                                                      lattice_region.b,
                                                      lattice_region.c))
示例#10
0
def test13():
    latt = Crystal3DLattice(a=4.0, b=4.0, c=4.0, alpha=90, beta=90, gamma=90)
    print(latt)
    p = [2.1, 0.9, 0.5]
    assert_true(
        np.allclose(latt.wrap_fractional_coordinate(p), Point(
            (0.1, 0.9, 0.5))))
示例#11
0
    def contains(self, point):
        """Test region membership of `point` in :class:`Sphere`.

        Parameters
        ----------
        point : array_like

        Returns
        -------
        :class:`~python:bool`
            `True` if `point` is within :class:`Sphere`,
            `False` otherwise.

        Notes
        -----
        A `point` :math:`(p_x, p_y, p_z)` is within the bounded region
        of a sphere with center :math:`(h, k, l)` and radius :math:`r`
        if the following is true:

        .. math::

           (p_x - h)^2 + (p_y - k)^2 + (p_z - l)^2 \\le r^2

        """
        x, y, z = Point(point)
        h, k, l = self.center
        r = self.r

        return (x - h)**2 + (y - k)**2 + (z - l)**2 <= r**2
示例#12
0
    def contains(self, point):
        """Test region membership of `point` in :class:`Ellipsoid`.

        Parameters
        ----------
        point : array_like

        Returns
        -------
        :class:`~python:bool`
            `True` if `point` is within :class:`Ellipsoid`,
            `False` otherwise

        Notes
        -----
        A `point` :math:`(p_x, p_y, p_z)` is within the bounded region of
        an ellipsoid with center :math:`(c_x, c_y, c_z)` and semi-axes lengths
        :math:`r_x, r_y, r_z` if the following is true:

        .. math::

           \\left(\\frac{p_x - c_x}{r_x}\\right)^2 +
           \\left(\\frac{p_y - c_y}{r_y}\\right)^2 +
           \\left(\\frac{p_z - c_z}{r_z}\\right)^2\\le 1

        """
        px, py, pz = Point(point)
        cx, cy, cz = self.center
        rx, ry, rz = self.rx, self.ry, self.rz

        q1 = (px - cx)**2 / rx**2
        q2 = (py - cy)**2 / ry**2
        q3 = (pz - cz)**2 / rz**2

        return q1 + q2 + q3 <= 1.0
示例#13
0
    def centroid(self):
        """:class:`Triangle` centroid, :math:`(c_x, c_y)`.

        Computed as 2D :class:`Point` :math:`(c_x, c_y)` with
        coordinates:

        .. math::

           c_x = \\frac{x_1 + x_2 + x_3}{3}

           c_y = \\frac{y_1 + y_2 + y_3}{3}

        Returns
        -------
        :class:`Point`
            2D :class:`Point` of centroid.

        """
        x1, y1 = self.p1
        x2, y2 = self.p2
        x3, y3 = self.p3

        cx = (x1 + x2 + x3) / 3
        cy = (y1 + y2 + y3) / 3
        return Point([cx, cy])
示例#14
0
    def __init__(self, o=None, u=None, v=None, w=None):

        self._o = Point()
        self._u = Vector()
        self._v = Vector()
        self._w = Vector()

        super().__init__()

        if o is None:
            o = [0, 0, 0]
        self.o = o

        if u is None:
            u = [1, 0, 0]
        self.u = u

        if v is None:
            v = [1, 1, 0]
        self.v = v

        if w is None:
            w = [0, 1, 1]
        self.w = w

        self.points.append(self.o)
        self.vectors.extend([self.u, self.v, self.w])

        self.fmtstr = "o={o!r}, u={u!r}, v={v!r}, w={w!r}"
示例#15
0
    def contains(self, point):
        """Test region membership of `point` in :class:`Square`.

        Parameters
        ----------
        point : array_like

        Returns
        -------
        :class:`~python:bool`
            `True` if `point` is within :class:`Square`,
            `False` otherwise.

        Notes
        -----
        A `point` :math:`(p_x, p_y)` is within the bounded region of a
        square with center :math:`(c_x, c_y)` and side length :math:`a`
        if the following is true:

        .. math::

           c_i - \\frac{a}{2}\\le p_i\\le c_i + \\frac{a}{2}\\forall
           i\\in \\{x, y\\}

        """
        px, py = Point(point)
        cx, cy = self.center
        a = self.a
        xmin = cx - a / 2
        xmax = cx + a / 2
        ymin = cy - a / 2
        ymax = cy + a / 2
        return (px >= xmin) and (px <= xmax) and (py >= ymin) and (py <= ymax)
示例#16
0
    def centroid(self):
        """Paralleogram centroid, :math:`(c_x, c_y)`.

        Computed as the 2D point :math:`(c_x, c_y)` with coordinates:

        .. math::

           c_x = o_x + \\frac{u_x + v_x}{2}

           c_y = o_y + \\frac{u_y + v_y}{2}

        where :math:`(o_x, o_y)`, :math:`(u_x, u_y)`, and :math:`(v_x, v_y)`
        are the :math:`(x, y)` coordinates of the origin :math:`o`
        and :math:`(x, y)` components of the direction vectors
        :math:`\\mathbf{u}` and :math:`\\mathbf{v}`, respectively.

        Returns
        -------
        :class:`Point`
            2D :class:`Point` of centroid.

        """
        ox, oy = self.o
        ux, uy = self.u
        vx, vy = self.v

        cx = ox + (ux + vx) / 2
        cy = oy + (uy + vy) / 2

        return Point([cx, cy])
示例#17
0
    def __init__(self, p1=None, p2=None, r=1):
        super().__init__()

        self._p1 = Point()
        self._p2 = Point()

        if p1 is None:
            p1 = [0, 0, -1]
        if p2 is None:
            p2 = [0, 0, 1]

        self.p1 = p1
        self.p2 = p2
        self.points.extend([self.p1, self.p2])
        self.r = r
        self.fmtstr = "p1={p1!r}, p2={p2!r}, r={r:.3f}"
示例#18
0
def test_rectangle():
    r = Rectangle()
    assert_is_instance(r, Rectangle)
    assert_equal(r.measure, 1)
    assert_equal(r.centroid, Point([0.5, 0.5]))
    assert_true(r.contains(r.centroid))
    assert_false(r.contains([1.1, 1.1]))
    assert_is_instance(r.centroid, Point)
示例#19
0
def test_cuboid():
    r = Cuboid()
    assert_is_instance(r, Cuboid)
    assert_equal(r.centroid, Point([0.5, 0.5, 0.5]))
    assert_true(np.allclose(r.measure, 1.0))
    assert_true(r.contains(r.centroid))
    assert_false(r.contains([-0.1, 0, 0]))
    assert_is_instance(r.centroid, Point)
示例#20
0
def test_square():
    r = Square()
    assert_is_instance(r, Square)
    assert_equal(r.measure, 1)
    assert_equal(r.centroid, Point([0, 0]))
    assert_true(r.contains([0, 0]))
    assert_false(r.contains([1, 1]))
    assert_is_instance(r.centroid, Point)
示例#21
0
    def __init__(self,
                 nd=None,
                 cell_matrix=None,
                 orientation_matrix=None,
                 offset=None):
        super().__init__()

        self.nd = nd
        self.offset = Point(offset, nd=3)
        if cell_matrix is not None and orientation_matrix is None:
            orientation_matrix = cell_matrix.T * self.fractional_matrix

        if orientation_matrix is None:
            orientation_matrix = np.asmatrix(np.identity(3))

        self.orientation_matrix = np.asmatrix(orientation_matrix)
        self.lattice_type = None
示例#22
0
def test_ellipsoid():
    r = Ellipsoid()
    assert_is_instance(r, Ellipsoid)
    assert_equal(r.centroid, Point([0, 0, 0]))
    assert_true(np.allclose(r.measure, 4 / 3 * np.pi))
    assert_true(r.contains(r.centroid))
    assert_false(r.contains([1.01, 1.01, 1.01]))
    assert_is_instance(r.centroid, Point)
示例#23
0
def test_cube():
    r = Cube()
    assert_is_instance(r, Cube)
    assert_equal(r.centroid, Point([0, 0, 0]))
    assert_true(np.allclose(r.measure, 1.0))
    assert_true(r.contains([0, 0, 0]))
    assert_false(r.contains([1, 1, 1]))
    assert_is_instance(r.centroid, Point)
示例#24
0
    def __init__(self, pmin=None, pmax=None, xmin=0, ymin=0, xmax=1, ymax=1):

        super().__init__()

        self._pmin = Point(nd=2)
        self._pmax = Point(nd=2)

        if pmin is None:
            pmin = [xmin, ymin]
        self.pmin = pmin

        if pmax is None:
            pmax = [xmax, ymax]
        self.pmax = pmax

        self.points.append([self.pmin, self.pmax])

        self.fmtstr = "pmin={pmin!r}, pmax={pmax!r}"
示例#25
0
def test_circle():
    r = Circle()
    assert_is_instance(r, Circle)
    assert_equal(r.measure, np.pi)
    assert_equal(r.centroid, Point([0, 0]))
    assert_equal(r.r, 1.0)
    assert_true(r.contains([0, 0]))
    assert_false(r.contains([1.1, 0]))
    assert_is_instance(r.centroid, Point)
示例#26
0
def test_sphere():
    r = Sphere()
    assert_is_instance(r, Sphere)
    assert_equal(r.center, Point([0, 0, 0]))
    assert_equal(r.r, 1.0)
    assert_true(np.allclose(r.measure, 4 / 3 * np.pi))
    assert_true(r.contains([0, 0, 0]))
    assert_false(r.contains([1.1, 1.1, 1.1]))
    assert_is_instance(r.centroid, Point)
示例#27
0
    def contains(self, point):
        """Test region membership of `point` in :class:`Cone`.

        Parameters
        ----------
        point : array_like

        Returns
        -------
        :class:`~python:bool`
            `True` if `point` is within :class:`Cone`,
            `False` otherwise.

        Notes
        -----
        A `point` :math:`(p_x, p_y, p_z)` is within the bounded region
        of a cone with a base of radius :math:`r` centered at
        :math:`p_1=(x_1, y_1, z_1)` and tip at :math:`p_2 = (x_2, y_2, z_2)`
        if the following is true:

        .. math::

           0\\le q\\le 1\\land
           (x_1 - p_x + (x_2 - x_1) q)^2 +
           (y_1 - p_y + (y_2 - y_1) q)^2 +
           (z_1 - p_z + (z_2 - z_1) q)^2 \\le r^2 q^2

        where :math:`q` is:

        .. math::

           q = \\frac{(p_x - x_1)(x_2 - x_1) +
           (p_y - y_1)(y_2 - y_1) +
           (p_z - z_1)(z_2 - z_1)}{(x_2 - x_1)^2 +
           (y_2 - y_1)^2 + (z_2 - z_1)^2}

        """
        px, py, pz = Point(point)
        x1, y1, z1 = self.p1
        x2, y2, z2 = self.p2
        r = self.r

        q1 = ((px - x1) * (x2 - x1) +
              (py - y1) * (y2 - y1) +
              (pz - z1) * (z2 - z1)) / \
            ((x2 - x1) ** 2 + (y2 - y1) ** 2 + (z2 - z1) ** 2)

        q2 = (x1 - px + (x2 - x1) * q1) ** 2 + \
            (y1 - py + (y2 - y1) * q1) ** 2 + \
            (z1 - pz + (z2 - z1) * q1) ** 2

        q3 = r**2 * q1**2

        return (not np.allclose(x1, x2) or not np.allclose(y1, y2) or
                not np.allclose(z1, z2)) and r > 0 and q1 >= 0 and q1 <= 1 \
            and q2 <= q3
示例#28
0
    def __init__(self, p1=None, p2=None, p3=None):
        super().__init__()

        self._p1 = Point(nd=2)
        self._p2 = Point(nd=2)
        self._p3 = Point(nd=2)

        if p1 is None:
            p1 = [0, 0]
        if p2 is None:
            p2 = [0, 1]
        if p3 is None:
            p3 = [1, 0]

        self.p1 = p1
        self.p2 = p2
        self.p3 = p3
        self.points.extend([self.p1, self.p2, self.p3])
        self.fmtstr = "p1={p1!r}, p2={p2!r}, p3={p3!r}"
示例#29
0
def test_point_rotation():
    assert_true(
        np.allclose(rotate(Point([1.0, 0.0]), np.pi / 2), np.array([0.0,
                                                                    1.0])))

    with assert_raises(ValueError):
        np.allclose(rotate(Point([1.0, 0.0, 0.0]), angle=np.pi / 2),
                    np.array([0.0, 1.0, 0.0]))

    assert_true(
        np.allclose(
            rotate(Point([1.0, 0.0, 0.0]),
                   angle=np.pi / 2,
                   axis=Vector([1.0, 0.0, 0.0])), np.array([1.0, 0.0, 0.0])))

    assert_true(
        np.allclose(
            rotate(Point([0.0, 1.0, 0.0]),
                   angle=np.pi / 2,
                   axis=Vector([1.0, 0.0, 0.0])), np.array([0.0, 0.0, 1.0])))
示例#30
0
    def i(self, value):
        """Set :math:`i_x, i_y, i_z` image flags.

        Parameters
        ----------
        value : array_like

        """
        if not isinstance(value, (list, np.ndarray)):
            raise TypeError('Expected an array_like object')
        self._i[:] = Point(value, nd=3, dtype=int)
示例#31
0
    def __init__(self, nd=None, cell_matrix=None, orientation_matrix=None,
                 offset=None):
        super().__init__()

        self.nd = nd
        self.offset = Point(offset, nd=3)
        if cell_matrix is not None and orientation_matrix is None:
            orientation_matrix = cell_matrix.T * self.fractional_matrix

        if orientation_matrix is None:
            orientation_matrix = np.asmatrix(np.identity(3))

        self.orientation_matrix = np.asmatrix(orientation_matrix)
        self.lattice_type = None
示例#32
0
def test3():
    p = Point([1.0, 0.0, 0.0])
    p.rotate(np.pi/2, rot_axis='z')
    assert_true(np.allclose(p, np.array([0, 1, 0])))
    p.rotate(np.pi/2, rot_axis='z')
    assert_true(np.allclose(p, np.array([-1, 0, 0])))
    p.rotate(np.pi/2, rot_axis='z')
    assert_true(np.allclose(p, np.array([0, -1, 0])))
    p.rotate(np.pi/2, rot_axis='z')
    assert_true(np.allclose(p, np.array([1, 0, 0])))
    p.rotate(np.pi/2, rot_axis=[0, 0, 1], rot_point=[1, 1, 0])
    assert_true(np.allclose(p, np.array([2, 1, 0])))
示例#33
0
def test2():
    p = Point([1e-9, 1e-11, -1e-16])
    p.rezero(epsilon=1e-10)
    assert_not_equal(p.x, 0.0)
    assert_equal(p.y, 0.0)
    assert_equal(p.z, 0.0)
示例#34
0
class LatticeBase(BaseClass):
    """Base class for crystallographic lattice objects.

    Parameters
    ----------
    nd : int
    cell_matrix : array_like
    orientation_matrix : array_like, optional
    offset : array_like, optional

    """

    def __init__(self, nd=None, cell_matrix=None, orientation_matrix=None,
                 offset=None):
        super().__init__()

        self.nd = nd
        self.offset = Point(offset, nd=3)
        if cell_matrix is not None and orientation_matrix is None:
            orientation_matrix = cell_matrix.T * self.fractional_matrix

        if orientation_matrix is None:
            orientation_matrix = np.asmatrix(np.identity(3))

        self.orientation_matrix = np.asmatrix(orientation_matrix)
        self.lattice_type = None

    def __dir__(self):
        return ['nd', 'offset', 'orientation_matrix']

    def __eq__(self, other):
        if isinstance(other, type(self)):
            return self is other or \
                all([np.allclose(getattr(self, attr), getattr(other, attr))
                     for attr in dir(self)])

    def __lt__(self, other):
        if isinstance(other, type(self)):
            try:
                return self.cell_volume < other.cell_volume
            except AttributeError:
                return self.cell_area < other.cell_area

    @property
    def cell_matrix(self):
        """Matrix of lattice row vectors.

        Same as :attr:`Crystal2DLattice.ortho_matrix`\ .T or
        :attr:`Crystal3DLattice.ortho_matrix`\ .T.

        """
        return (self.orientation_matrix * self.ortho_matrix).T

    @property
    def matrix(self):
        """Alias for \
            :attr:`~sknano.core.crystallography.LatticeBase.cell_matrix`."""
        return self.cell_matrix

    @property
    def fractional_matrix(self):
        """Transformation matrix to convert from cartesian coordinates to \
            fractional coordinates."""
        return np.linalg.inv(self.ortho_matrix)

    @property
    def metric_tensor(self):
        """Metric tensor."""
        return self.cell_matrix * self.cell_matrix.T

    def fractional_to_cartesian(self, fcoords):
        """Convert fractional coordinate to cartesian coordinate.

        Parameters
        ----------
        fcoords : array_like

        Returns
        -------
        :class:`~numpy:numpy.ndarray`

        """
        ccoords = self.orientation_matrix * self.ortho_matrix * \
            np.asmatrix(fcoords).T + self.offset.column_matrix
        try:
            return ccoords.T.A.reshape((3, ))
        except ValueError:
            return ccoords.T.A.reshape((len(fcoords), 3))

    def cartesian_to_fractional(self, ccoords):
        """Convert cartesian coordinate to fractional coordinate.

        Parameters
        ----------
        ccoords : array_like

        Returns
        -------
        :class:`~numpy:numpy.ndarray`

        """
        fcoords = np.linalg.inv(self.ortho_matrix) * \
            np.linalg.inv(self.orientation_matrix) * \
            (np.asmatrix(ccoords).T - self.offset.column_matrix)
        try:
            return fcoords.T.A.reshape((3, ))
        except ValueError:
            return fcoords.T.A.reshape((len(ccoords), 3))

    def wrap_fractional_coordinate(self, p, epsilon=1e-6, pbc=None):
        """Wrap fractional coordinate to lie within unit cell.

        Parameters
        ----------
        p : array_like

        Returns
        -------
        :class:`~numpy:numpy.ndarray`

        """
        if pbc is None:
            pbc = np.asarray(np.ones(3), dtype=bool)

        p = np.ma.array(p, mask=~pbc)
        p = np.ma.fmod(p, 1)
        p[np.ma.where(p < 0)] += 1
        p[np.ma.where(p > 1 - epsilon)] -= 1
        p[np.ma.where(np.logical_or((p > 1 - epsilon), (p < epsilon)))] = 0
        p.mask = np.ma.nomask
        return p.tolist()

    def wrap_cartesian_coordinate(self, p, pbc=None):
        """Wrap cartesian coordinate to lie within unit cell.

        Parameters
        ----------
        p : array_like

        Returns
        -------
        :class:`~numpy:numpy.ndarray`

        """
        return self.fractional_to_cartesian(
            self.wrap_fractional_coordinate(self.cartesian_to_fractional(p),
                                            pbc=pbc))

    def rotate(self, angle=None, axis=None, anchor_point=None,
               rot_point=None, from_vector=None, to_vector=None, degrees=False,
               transform_matrix=None, verbose=False, **kwargs):
        """Rotate unit cell.

        Parameters
        ----------
        angle : float
        axis : :class:`~sknano.core.math.Vector`, optional
        anchor_point : :class:`~sknano.core.math.Point`, optional
        rot_point : :class:`~sknano.core.math.Point`, optional
        from_vector, to_vector : :class:`~sknano.core.math.Vector`, optional
        degrees : bool, optional
        transform_matrix : :class:`~numpy:numpy.ndarray`

        See Also
        --------
        core.math.rotate

        """
        if self.nd == 2:
            axis = 'z'
        if transform_matrix is None:
            transform_matrix = \
                np.asmatrix(
                    rotation_matrix(angle=angle, axis=axis,
                                    anchor_point=anchor_point,
                                    rot_point=rot_point,
                                    from_vector=from_vector,
                                    to_vector=to_vector, degrees=degrees,
                                    verbose=verbose, **kwargs))
            # print('transform_matrix: {}'.format(transform_matrix))

            # transform_matrix = \
            #     transformation_matrix(angle=angle, axis=axis,
            #                           anchor_point=anchor_point,
            #                           rot_point=rot_point,
            #                           from_vector=from_vector,
            #                           to_vector=to_vector, degrees=degrees,
            #                           verbose=verbose, **kwargs)

        self.orientation_matrix = \
            transform_matrix * self.orientation_matrix

    def translate(self, t):
        """Translate lattice.

        Parameters
        ----------
        t : :class:`Vector`

        See Also
        --------
        core.math.translate

        """
        self.offset.translate(t)