Esempio n. 1
0
def set_item(handle, uids, value):
    root = handle.root
    if hasattr(root, 'my_data_table'):
        handle.remove_node(root, 'my_data_table', recursive=True)
    table = IndexedDataContainerTable(root, 'my_data_table', expected_number=n)
    for uid in uids:
        table[uid] = value
Esempio n. 2
0
    def __init__(self, group, meshFile):

        if not ("cuds_version" in group._v_attrs):
            group._v_attrs.cuds_version = MESH_CUDS_VERSION
        else:
            if group._v_attrs.cuds_version != MESH_CUDS_VERSION:
                raise ValueError(
                    "Mesh file layout has an incompatible version")

        self._file = meshFile
        self._group = group
        self._data = IndexedDataContainerTable(group, 'data')
        self._uidData = DataContainerTable(self._group, 'item_data')

        if "points" not in self._group:
            self._create_points_table()

        if "edges" not in self._group:
            self._create_edges_table()

        if "faces" not in self._group:
            self._create_faces_table()

        if "cells" not in self._group:
            self._create_cells_table()

        self._items_count = {
            CUDSItem.POINT: lambda: self._group.points,
            CUDSItem.EDGE: lambda: self._group.edges,
            CUDSItem.FACE: lambda: self._group.faces,
            CUDSItem.CELL: lambda: self._group.cells
        }
Esempio n. 3
0
    def __init__(self, group):
        """ Return a reference to existing lattice in a H5CUDS group.

        Parameters
        ----------
        group : HDF5 group in PyTables file
            reference to a group (folder) in PyTables file where the tables
            for lattice and data are located

        """
        if group._v_attrs.cuds_version != LATTICE_CUDS_VERSION:
            raise ValueError("Lattice file layout has an incompatible version")

        self._group = group
        attrs = group.lattice.attrs
        self._primitive_cell = PrimitiveCell(
            attrs.primitive_cell[0], attrs.primitive_cell[1],
            attrs.primitive_cell[2], BravaisLattice(attrs.bravais_lattice))

        self._size = attrs.size
        self._origin = attrs.origin

        self._table = IndexedDataContainerTable(group, 'lattice')
        self._data = IndexedDataContainerTable(group, 'data')

        self._items_count = {CUDSItem.NODE: lambda: self._table}
Esempio n. 4
0
def main():
    try:
        print("""
        Benchmarking various operations on the IndexDataContainerTable.

        """)
        with closing(tables.open_file(filename, mode='w')) as handle:
            root = handle.root
            table = IndexedDataContainerTable(root, 'my_data_table')
            print("Append {}:".format(n),
                  bench(lambda: append(handle, 1000, data_container)))

        with closing(tables.open_file(filename, mode='w')) as handle:
            root = handle.root
            table = IndexedDataContainerTable(root,
                                              'my_data_table',
                                              expected_number=n)
            print("Append {} masked:".format(n),
                  bench(lambda: append(handle, 1000, data_container_half)))

        uids = create_table(filename)
        sample = random.sample(uids, 300)

        with closing(tables.open_file(filename, mode='r')) as handle:
            root = handle.root
            table = IndexedDataContainerTable(root,
                                              'my_data_table',
                                              expected_number=n)
            print("Iterate {}:".format(n), bench(lambda: iteration(table)))
            print('Getitem sample of 300:',
                  bench(lambda: getitem_access(table, sample)))

        with closing(tables.open_file(filename, mode='a')) as handle:
            root = handle.root
            table = IndexedDataContainerTable(root,
                                              'my_data_table',
                                              expected_number=n)
            print("Update item of 300 sample:",
                  bench(lambda: setitem(table, data_container_half, sample)))
    finally:
        shutil.rmtree(temp_dir)
Esempio n. 5
0
 def open_table(self, table_name, mode='r'):
     handle = None
     try:
         handle = tables.open_file(self.filename, mode=mode)
         root = handle.root
         table = IndexedDataContainerTable(root,
                                           table_name,
                                           record=self.record)
         yield table
     finally:
         if handle is not None:
             handle.close()
