def test_multi_poly_lookup():
    # A simple quad grid
    nodes = np.array(
        [
            [0.0, 0.0],  # 0
            [0.0, 2.0],  # 1
            [2.0, 0.0],  # 2
            [2.0, 2.0],  # 3
            [4.0, 0.0],  # 4
            [4.0, 2.0],  # 5
            [6.0, 0.0],  # 6
            [6.0, 2.0],  # 7
            [0.0, 4.0],  # 8
            [2.0, 4.0],  # 9
            [4.0, 4.0],  # 10
            [6.0, 4.0],  # 11
        ]
    )

    faces = np.array([[0, 8, 9, 5, 2], [9, 11, 7, 5, -1], [4, 7, 6, -1, -1]], dtype=np.intc)
    tree = CellTree(nodes, faces, num_buckets=2, cells_per_leaf=1)
    point = np.array([1.0, 1.0])  # in POLY 1
    result = tree.locate(point)
    assert result == 0
    point[0] = 5.0  # tri 2
    result = tree.locate(point)
    assert result == 2

    point[1] = 3.0
    result = tree.locate(point)
    assert result == 1

    point[0] = -1.0  # out of grid
    result = tree.locate(point)
    assert result == -1
Example #2
0
def test_poly_lookup():
    # A simple quad grid
    nodes = np.array([[0.0,0.0],
                      [0.0,2.0],
                      [2.0,0.0],
                      [2.0,2.0],
                      [4.0,0.0],
                      [4.0,2.0],
                      [6.0,0.0],
                      [6.0,2.0]
                      ])

    faces = np.array([[0, 2, 3, 1],
                      [4, 6, 7, 5],
                     ], dtype = np.intc)
    print(faces)
    print(faces.dtype)
    tree = CellTree(nodes, faces, 2, 1)
    point = np.array([1.,1.]) #in triangle 1
    result = tree.find_poly(point)
    assert result == 0
    point[0] = 5.0 # tri 2
    result = tree.find_poly(point)
    assert result == 1
    point[0] = -1.0 # out of grid
    result = tree.find_poly(point)
    assert result == -1
def test_edge_cases():
    nodes = np.array([[0.0, 0.0], [2.0, 0.0], [2.0, 2.0], [0.0, 2.0],
                      [1.0, 1.0]])

    faces1 = np.array([[0, 1, 3], [1, 2, 3]], dtype=np.intc)
    faces2 = np.array([[0, 1, 3], [1, 2, 4], [2, 4, 3]], dtype=np.intc)
    tree1 = CellTree(nodes, faces1)
    tree2 = CellTree(nodes, faces2)
def test_triangle_lookup():
    tree = CellTree(nodes, faces)
    point = np.array([1., 1.])  # in triangle 1
    result = tree.locate(point)
    assert result == 0
    point[0] = 2.0  # tri 2
    result = tree.locate(point)
    assert result == 1
    point[0] = -1.0  # out of grid
    result = tree.locate(point)
    assert result == -1
def test_triangle_lookup():
    tree = CellTree(nodes, faces)
    point = np.array([1.0, 1.0])  # in triangle 1
    result = tree.locate(point)
    assert result == 0
    point[0] = 2.0  # tri 2
    result = tree.locate(point)
    assert result == 1
    point[0] = -1.0  # out of grid
    result = tree.locate(point)
    assert result == -1
Example #6
0
def test_triangle_lookup():
    tree = CellTree(nodes, faces, 2, 1)
    point = np.array([1.,1.]) #in triangle 1
    result = tree.find_poly(point)
    assert result == 0
    point[0] = 2.0 # tri 2
    result = tree.find_poly(point)
    assert result == 1
    point[0] = -1.0 # out of grid
    result = tree.find_poly(point)
    assert result == -1
Example #7
0
def test_multipoint():
    tree = CellTree(nodes21, faces21)
    points = [ (4.2,  3.0),
               (7.7, 13.5),
               (3.4, 7.000000001),
               (7.0,  5.0), # out of bounds points
               (8.66, 10.99),
               (7.3, 0.74),
               (2.5, 5.5),
               (9.8, 12.3),
               ]
    correct_indexes = (1, 20, 7, -1, -1, -1, -1, -1)

    ind = tree.multi_locate(points)
    assert np.array_equal(ind, correct_indexes)
def test_shape_error():
    nodes = [(1, 2, 3), (3, 4, 5), (4, 5, 6)]
    faces = [
        [0, 1, 2],
        [1, 3, 2],
    ]

    with pytest.raises(ValueError):
        # nodes is wrong shape
        tree = CellTree(nodes, faces)

        tree = CellTree(nodes2, (2, 3, 4, 5))

        tree = CellTree(nodes2,
                        ((2, 3, 4, 5), (1, 2, 3, 4, 5), (1, 2, 3, 4, 5)))
