# Path: batoid/utils.py
# class lazy_property(object):
#     """
#     meant to be used for lazy evaluation of an object attribute.
#     property should represent non-mutable data, as it replaces itself.
#     """
#     def __init__(self, fget):
#         self.fget = fget
#         self.func_name = fget.__name__
# 
#     def __get__(self, obj, cls):
#         if obj is None:
#             return self
#         value = self.fget(obj)
#         setattr(obj, self.func_name, value)
#         return value


import numpy as np
from .utils import lazy_property
    Notes
    -----
        The ``coords`` attribute will contain the coordinates of each lattice
        point determined by the coordinate index and the primitive lattice
        vectors.  E.g., in 2-dimensions

            lattice.coord[i, j] = (i - N1//2) * primitiveVector[0] + (j - N2//2) * primitiveVector[1]

        Note, this convention places

            lattice.coord[0,0] = (-N1//2) * primitiveVector[0] + (-N2/2) * primitiveVector[1]

        but the location of lattice.coord[-1,-1] depends on whether the size of
        each dimension is even or odd.  An odd-sized dimension is "centered", in
        that the 0-coordinate is precisely in the middle of the dimension.  An
        even-sized dimension will be slightly decentered, with more negative
        points than positive points.  The above convention is the same as for
        numpy.fft.fftfreq.
    """
    def __init__(self, array, primitiveVectors):
        primitiveVectors = np.atleast_2d(primitiveVectors)

        if array.ndim != len(primitiveVectors):
            raise ValueError("Not enough primitiveVectors for array")
        if array.ndim != len(primitiveVectors[0]):
            raise ValueError("primitiveVectors are too small for array")

        self.array = array
        self.primitiveVectors = primitiveVectors


# Path: batoid/utils.py
# class lazy_property(object):
#     """
#     meant to be used for lazy evaluation of an object attribute.
#     property should represent non-mutable data, as it replaces itself.
#     """
#     def __init__(self, fget):
#         self.fget = fget
#         self.func_name = fget.__name__
# 
#     def __get__(self, obj, cls):
#         if obj is None:
#             return self
#         value = self.fget(obj)
#         setattr(obj, self.func_name, value)
#         return value


# Path: batoid/lattice.py
import numpy as np
from .utils import lazy_property

    Notes
    -----
        The ``coords`` attribute will contain the coordinates of each lattice
        point determined by the coordinate index and the primitive lattice
        vectors.  E.g., in 2-dimensions

            lattice.coord[i, j] = (i - N1//2) * primitiveVector[0] + (j - N2//2) * primitiveVector[1]

        Note, this convention places

            lattice.coord[0,0] = (-N1//2) * primitiveVector[0] + (-N2/2) * primitiveVector[1]

        but the location of lattice.coord[-1,-1] depends on whether the size of
        each dimension is even or odd.  An odd-sized dimension is "centered", in
        that the 0-coordinate is precisely in the middle of the dimension.  An
        even-sized dimension will be slightly decentered, with more negative
        points than positive points.  The above convention is the same as for
        numpy.fft.fftfreq.
    """
    def __init__(self, array, primitiveVectors):
        primitiveVectors = np.atleast_2d(primitiveVectors)

        if array.ndim != len(primitiveVectors):
            raise ValueError("Not enough primitiveVectors for array")
        if array.ndim != len(primitiveVectors[0]):
            raise ValueError("primitiveVectors are too small for array")

        self.array = array
        self.primitiveVectors = primitiveVectors


    @lazy_property