Esempio n. 6
0
 def new_table(self, table_name):
     handle = None
     try:
         handle = tables.open_file(self.filename, mode='w')
         root = handle.root
         table = IndexedDataContainerTable(root,
                                           table_name,
                                           record=self.record)
         self.assertEqual(len(table), 0)
         yield table
     finally:
         if handle is not None:
             handle.close()
 def test_creating_a_data_container_table_using_default_record(self):
     with closing(tables.open_file(self.filename, mode='w')) as handle:
         root = handle.root
         table = IndexedDataContainerTable(root, 'my_data_table')
         self.assertEqual(len(table), 0)
         self.assertIn('my_data_table', root)
         self.assertTrue(table.valid)
         data_column = root.my_data_table.colinstances['data']
         expected_column_names = [
             key.name.lower() for key in self.saved_keys
         ]
         self.assertItemsEqual(data_column._v_colnames,
                               expected_column_names)
Esempio n. 8
0
    def create_new(cls, group, primitive_cell, size, origin, record=None):
        """ Create a new lattice in H5CUDS file.

        Parameters
        ----------
        group : HDF5 group in PyTables file
            reference to a group (folder) in PyTables file where the tables
            for lattice and data will be located
        primitive_cell : PrimitiveCell
            primitive cell specifying the 3D Bravais lattice
        size : int[3]
            number of lattice nodes (in the direction of each axis).
        origin : float[3]
            origin of lattice
        record : tables.IsDescription
            A class that describes column types for PyTables table.

        """
        group._v_attrs.cuds_version = LATTICE_CUDS_VERSION

        # If record not specified use NoUIDRecord in table initialization
        lattice = IndexedDataContainerTable(group, 'lattice',
                                            record if record is not None
                                            else NoUIDRecord, np.prod(size))
        for i in xrange(np.prod(size)):
            lattice.append(DataContainer())

        pc = primitive_cell
        lattice._table.attrs.primitive_cell = [pc.p1, pc.p2, pc.p3]
        lattice._table.attrs.bravais_lattice = pc.bravais_lattice
        lattice._table.attrs.size = size
        lattice._table.attrs.origin = origin

        IndexedDataContainerTable(group, 'data', NoUIDRecord, 1)

        return cls(group)
Esempio n. 9
0
    def __init__(self, group):
        if not ("cuds_version" in group._v_attrs):
            group._v_attrs.cuds_version = PARTICLES_CUDS_VERSION
        else:
            if group._v_attrs.cuds_version != PARTICLES_CUDS_VERSION:
                raise ValueError(
                    "Particles file layout has an incompatible version")

        self._group = group
        self._data = IndexedDataContainerTable(group, 'data')
        self._particles = H5ParticleItems(group, 'particles')
        self._bonds = H5BondItems(group, 'bonds')

        self._items_count = {
            CUDSItem.PARTICLE: lambda: self._particles,
            CUDSItem.BOND: lambda: self._bonds
        }