def test_poly_lookup():
    # A simple quad grid
    nodes = np.array([
        [0.0, 0.0],  #0
        [0.0, 2.0],  #1
        [2.0, 0.0],  #2
        [2.0, 2.0],  #3
        [4.0, 0.0],  #4
        [4.0, 2.0],  #5
        [6.0, 0.0],  #6
        [6.0, 2.0],  #7
        [0.0, 4.0],  #8
        [2.0, 4.0],  #9
        [4.0, 4.0],  #10
        [6.0, 4.0]  #11
    ])

    #quads
    faces1 = np.array([
        [0, 2, 3, 1],
        [4, 6, 7, 5],
    ], dtype=np.intc)
    #Pentas
    faces2 = np.array([
        [0, 8, 9, 5, 2],
        [9, 11, 6, 2, 5],
    ], dtype=np.intc)
    tree1 = CellTree(nodes, faces1, num_buckets=2, cells_per_leaf=1)
    point = np.array([1., 1.])  # in triangle 1
    result = tree1.locate(point)
    assert result == 0
    point[0] = 5.0  # tri 2
    result = tree1.locate(point)
    assert result == 1
    point[0] = -1.0  # out of grid
    result = tree1.locate(point)
    assert result == -1

    tree2 = CellTree(nodes, faces2, num_buckets=2, cells_per_leaf=1)
    point = np.array([1., 2.])  # in triangle 1
    result = tree2.locate(point)
    assert result == 0
    point[0] = 5.0  # tri 2
    result = tree2.locate(point)
    assert result == 1
    point[0] = -1.0  # out of grid
    result = tree2.locate(point)
    assert result == -1
def test_build_tree_from_coords():
    """
    this tests using a structured grid with cell coordinates

    converting it to a flattened grid with nodes and cells
    defined as indexes to those nodes

    as much as anything else, this surves as example code for how to do that.
    """

    x, y = curv_grid(n_x=3,
                     n_y=3,
                     center=(0.0, 0.0),
                     min_radius=9.0,
                     max_radius=18.0,
                     angle=np.pi / 4.0
                     )

    nodes, faces = nodes_from_coords(x, y)
    # these range from (30.,  20.) to (31.1,  21.1)

    tree = CellTree(nodes, faces)

    # try to find some points

    # points outside the domain:
    result = tree.locate([(0.0, 0.0),
                          (19.0, 5.0),
                          (17.0, -1.0),
                          (9.0, 10.0),
                          ],
                         )
    assert np.all(result == -1)

    # points inside the domain
    result = tree.locate([(10.0, 1.0),
                          (9.0, 3.0),
                          (8.0, 6.0),
                          (13.0, 1.0),
                          (12.0, 4.0),
                          (11.0, 7.0),
                          (16.0, 1.0),
                          (15.0, 8.0),
                          (13.0, 11.0),
                          ]
                         )

    assert np.array_equal(result, [0, 1, 2, 3, 4, 5, 6, 7, 8])
def test_multipoint():
    tree = CellTree(nodes21, faces21)
    points = [
        (4.2, 3.0),
        (7.7, 13.5),
        (3.4, 7.000000001),
        (7.0, 5.0),  # out of bounds points
        (8.66, 10.99),
        (7.3, 0.74),
        (2.5, 5.5),
        (9.8, 12.3),
    ]
    correct_indexes = (1, 20, 7, -1, -1, -1, -1, -1)

    ind = tree.locate(points)
    assert np.array_equal(ind, correct_indexes)
def test_types():
    """
    It should auto-cast the types to the right types for you
    """
    nodes = np.array(nodes2, dtype=np.float32)
    faces = np.array(faces2, dtype=np.int64)

    tree = CellTree(nodes, faces)
    assert True
def test_init():
    """
    can  a tree be initialized
    """

    # with defaults
    tree = CellTree(nodes, faces)

    # with everything specified
    tree = CellTree(nodes, faces, num_buckets=2, cells_per_leaf=1)

    # with num_buckets
    tree = CellTree(nodes, faces, num_buckets=4)

    # with cells_per_leaf
    tree = CellTree(nodes, faces, cells_per_leaf=2)

    assert True
Example #14
0
 def build_celltree(self):
     """
     Tries to build the celltree for the current UGrid. Will fail if nodes
     or faces is not defined.
     """
     from cell_tree2d import CellTree
     if self.nodes is None or self.faces is None:
         raise ValueError(
             "Nodes and faces must be defined in order to create and use CellTree")
     self._tree = CellTree(self.nodes, self.faces)