Esempio n. 10
0
class H5Particles(ABCParticles):
    """ An HDF5 backed particle container.

    """
    def __init__(self, group):
        if not ("cuds_version" in group._v_attrs):
            group._v_attrs.cuds_version = PARTICLES_CUDS_VERSION
        else:
            if group._v_attrs.cuds_version != PARTICLES_CUDS_VERSION:
                raise ValueError(
                    "Particles file layout has an incompatible version")

        self._group = group
        self._data = IndexedDataContainerTable(group, 'data')
        self._particles = H5ParticleItems(group, 'particles')
        self._bonds = H5BondItems(group, 'bonds')

        self._items_count = {
            CUDSItem.PARTICLE: lambda: self._particles,
            CUDSItem.BOND: lambda: self._bonds
        }

    @property
    def name(self):
        """ The name of the container
        """
        return self._group._v_name

    @name.setter
    def name(self, value):
        self._group._f_rename(value)

    @property
    def data(self):
        if len(self._data) == 1:
            return self._data[0]
        else:
            return DataContainer()

    @data.setter
    def data(self, value):
        if len(self._data) == 0:
            self._data.append(value)
        else:
            self._data[0] = value

    # Particle methods ######################################################

    def add_particles(self, iterable):
        """Add a set of particles.

        If the particles have a uid set then they are used. If any of the
        particle's uid is None then a new uid is generated for the
        particle.

        Returns
        -------
        uid : uuid.UUID
            uid of particle.

        Raises
        ------
        ValueError :
           Any particle uid already exists in the container.

        """
        uids = []
        for particle in iterable:
            uids.append(self._add_particle(particle))
        return uids

    def update_particles(self, iterable):
        for particle in iterable:
            self._update_particle(particle)

    def get_particle(self, uid):
        return self._particles[uid]

    def remove_particles(self, uids):
        for uid in uids:
            self._remove_particle(uid)

    def iter_particles(self, ids=None):
        """Get iterator over particles"""
        if ids is None:
            return iter(self._particles)
        else:
            return self._particles.itersequence(ids)

    def has_particle(self, uid):
        """Checks if a particle with uid "uid" exists in the container."""
        return uid in self._particles

    # Bond methods #######################################################

    def add_bonds(self, iterable):
        """Add a set of bonds.

        If the bonds have an uid then they are used. If any of the
        bond's uid is None then a uid is generated for the
        bond.

        Returns
        -------
        uid : uuid.UUID
            uid of bond

        Raises
        ------
        ValueError :
           if an uid is given which already exists.

        """
        uids = []
        for bond in iterable:
            uids.append(self._add_bond(bond))
        return uids

    def update_bonds(self, iterable):
        for bond in iterable:
            self._update_bond(bond)

    def get_bond(self, uid):
        return self._bonds[uid]

    def remove_bonds(self, uids):
        for uid in uids:
            self._remove_bond(uid)

    def iter_bonds(self, ids=None):
        """Get iterator over particles"""
        if ids is None:
            return iter(self._bonds)
        else:
            return self._bonds.itersequence(ids)

    def has_bond(self, uid):
        """Checks if a bond with uid "uid" exists in the container."""
        return uid in self._bonds

    def count_of(self, item_type):
        """ Return the count of item_type in the container.

        Parameters
        ----------
        item_type : CUDSItem
            The CUDSItem enum of the type of the items to return the count of.

        Returns
        -------
        count : int
            The number of items of item_type in the container.

        Raises
        ------
        ValueError :
            If the type of the item is not supported in the current
            container.

        """
        try:
            return len(self._items_count[item_type]())
        except KeyError:
            error_str = "Trying to obtain count a of non-supported item: {}"
            raise ValueError(error_str.format(item_type))

    # Private methods --- these are temporary till we optimize things

    def _add_particle(self, particle):
        uid = particle.uid
        if uid is None:
            uid = uuid.uuid4()
            particle.uid = uid
            self._particles.add_unsafe(particle)
        else:
            self._particles.add_safe(particle)
        return uid

    def _update_particle(self, particle):
        self._particles.update_existing(particle)

    def _remove_particle(self, uid):
        del self._particles[uid]

    def _add_bond(self, bond):
        uid = bond.uid
        if uid is None:
            uid = uuid.uuid4()
            bond.uid = uid
            self._bonds.add_unsafe(bond)
        else:
            self._bonds.add_safe(bond)
        return uid

    def _update_bond(self, bond):
        self._bonds.update_existing(bond)

    def _remove_bond(self, uid):
        del self._bonds[uid]