Example #15
0
 def build_celltree(self):
     """
     Tries to build the celltree for the current UGrid. Will fail if nodes
     or faces is not defined.
     """
     try:
         from cell_tree2d import CellTree
     except ImportError:
         raise ImportError("the cell_tree2d package must be installed to "
                           "use the celltree search:\n"
                           "https://github.com/NOAA-ORR-ERD/cell_tree2d/")
     self._tree = CellTree(self.nodes, self.faces)
def test_multi_poly_lookup():
    # A simple quad grid
    nodes = np.array([
        [0.0, 0.0],  #0
        [0.0, 2.0],  #1
        [2.0, 0.0],  #2
        [2.0, 2.0],  #3
        [4.0, 0.0],  #4
        [4.0, 2.0],  #5
        [6.0, 0.0],  #6
        [6.0, 2.0],  #7
        [0.0, 4.0],  #8
        [2.0, 4.0],  #9
        [4.0, 4.0],  #10
        [6.0, 4.0]  #11
    ])

    faces = np.array([[0, 8, 9, 5, 2], [9, 11, 7, 5, -1], [4, 7, 6, -1, -1]],
                     dtype=np.intc)
    tree = CellTree(nodes, faces, num_buckets=2, cells_per_leaf=1)
    point = np.array([1., 1.])  # in POLY 1
    result = tree.locate(point)
    assert result == 0
    point[0] = 5.0  # tri 2
    result = tree.locate(point)
    assert result == 2

    point[1] = 3.0
    result = tree.locate(point)
    assert result == 1

    point[0] = -1.0  # out of grid
    result = tree.locate(point)
    assert result == -1
Example #17
0
    def build_celltree(self, grid='node'):
        """
        Tries to build the celltree for grid defined by the node coordinates of the specified grid.

        :param grid: which grid to biuld the celltree for. options are:
                     'node', 'edge1', 'edge2', 'center'
        """

        if not hasattr(self, '_ind_memo_dict'):
            self._ind_memo_dict = {
                'node': None,
                'edge1': None,
                'edge2': None,
                'center': None
            }
        if not hasattr(self, '_cell_trees'):
            self._cell_trees = {
                'node': None,
                'edge1': None,
                'edge2': None,
                'center': None
            }
        try:
            from cell_tree2d import CellTree
        except ImportError:
            raise ImportError(
                "the cell_tree2d package must be installed to use the "
                "celltree search:\n"
                "https://github.com/NOAA-ORR-ERD/cell_tree2d/")

        lon, lat = self._get_grid_vars(grid)
        if lon is None or lat is None:
            raise ValueError(
                "{0}_lon and {0}_lat must be defined in order to create and "
                "use CellTree for this grid".format(grid))
        lin_nodes = np.ascontiguousarray(
            np.column_stack(
                (lon[:].reshape(-1), lat[:].reshape(-1)))).astype(np.float64)
        y_size = lon.shape[0]
        x_size = lon.shape[1]
        lin_faces = np.array([
            np.array([[x, x + 1, x + x_size + 1, x + x_size]
                      for x in range(0, x_size - 1, 1)]) + y * x_size
            for y in range(0, y_size - 1)
        ])
        lin_faces = np.ascontiguousarray(
            lin_faces.reshape(-1, 4).astype(np.int32))
        self._cell_trees[grid] = (CellTree(lin_nodes,
                                           lin_faces), lin_nodes, lin_faces)
def test_poly_lookup():
    # A simple quad grid
    nodes = np.array(
        [
            [0.0, 0.0],  # 0
            [0.0, 2.0],  # 1
            [2.0, 0.0],  # 2
            [2.0, 2.0],  # 3
            [4.0, 0.0],  # 4
            [4.0, 2.0],  # 5
            [6.0, 0.0],  # 6
            [6.0, 2.0],  # 7
            [0.0, 4.0],  # 8
            [2.0, 4.0],  # 9
            [4.0, 4.0],  # 10
            [6.0, 4.0],  # 11
        ]
    )

    # quads
    faces1 = np.array([[0, 2, 3, 1], [4, 6, 7, 5]], dtype=np.intc)
    # Pentas
    faces2 = np.array([[0, 8, 9, 5, 2], [9, 11, 6, 2, 5]], dtype=np.intc)
    tree1 = CellTree(nodes, faces1, num_buckets=2, cells_per_leaf=1)
    point = np.array([1.0, 1.0])  # in triangle 1
    result = tree1.locate(point)
    assert result == 0
    point[0] = 5.0  # tri 2
    result = tree1.locate(point)
    assert result == 1
    point[0] = -1.0  # out of grid
    result = tree1.locate(point)
    assert result == -1

    tree2 = CellTree(nodes, faces2, num_buckets=2, cells_per_leaf=1)
    point = np.array([1.0, 2.0])  # in triangle 1
    result = tree2.locate(point)
    assert result == 0
    point[0] = 5.0  # tri 2
    result = tree2.locate(point)
    assert result == 1
    point[0] = -1.0  # out of grid
    result = tree2.locate(point)
    assert result == -1