Esempio n. 11
0
class H5Mesh(ABCMesh):
    """ H5Mesh.

    Interface of the mesh file driver.
    Stores general mesh information Points and Elements
    such as Edges, Faces and Cells and provide the
    methods to interact with them. The methods are
    divided in four diferent blocks:

    (1) methods to get the related item with the provided uid;
    (2) methods to add a new item or replace;
    (3) generator methods that return iterators
        over all or some of the mesh items and;
    (4) inspection methods to identify if there are any edges,
        faces or cells described in the mesh.

    Attributes
    ----------
    data : Data
        Data relative to the mesh
    name : String
        Name of the mesh

    See Also
    --------
    get_point, get_edge, get_face, get_cell
    add_point, add_edge, add_face, add_cell
    update_point, update_edge, update_face, update_cell
    iter_points, iter_edges, iter_faces, iter_cells
    has_edges, has_faces, has_cells
    _create_points_table, _create_edges_table
    _create_faces_table, _create_cells_table

    """

    def __init__(self, group, meshFile):

        if not ("cuds_version" in group._v_attrs):
            group._v_attrs.cuds_version = MESH_CUDS_VERSION
        else:
            if group._v_attrs.cuds_version != MESH_CUDS_VERSION:
                raise ValueError(
                    "Mesh file layout has an incompatible version")

        self._file = meshFile
        self._group = group
        self._data = IndexedDataContainerTable(group, 'data')
        self._uidData = DataContainerTable(self._group, 'item_data')

        if "points" not in self._group:
            self._create_points_table()

        if "edges" not in self._group:
            self._create_edges_table()

        if "faces" not in self._group:
            self._create_faces_table()

        if "cells" not in self._group:
            self._create_cells_table()

        self._items_count = {
            CUDSItem.POINT: lambda: self._group.points,
            CUDSItem.EDGE: lambda: self._group.edges,
            CUDSItem.FACE: lambda: self._group.faces,
            CUDSItem.CELL: lambda: self._group.cells
        }

    @property
    def name(self):
        return self._group._v_name

    @name.setter
    def name(self, value):
        self._group._f_rename(value)

    @property
    def data(self):
        if len(self._data) == 1:
            return self._data[0]
        else:
            return DataContainer()

    @data.setter
    def data(self, value):
        if len(self._data) == 0:
            self._data.append(value)
        else:
            self._data[0] = value

    def get_point(self, uid):
        """ Returns a point with a given uid.

        Returns the point stored in the mesh
        identified by uid. If such point do not
        exists an exception is raised.

        Parameters
        ----------
        uid : UUID
            uid of the desired point.

        Returns
        -------
        Point
            Mesh point identified by uid

        Raises
        ------
        Exception
            If the point identified by uid was not found

        """
        if not hasattr(uid, 'hex'):
            message = 'Expected type for `uid` is uuid.UUID but received {!r}'
            raise TypeError(message.format(type(uid)))

        for row in self._group.points.where(
                'uid == value', condvars={'value': uid.hex}):
            return Point(
                coordinates=tuple(row['coordinates']),
                uid=uuid.UUID(hex=row['uid'], version=4),
                data=self._uidData[uuid.UUID(hex=row['data'], version=4)])
        else:
            error_str = "Trying to get an non existing point with uid: {}"
            raise KeyError(error_str.format(uid))

    def get_edge(self, uid):
        """ Returns an edge with a given uid.

        Returns the edge stored in the mesh
        identified by uid. If such edge do not
        exists a exception is raised.

        Parameters
        ----------
        uid : UUID
            uid of the desired edge.

        Returns
        -------
        Edge
            Edge identified by uid

        Raises
        ------
        Exception
            If the edge identified by uid was not found

        """
        if not hasattr(uid, 'hex'):
            message = 'Expected type for `uid` is uuid.UUID but received {!r}'
            raise TypeError(message.format(type(uid)))

        for row in self._group.edges.where(
                'uid == value', condvars={'value': uid.hex}):
            return Edge(
                points=tuple(
                    uuid.UUID(hex=pb, version=4)
                    for pb in row['points_uids'][0:row['n_points']]),
                uid=uuid.UUID(hex=row['uid'], version=4),
                data=self._uidData[uuid.UUID(hex=row['data'], version=4)])
        else:
            error_str = "Trying to get an non existing edge with uid: {}"
            raise KeyError(error_str.format(uid))

    def get_face(self, uid):
        """ Returns an face with a given uid.

        Returns the face stored in the mesh
        identified by uid. If such face do not
        exists a exception is raised.

        Parameters
        ----------
        uid : UUID
            uid of the desired face.

        Returns
        -------
        Face
            Face identified by uid

        Raises
        ------
        Exception
            If the face identified by uid was not found

        """
        if not hasattr(uid, 'hex'):
            message = 'Expected type for `uid` is uuid.UUID but received {!r}'
            raise TypeError(message.format(type(uid)))

        for row in self._group.faces.where(
                'uid == value', condvars={'value': uid.hex}):
            return Face(
                uid=uuid.UUID(hex=row['uid'], version=4),
                points=tuple(
                    uuid.UUID(hex=pb, version=4)
                    for pb in row['points_uids'][:row['n_points']]),
                data=self._uidData[uuid.UUID(hex=row['data'], version=4)])
        else:
            error_str = "Trying to get an non existing face with uid: {}"
            raise KeyError(error_str.format(uid))

    def get_cell(self, uid):
        """ Returns an cell with a given uid.

        Returns the cell stored in the mesh
        identified by uid . If such cell do not
        exists a exception is raised.

        Parameters
        ----------
        uid : UUID
            uid of the desired cell.

        Returns
        -------
        Cell
            Cell identified by uid

        Raises
        ------
        Exception
            If the cell identified by uid was not found

        """
        if not hasattr(uid, 'hex'):
            message = 'Expected type for `uid` is uuid.UUID but received {!r}'
            raise TypeError(message.format(type(uid)))

        for row in self._group.cells.where(
                'uid == value', condvars={'value': uid.hex}):
            return Cell(
                points=tuple(
                    uuid.UUID(hex=pb, version=4)
                    for pb in row['points_uids'][0:row['n_points']]),
                uid=uuid.UUID(hex=row['uid'], version=4),
                data=self._uidData[uuid.UUID(hex=row['data'], version=4)])
        else:
            error_str = "Trying to get an non existing cell with id: {}"
            raise KeyError(error_str.format(uid))

    def add_points(self, points):
        """ Adds a new set of points to the mesh container.

        Parameters
        ----------
        points : iterable of Point
            Points to be added to the mesh container

        Raises
        ------
        KeyError
            If other point with the same uid was already
            in the mesh

        """
        rpoints = []
        for point in points:
            if point.uid is None:
                point.uid = self._generate_uid()

            for row in self._group.points.where(
                    'uid == value', condvars={'value': point.uid.hex}):
                raise ValueError(err_add.format('point', point.uid))

            row = self._group.points.row

            row['uid'] = point.uid.hex
            row['data'] = self._uidData.append(point.data).hex
            row['coordinates'] = point.coordinates

            row.append()
            rpoints.append(point.uid)

        self._group.points.flush()
        return rpoints

    def add_edges(self, edges):
        """ Adds a new set of edges to the mesh container.

        Parameters
        ----------
        edges : iterable of Edge
            Edges to be added to the mesh container

        Raises
        ------
        KeyError
            If other edge with the same uid was already
            in the mesh

        """
        redges = []
        for edge in edges:
            if edge.uid is None:
                edge.uid = self._generate_uid()
            else:
                for row in self._group.edges.where(
                        'uid == value', condvars={'value': edge.uid.hex}):
                    raise ValueError(err_add.format('edge', edge.uid))

            n = len(edge.points)

            row = self._group.edges.row

            row['uid'] = edge.uid.hex
            row['data'] = self._uidData.append(edge.data).hex
            row['n_points'] = n
            row['points_uids'] = [puid.hex for puid in
                                  edge.points] + [''] * (MAX_POINTS_IN_EDGE-n)

            row.append()
            redges.append(edge.uid)

        self._group.edges.flush()
        return redges

    def add_faces(self, faces):
        """ Adds a new set of faces to the mesh container.

        Parameters
        ----------
        faces : iterable of Face
            Faces to be added to the mesh container

        Raises
        ------
        KeyError
            If other face with the same uid was already
            in the mesh

        """
        rfaces = []
        for face in faces:
            if face.uid is None:
                face.uid = self._generate_uid()
            else:
                for row in self._group.faces.where(
                        'uid == value', condvars={'value': face.uid.hex}):
                    raise ValueError(err_add.format('face', face.uid))

            n = len(face.points)

            row = self._group.faces.row

            row['uid'] = face.uid.hex
            row['data'] = self._uidData.append(face.data).hex
            row['n_points'] = n
            row['points_uids'] = [puid.hex for puid in
                                  face.points] + [''] * (MAX_POINTS_IN_FACE-n)

            row.append()
            rfaces.append(face.uid)

        self._group.faces.flush()
        return rfaces

    def add_cells(self, cells):
        """ Adds a new set of cells to the mesh container.

        Parameters
        ----------
        cells : iterable of Cell
            Cells to be added to the mesh container

        Raises
        ------
        KeyError
            If other cell with the same uid was already
            in the mesh

        """
        rcells = []
        for cell in cells:
            if cell.uid is None:
                cell.uid = self._generate_uid()
            else:
                for row in self._group.cells.where(
                        'uid == value', condvars={'value': cell.uid.hex}):
                    raise ValueError(err_add.format('cell', cell.uid))

            n = len(cell.points)

            row = self._group.cells.row

            row['uid'] = cell.uid.hex
            row['data'] = self._uidData.append(cell.data).hex
            row['n_points'] = n
            row['points_uids'] = [puid.hex for puid in
                                  cell.points] + [''] * (MAX_POINTS_IN_CELL-n)

            row.append()
            rcells.append(cell.uid)

        self._group.cells.flush()
        return rcells

    def update_points(self, points):
        """ Updates the information of a point.

        Gets the mesh points identified by the same
        uids as the ones provided points and updates their information.

        Parameters
        ----------
        points : iterable of Point
            Points to be updated

        Raises
        ------
        KeyError
            If any point was not found in the mesh container.

        """

        for point in points:
            for row in self._group.points.where(
                    'uid == value', condvars={'value': point.uid.hex}):
                row['coordinates'] = list(point.coordinates)
                self._uidData[
                    uuid.UUID(hex=row['data'], version=4)
                    ] = point.data
                row.update()
                row._flush_mod_rows()
                break
            else:
                raise ValueError(err_upd.format('point', point.uid))

    def update_edges(self, edges):
        """ Updates the information of an edge.

        Gets the mesh edges identified by the same
        uids as the ones provided edges and updates their information.

        Parameters
        ----------
        edges : iterable of Edge
            Edges to be updated.

        Raises
        ------
        KeyError
            If any edge was not found in the mesh container.

        """
        for edge in edges:
            for row in self._group.edges.where(
                    'uid == value', condvars={'value': edge.uid.hex}):
                n = len(edge.points)
                row['n_points'] = n
                row['points_uids'] = [
                    puid.hex for puid in edge.points
                    ] + [0] * (MAX_POINTS_IN_EDGE-n)
                self._uidData[
                    uuid.UUID(hex=row['data'], version=4)
                    ] = edge.data
                row.update()
                row._flush_mod_rows()
                break
            else:
                raise ValueError(err_upd.format('edge', edge.uid))

    def update_faces(self, faces):
        """ Updates the information of a face.

        Gets the mesh faces identified by the same
        uids as the ones provided in faces and updates their information.

        Parameters
        ----------
        faces : iterable of Face
            Faces to be updated.

        Raises
        ------
        KeyError
            If any face was not found in the mesh container.

        """
        for face in faces:
            for row in self._group.faces.where(
                    'uid == value', condvars={'value': face.uid.hex}):
                n = len(face.points)
                row['n_points'] = n
                row['points_uids'] = [
                    puid.hex for puid in face.points
                    ] + [0] * (MAX_POINTS_IN_FACE-n)
                self._uidData[
                    uuid.UUID(hex=row['data'], version=4)
                    ] = face.data
                row.update()
                row._flush_mod_rows()
                break
            else:
                raise ValueError(err_upd.format('face', face.uid))

    def update_cells(self, cells):
        """ Updates the information of every cell in cells.

        Gets the mesh cells identified by the same
        uids as the ones provided in cells and updates their information.

        Parameters
        ----------
        cellss : iterable of Cell
            Cells to be updated.

        Raises
        ------
        KeyError
            If any cell was not found in the mesh container.

        """
        for cell in cells:
            for row in self._group.cells.where(
                    'uid == value', condvars={'value': cell.uid.hex}):
                n = len(cell.points)
                row['n_points'] = n
                row['points_uids'] = [
                    puid.hex for puid in cell.points
                    ] + [0] * (MAX_POINTS_IN_CELL-n)
                self._uidData[
                    uuid.UUID(hex=row['data'], version=4)
                    ] = cell.data
                row.update()
                row._flush_mod_rows()
                break
            else:
                raise ValueError(err_upd.format('cell', cell.uid))

    def iter_points(self, uids=None):
        """ Returns an iterator over points.

        Parameters
        ----------
        uids : iterable of uuid.UUID or None
            When the uids are provided, then the points are returned in
            the same order the uids are returned by the iterable. If uids is
            None, then all points are returned by the iterable and there
            is no restriction on the order that they are returned.

        Returns
        -------
        iter
            Iterator over the points

        """
        if uids is None:
            for row in self._group.points:
                yield Point(
                    tuple(row['coordinates']),
                    uuid.UUID(hex=row['uid'], version=4),
                    self._uidData[uuid.UUID(hex=row['data'], version=4)]
                )
        else:
            for uid in uids:
                yield self.get_point(uid)

    def iter_edges(self, uids=None):
        """ Returns an iterator over edges.

        Parameters
        ----------
        uids : iterable of uuid.UUID  or None
            When the uids are provided, then the edges are returned in the
            same order the uids are returned by the iterable. If uids is None,
            then all edges are returned by the iterable and there is no
            restriction on the order that they are returned.

        Returns
        -------
        iter
            Iterator over the selected edges

        """
        if uids is None:
            for row in self._group.edges:
                yield Edge(
                    list(uuid.UUID(hex=pb, version=4) for pb in
                         row['points_uids'][0:row['n_points']]),
                    uuid.UUID(hex=row['uid'], version=4),
                    self._uidData[uuid.UUID(hex=row['data'], version=4)]
                )
        else:
            for uid in uids:
                yield self.get_edge(uid)

    def iter_faces(self, uids=None):
        """ Returns an iterator over faces.

        Parameters
        ----------
        uids : iterable of uuid.UUID  or None
            When the uids are provided, then the faces are returned in the
            same order the uids are returned by the iterable. If uids is None,
            then all faces are returned by the iterable and there is no
            restriction on the order that they are returned.

        Returns
        -------
        iter
            Iterator over the faces

        """
        if uids is None:
            for row in self._group.faces:
                yield Face(
                    list(uuid.UUID(hex=pb, version=4) for pb in
                         row['points_uids'][0:row['n_points']]),
                    uuid.UUID(hex=row['uid'], version=4),
                    self._uidData[uuid.UUID(hex=row['data'], version=4)]
                )
        else:
            for uid in uids:
                yield self.get_face(uid)

    def iter_cells(self, uids=None):
        """ Returns an iterator over cells.

        Parameters
        ----------
        uids : iterable of uuid.UUID  or None
            When the uids are provided, then the cells are returned in the same
            order the uids are returned by the iterable. If uids is None, then
            all cells are returned by the iterable and there is no restriction
            on the order that they are returned.

        Returns
        -------
        iter
            Iterator over the selected cells

        """
        if uids is None:
            for row in self._group.cells:
                yield Cell(
                    list(uuid.UUID(hex=pb, version=4) for pb in
                         row['points_uids'][0:row['n_points']]),
                    uuid.UUID(hex=row['uid'], version=4),
                    self._uidData[uuid.UUID(hex=row['data'], version=4)]
                )
        else:
            for uid in uids:
                yield self.get_cell(uid)

    def has_edges(self):
        """ Check if the mesh container has edges

        Returns
        -------
        bool
            True of there are edges inside the mesh,
            False otherwise

        """
        return self._group.edges.nrows != 0

    def has_faces(self):
        """ Check if the mesh container has faces

        Returns
        -------
        bool
            True of there are faces inside the mesh,
            False otherwise

        """
        return self._group.faces.nrows != 0

    def has_cells(self):
        """ Check if the mesh container has cells

        Returns
        -------
        bool
            True of there are cells inside the mesh,
            False otherwise

        """
        return self._group.cells.nrows != 0

    def count_of(self, item_type):
        """ Return the count of item_type in the container.

        Parameters
        ----------
        item_type : CUDSItem
            The CUDSItem enum of the type of the items to return the count of.

        Returns
        -------
        count : int
            The number of items of item_type in the container.

        Raises
        ------
        ValueError :
            If the type of the item is not supported in the current
            container.

        """
        try:
            return len(self._items_count[item_type]())
        except KeyError:
            error_str = "Trying to obtain count a of non-supported item: {}"
            raise ValueError(error_str.format(item_type))

    def _generate_uid(self):
        """ Provides and uid for the object

        Provides an uid as defined in the standard RFC 4122
        """

        return uuid.uuid4()

    def _create_points_table(self):
        """ Generates the table to store points """

        self._file.create_table(
            self._group, "points", _PointDescriptor)

    def _create_edges_table(self):
        """ Generates the table to store edges """

        self._file.create_table(
            self._group, "edges", _EdgeDescriptor)

    def _create_faces_table(self):
        """ Generates the table to store faces """

        self._file.create_table(
            self._group, "faces", _FaceDescriptor)

    def _create_cells_table(self):
        """ Generates the table to store cells """

        self._file.create_table(
            self._group, "cells", _CellDescriptor)