Example #19
0
    def build_celltree(self, grid='node', use_mask=True):
        """
        Tries to build the celltree for grid defined by the node coordinates of the specified grid.

        :param grid: which grid to biuld the celltree for. options are:
                     'node', 'edge1', 'edge2', 'center'
        """

        if not hasattr(self, '_ind_memo_dict'):
            self._ind_memo_dict = {'node': None,
                                   'edge1': None,
                                   'edge2': None,
                                   'center': None}
        if not hasattr(self, '_cell_trees'):
            self._cell_trees = {'node': None,
                                'edge1': None,
                                'edge2': None,
                                'center': None}
        if not hasattr(self, '_masks'):
            self._masks = {'node':None,
                           'center':None,
                           'edge1':None,
                           'edge2':None}
        try:
            from cell_tree2d import CellTree
        except ImportError:
            raise ImportError("the cell_tree2d package must be installed to use the "
                              "celltree search:\n"
                              "https://github.com/NOAA-ORR-ERD/cell_tree2d/")

        lon, lat = self._get_grid_vars(grid)
        geo_mask = self._get_geo_mask(grid)
        if lon is None or lat is None:
            raise ValueError("{0}_lon and {0}_lat must be defined in order to create and "
                             "use CellTree for this grid".format(grid))

        if geo_mask is not None and use_mask:
            # Geometry has an external mask that needs to be applied.
            lon = lon[:].copy()
            lat = lat[:].copy()
            mask = gen_mask(geo_mask, add_boundary=self.use_masked_boundary)
            lon.mask = mask
            lat.mask = mask
            masked_faces_idxs = np.zeros_like(mask, dtype=np.int32)
            masked_faces_idxs[mask] = -1
            tmp = np.where(~mask.ravel())[0]
            masked_faces_idxs[~mask] = np.arange(0,len(tmp))
            lin_faces = np.full(shape=(lon[0:-1,0:-1].size,4), fill_value=-1, dtype=np.int32)
            lin_faces[:,0] = np.ravel(masked_faces_idxs[0:-1, 0:-1])
            lin_faces[:,1] = np.ravel(masked_faces_idxs[0:-1, 1:])
            lin_faces[:,2] = np.ravel(masked_faces_idxs[1:, 1:])
            lin_faces[:,3] = np.ravel(masked_faces_idxs[1:, 0:-1])
            faces_mask = np.any(lin_faces == -1, axis=1)
            lin_faces[faces_mask] = [-1,-1,-1,-1]
            lin_faces = np.ma.masked_less(lin_faces, 0).compressed().reshape(-1,4)
            #need to make a reversal_array. This is an array of the same length
            #as the unmasked nodes that contains the 'true' index of the
            #unmasked node. When CellTree gives back an index, it's 'true'
            #index is discovered using this array
            reversal_array = np.where(~faces_mask)[0].astype(np.int32)
            #append a -1 to preserve -1 entries when back-translating the indices
            reversal_array = np.concatenate((reversal_array, np.array([-1,])))
            self._masks[grid] = (mask, reversal_array)
        else:
            self._masks[grid] = None
            y_size = lon.shape[0]
            x_size = lon.shape[1]
            lin_faces = np.array([np.array([[x, x + 1, x + x_size + 1, x + x_size]
                                            for x in range(0, x_size - 1, 1)]) + y * x_size
                                            for y in range    (0, y_size - 1)])
        lin_faces = np.ascontiguousarray(lin_faces.reshape(-1, 4).astype(np.int32))

        if isinstance(lon, np.ma.MaskedArray) and lon.mask is not False and use_mask:
            lin_nodes = np.ascontiguousarray(np.column_stack((np.ma.compressed(lon[:]),
                                                              np.ma.compressed(lat[:]))).reshape(-1, 2).astype(np.float64))
        else:
            lin_nodes = np.ascontiguousarray(np.stack((lon, lat), axis=-1).reshape(-1, 2).astype(np.float64))

        self._cell_trees[grid] = (CellTree(lin_nodes, lin_faces), lin_nodes, lin_faces)
def test_lists():
    """
    python lists should get converted to numpy arrays
    """
    tree = CellTree(nodes2, faces2)
    assert True
def test_bounds_errors():
    with pytest.raises(ValueError):
        tree = CellTree(nodes, faces, cells_per_leaf=-1)

    with pytest.raises(ValueError):
        tree = CellTree(nodes, faces, num_buckets=0)