def append(handle, n, value):
    root = handle.root
    if hasattr(root, 'my_data_table'):
        handle.remove_node(root, 'my_data_table', recursive=True)
    table = IndexedDataContainerTable(root, 'my_data_table', expected_number=n)
    return [table.append(value) for i in range(n)]
Esempio n. 13
0
def append(handle, n, value):
    root = handle.root
    if hasattr(root, 'my_data_table'):
        handle.remove_node(root, 'my_data_table', recursive=True)
    table = IndexedDataContainerTable(root, 'my_data_table', expected_number=n)
    return [table.append(value) for i in range(n)]
Esempio n. 14
0
class H5Lattice(ABCLattice):
    """ H5Lattice object to use H5CUDS lattices.

    """
    def __init__(self, group):
        """ Return a reference to existing lattice in a H5CUDS group.

        Parameters
        ----------
        group : HDF5 group in PyTables file
            reference to a group (folder) in PyTables file where the tables
            for lattice and data are located

        """
        if group._v_attrs.cuds_version != LATTICE_CUDS_VERSION:
            raise ValueError("Lattice file layout has an incompatible version")

        self._group = group
        attrs = group.lattice.attrs
        self._primitive_cell = PrimitiveCell(
            attrs.primitive_cell[0], attrs.primitive_cell[1],
            attrs.primitive_cell[2], BravaisLattice(attrs.bravais_lattice))

        self._size = attrs.size
        self._origin = attrs.origin

        self._table = IndexedDataContainerTable(group, 'lattice')
        self._data = IndexedDataContainerTable(group, 'data')

        self._items_count = {CUDSItem.NODE: lambda: self._table}

    @classmethod
    def create_new(cls, group, primitive_cell, size, origin, record=None):
        """ Create a new lattice in H5CUDS file.

        Parameters
        ----------
        group : HDF5 group in PyTables file
            reference to a group (folder) in PyTables file where the tables
            for lattice and data will be located
        primitive_cell : PrimitiveCell
            primitive cell specifying the 3D Bravais lattice
        size : int[3]
            number of lattice nodes (in the direction of each axis).
        origin : float[3]
            origin of lattice
        record : tables.IsDescription
            A class that describes column types for PyTables table.

        """
        group._v_attrs.cuds_version = LATTICE_CUDS_VERSION

        # If record not specified use NoUIDRecord in table initialization
        lattice = IndexedDataContainerTable(group, 'lattice',
                                            record if record is not None
                                            else NoUIDRecord, np.prod(size))
        for i in xrange(np.prod(size)):
            lattice.append(DataContainer())

        pc = primitive_cell
        lattice._table.attrs.primitive_cell = [pc.p1, pc.p2, pc.p3]
        lattice._table.attrs.bravais_lattice = pc.bravais_lattice
        lattice._table.attrs.size = size
        lattice._table.attrs.origin = origin

        IndexedDataContainerTable(group, 'data', NoUIDRecord, 1)

        return cls(group)

    def get_node(self, index):
        """ Get a copy of the node corresponding to the given index.

        Parameters
        ----------
        index : int[3]
            node index coordinate

        Returns
        -------
        node : LatticeNode

        """
        try:
            n = np.ravel_multi_index(index, self._size)
        except ValueError:
            raise IndexError('invalid index: {}'.format(index))
        return LatticeNode(index, self._table[n])

    def update_nodes(self, nodes):
        """ Updates H5Lattice data for a LatticeNode

        Parameters
        ----------
        nodes : iterable of LatticeNode objects
            reference to LatticeNode objects

        """
        # Find correct row for node
        for node in nodes:
            index = node.index
            try:
                n = np.ravel_multi_index(index, self._size)
            except ValueError:
                raise IndexError('invalid index: {}'.format(index))
            self._table[n] = node.data

    def iter_nodes(self, indices=None):
        """ Get an iterator over the LatticeNodes described by the ids.

        Parameters
        ----------
        indices : iterable set of int[3], optional
            node index coordinates

        Returns
        -------
        A generator for LatticeNode objects

        """
        if indices is None:
            for row_number, data in enumerate(self._table):
                index = np.unravel_index(row_number, self._size)
                yield LatticeNode(index, data)
        else:
            for index in indices:
                yield self.get_node(index)

    def count_of(self, item_type):
        """ Return the count of item_type in the container.

        Parameters
        ----------
        item_type : CUDSItem
            The CUDSItem enum of the type of the items to return the count of.

        Returns
        -------
        count : int
            The number of items of item_type in the container.

        Raises
        ------
        ValueError :
            If the type of the item is not supported in the current
            container.

        """
        try:
            return len(self._items_count[item_type]())
        except KeyError:
            error_str = "Trying to obtain count a of non-supported item: {}"
            raise ValueError(error_str.format(item_type))

    @property
    def size(self):
        return self._size

    @property
    def origin(self):
        return self._origin

    @property
    def name(self):
        return self._group._v_name

    @name.setter
    def name(self, value):
        self._group._f_rename(value)

    @property
    def data(self):
        if len(self._data) == 1:
            return self._data[0]
        else:
            return DataContainer()

    @data.setter
    def data(self, value):
        if len(self._data) == 0:
            self._data.append(value)
        else:
            self._data[0] = value