Esempio n. 1
0
    def test_create_or_get_group(self):
        ocmpi = OcgDist()
        _ = ocmpi._create_or_get_group_(['moon', 'base'])
        _ = ocmpi._create_or_get_group_(None)
        _ = ocmpi._create_or_get_group_('flower')
        ocmpi.create_dimension('foo', group=['moon', 'base'])
        ocmpi.create_dimension('end_of_days')
        ocmpi.create_dimension('start_of_days')

        actual = ocmpi.get_dimension('foo', ['moon', 'base'])
        desired = Dimension('foo')
        self.assertEqual(actual, desired)

        desired = {0: {None: {'variables': {},
                              'dimensions': {'end_of_days': Dimension(name='end_of_days', size=None, size_current=None),
                                             'start_of_days': Dimension(name='start_of_days', size=None,
                                                                        size_current=None)},
                              'groups': {'flower': {'variables': {}, 'dimensions': {}, 'groups': {}},
                                         'moon': {'variables': {}, 'dimensions': {},
                                                  'groups': {'base': {'variables': {},
                                                                      'dimensions': {
                                                                          'foo': Dimension(
                                                                              name='foo',
                                                                              size=None,
                                                                              size_current=None)},
                                                                      'groups': {}}}}}}}}

        self.assertDictEqual(ocmpi.mapping, desired)
Esempio n. 2
0
    def test_init_source_name(self):
        dim = Dimension('foo', source_name='actual_foo')
        self.assertEqual(dim.source_name, 'actual_foo')

        dim = Dimension('foo')
        dim.set_name('new_foo')
        self.assertEqual(dim.source_name, 'foo')
Esempio n. 3
0
    def test_get_unioned_spatial_average_differing_dimensions(self):
        pa = self.get_geometryvariable()

        to_weight = Variable(name='to_weight',
                             dimensions=pa.dimensions,
                             dtype=float)
        to_weight.get_value()[0] = 5.0
        to_weight.get_value()[1] = 10.0
        pa.parent.add_variable(to_weight)

        to_weight2 = Variable(name='to_weight2',
                              dimensions=[
                                  Dimension('time', 10),
                                  Dimension('level', 3), pa.dimensions[0]
                              ],
                              dtype=float)
        for time_idx in range(to_weight2.shape[0]):
            for level_idx in range(to_weight2.shape[1]):
                to_weight2.get_value()[time_idx, level_idx] = (
                    time_idx + 2) + (level_idx + 2)**(level_idx + 1)
        pa.parent.add_variable(to_weight2)

        unioned = pa.get_unioned(spatial_average=['to_weight', 'to_weight2'])

        actual = unioned.parent[to_weight2.name]
        self.assertEqual(actual.shape, (10, 3, 1))
        self.assertEqual(to_weight2.shape, (10, 3, 2))
        self.assertNumpyAll(actual.get_value(),
                            to_weight2.get_value()[:, :, 0].reshape(10, 3, 1))
        self.assertEqual(actual.dimension_names,
                         ('time', 'level', 'ocgis_geom_union'))

        self.assertEqual(unioned.parent[to_weight.name].get_value()[0], 7.5)
Esempio n. 4
0
    def test_len(self):
        dim = Dimension('foo')
        self.assertEqual(len(dim), 0)

        # Test size current is used for length.
        dim = Dimension('unlimited', size=None, size_current=4)
        self.assertEqual(len(dim), 4)
Esempio n. 5
0
    def test_init(self):
        ompi = OcgDist(size=2)
        self.assertEqual(len(ompi.mapping), 2)

        dim_x = Dimension('x', 5, dist=False)
        dim_y = Dimension('y', 11, dist=True)
        var_tas = Variable('tas', value=np.arange(0, 5 * 11).reshape(5, 11), dimensions=(dim_x, dim_y))
        thing = Variable('thing', value=np.arange(11) * 10, dimensions=(dim_y,))

        vc = VariableCollection(variables=[var_tas, thing])
        child = VariableCollection(name='younger')
        vc.add_child(child)
        childer = VariableCollection(name='youngest')
        child.add_child(childer)
        dim_six = Dimension('six', 6)
        hidden = Variable('hidden', value=[6, 7, 8, 9, 0, 10], dimensions=dim_six)
        childer.add_variable(hidden)

        ompi.add_dimensions([dim_x, dim_y])
        ompi.add_dimension(dim_six, group=hidden.group)
        ompi.add_variables([var_tas, thing])
        ompi.add_variable(hidden)

        var = ompi.get_variable(hidden)
        self.assertIsInstance(var, dict)
Esempio n. 6
0
    def fixture_regular_ugrid_file(self, ufile, resolution, crs=None):
        """
        Create a UGRID convention file from a structured, rectilinear grid. This will create element centers in addition
        to element node connectivity.

        :param str ufile: Path to the output UGRID NetCDF file.
        :param float resolution: The resolution fo the structured grid to convert to UGRID.
        :param crs: The coordinate system for the UGRID data.
        :type crs: :class:`~ocgis.CRS`
        """

        src_grid = self.get_gridxy_global(resolution=resolution, crs=crs)
        polygc = src_grid.get_abstraction_geometry()
        polygc.reshape([Dimension(name='element_count', size=polygc.size)])
        polygc = polygc.convert_to(max_element_coords=4)

        pointgc = src_grid.get_point()
        pointgc.reshape([Dimension(name='element_count', size=pointgc.size)])
        pointgc = pointgc.convert_to(xname='face_center_x', yname='face_center_y')

        polygc.parent.add_variable(pointgc.parent.first(), force=True)
        polygc.parent.dimension_map.update(pointgc.dimension_map)
        pointgc.parent = polygc.parent

        gu = GridUnstruct(geoms=[polygc, pointgc])
        gu.parent.write(ufile)
Esempio n. 7
0
 def test_convert_to_empty(self):
     dim = Dimension('three', 3, src_idx=np.array([10, 11, 12]), dist=True)
     dim.convert_to_empty()
     self.assertFalse(dim.is_unlimited)
     self.assertTrue(dim.is_empty)
     self.assertEqual(len(dim), 0)
     self.assertEqual(dim.size, 0)
     self.assertEqual(dim.size_current, 0)
Esempio n. 8
0
 def test_convert_to_empty(self):
     dim = Dimension('three', 3, src_idx=np.array([10, 11, 12]), dist=True)
     dim.convert_to_empty()
     self.assertFalse(dim.is_unlimited)
     self.assertTrue(dim.is_empty)
     self.assertEqual(len(dim), 0)
     self.assertEqual(dim.size, 0)
     self.assertEqual(dim.size_current, 0)
Esempio n. 9
0
    def test(self):
        ompi = OcgDist()
        src_idx = np.array([2, 3, 4, 5, 6])
        dim = ompi.create_dimension('foo', size=5, group='subroot', dist=True, src_idx=src_idx)
        self.assertEqual(dim, ompi.get_dimension(dim.name, group='subroot'))
        self.assertEqual(dim.bounds_local, (0, len(dim)))
        self.assertFalse(dim.is_empty)
        ompi.update_dimension_bounds()
        with self.assertRaises(ValueError):
            ompi.update_dimension_bounds()

        if ompi.size == 2:
            if MPI_RANK == 0:
                self.assertEqual(dim.bounds_local, (0, 3))
                self.assertEqual(dim._src_idx.tolist(), [2, 3, 4])
            elif MPI_RANK == 1:
                self.assertEqual(dim.bounds_local, (3, 5))
                self.assertEqual(dim._src_idx.tolist(), [5, 6])
        elif ompi.size == 8:
            if MPI_RANK <= 1:
                self.assertTrue(len(dim) >= 2)
            else:
                self.assertTrue(dim.is_empty)

        # Test with multiple dimensions.
        d1 = Dimension('d1', size=5, dist=True, src_idx=np.arange(5, dtype=np.int32))
        d2 = Dimension('d2', size=10, dist=False)
        d3 = Dimension('d3', size=3, dist=True)
        dimensions = [d1, d2, d3]
        ompi = OcgDist()
        for dim in dimensions:
            ompi.add_dimension(dim)
        ompi.update_dimension_bounds()
        bounds_local = ompi.get_bounds_local()
        if ompi.size <= 2:
            desired = {(1, 0): ((0, 5), (0, 10), (0, 3)),
                       (2, 0): ((0, 3), (0, 10), (0, 3)),
                       (2, 1): ((3, 5), (0, 10), (0, 3))}
            self.assertAsSetEqual(bounds_local, desired[(ompi.size, MPI_RANK)])
        else:
            if MPI_RANK <= 1:
                self.assertTrue(dimensions[0]._src_idx.shape[0] <= 3)
            for dim in dimensions:
                if MPI_RANK >= 2:
                    if dim.name == 'd1':
                        self.assertTrue(dim.is_empty)
                    else:
                        self.assertFalse(dim.is_empty)
                else:
                    self.assertFalse(dim.is_empty)

        # Test adding an existing dimension.
        ompi = OcgDist()
        ompi.create_dimension('one')
        with self.assertRaises(ValueError):
            ompi.create_dimension('one')
Esempio n. 10
0
 def test_renamed_dimensions(self):
     d = [Dimension('a', 5), Dimension('b', 6)]
     desired_after = deepcopy(d)
     name_mapping = {'time': ['b']}
     desired = [Dimension('a', 5), Dimension('time', 6)]
     with renamed_dimensions(d, name_mapping):
         for idx in range(len(d)):
             self.assertEqual(d[idx], desired[idx])
         self.assertEqual(d, desired)
     self.assertEqual(desired_after, d)
Esempio n. 11
0
    def test_write_variable_collection(self):
        # Attempt to write without a geometry variable.
        v = Variable('a', value=[1, 2], dimensions='bb')
        field = Field(variables=v)
        path = self.get_temporary_file_path('out.shp')
        with self.assertRaises(ValueError):
            field.write(path, driver=DriverVector)

        # Test writing a field with two-dimensional geometry storage.
        value = [Point(1, 2), Point(3, 4), Point(5, 6), Point(6, 7), Point(8, 9), Point(10, 11)]
        gvar = GeometryVariable(value=value, name='points', dimensions='ngeoms')
        gvar.reshape([Dimension('lat', 2), Dimension('lon', 3)])
        var1 = Variable(name='dummy', value=[6, 7, 8], dimensions=['a'])
        var2 = Variable(name='some_lats', value=[41, 41], dimensions=['lat'])
        var3 = Variable(name='some_lons', value=[0, 90, 280], dimensions=['lon'])
        var4 = Variable(name='data', value=np.random.rand(4, 3, 2), dimensions=['time', 'lon', 'lat'])
        field = Field(variables=[var1, var2, var3, var4], geom=gvar, is_data=['data'])
        path = self.get_temporary_file_path('2d.shp')
        field.write(path, iter_kwargs={'followers': ['some_lats', 'some_lons']}, driver=DriverVector)
        read = RequestDataset(uri=path).get()
        self.assertTrue(len(read) > 2)
        self.assertEqual(list(read.keys()),
                         ['data', 'some_lats', 'some_lons', constants.DimensionName.GEOMETRY_DIMENSION])

        # Test writing a subset of the variables.
        path = self.get_temporary_file_path('limited.shp')
        value = [Point(1, 2), Point(3, 4), Point(5, 6)]
        gvar = GeometryVariable(value=value, name='points', dimensions='points')
        var1 = Variable('keep', value=[1, 2, 3], dimensions='points')
        var2 = Variable('remove', value=[4, 5, 6], dimensions='points')
        field = Field(variables=[var1, var2], geom=gvar, is_data=[var1])
        field.write(path, variable_names=['keep'], driver=DriverVector)
        read = RequestDataset(uri=path).get()
        self.assertNotIn('remove', read)

        # Test using append.
        path = self.get_temporary_file_path('limited.shp')
        value = [Point(1, 2), Point(3, 4), Point(5, 6)]
        gvar = GeometryVariable(value=value, name='points', dimensions='points')
        var1 = Variable('keep', value=[1, 2, 3], dimensions='points')
        var2 = Variable('remove', value=[4, 5, 6], dimensions='points')
        field = Field(variables=[var1, var2], geom=gvar, is_data=[var1, var2])
        for idx in range(3):
            sub = field[{'points': idx}]
            if idx == 0:
                write_mode = MPIWriteMode.WRITE
            else:
                write_mode = MPIWriteMode.APPEND
            sub.write(path, write_mode=write_mode, driver=DriverVector)
            self.assertOGRFileLength(path, idx + 1)
Esempio n. 12
0
    def test_getitem(self):
        dim = Dimension('foo', size=50)
        sub = dim[30:40]
        self.assertEqual(len(sub), 10)

        dim = Dimension('foo', size=None)
        with self.assertRaises(IndexError):
            dim[400:500]

        dim = self.get_dimension(src_idx=np.arange(10))

        sub = dim[4]
        self.assertEqual(sub.size, 1)

        sub = dim[4:5]
        self.assertEqual(sub.size, 1)

        sub = dim[4:6]
        self.assertEqual(sub.size, 2)

        sub = dim[[4, 5, 6]]
        self.assertEqual(sub.size, 3)

        sub = dim[[2, 4, 6]]
        self.assertEqual(sub.size, 3)
        self.assertNumpyAll(sub._src_idx, dim._src_idx[[2, 4, 6]])

        sub = dim[:]
        self.assertEqual(len(sub), len(dim))

        dim = self.get_dimension()
        sub = dim[2:]
        self.assertEqual(len(sub), 8)

        dim = self.get_dimension(src_idx=np.arange(10))
        sub = dim[3:-1]
        np.testing.assert_equal(sub._src_idx, [3, 4, 5, 6, 7, 8])

        dim = self.get_dimension(src_idx=np.arange(10))
        sub = dim[-3:]
        self.assertEqual(sub._src_idx.shape[0], sub.size)

        dim = self.get_dimension(src_idx=np.arange(10))
        sub = dim[-7:-3]
        self.assertEqual(sub._src_idx.shape[0], sub.size)

        dim = self.get_dimension(src_idx=np.arange(10))
        sub = dim[:-3]
        self.assertEqual(sub._src_idx.shape[0], sub.size)
Esempio n. 13
0
    def test_grid(self):
        # Test mask variable information is propagated through property.
        grid = self.get_gridxy(with_xy_bounds=True)
        self.assertTrue(grid.is_vectorized)
        self.assertTrue(grid.has_bounds)
        np.random.seed(1)
        value = np.random.rand(*grid.shape)
        select = value > 0.4
        mask_var = create_spatial_mask_variable('nonstandard', select, grid.dimensions)
        grid.set_mask(mask_var)
        field = Field(grid=grid)
        self.assertTrue(field.grid.has_bounds)
        self.assertEqual(field.dimension_map.get_spatial_mask(), mask_var.name)
        self.assertNumpyAll(field.grid.get_mask(), mask_var.get_mask())

        # Test dimension map bounds are updated appropriately.
        dim = Dimension('count', 2)
        x = Variable(name='x', value=[1., 2.], dimensions=dim)
        y = Variable(name='y', value=[1., 2.], dimensions=dim)
        xb = Variable(name='xb', value=[[0., 1.5], [1.5, 2.5]], dimensions=[dim, 'bounds'])
        yb = Variable(name='yb', value=[[0., 1.5], [1.5, 2.5]], dimensions=[dim, 'bounds'])
        variables = [x, y, xb, yb]
        dmap = DimensionMap()
        dmap.set_variable(DMK.X, x, bounds=xb)
        dmap.set_variable(DMK.Y, y, bounds=yb)
        f = Field(dimension_map=dmap, variables=variables)
        self.assertTrue(f.grid.has_bounds)
Esempio n. 14
0
 def _get_field_write_target_(cls, field):
     dmap = field.dimension_map
     driver = dmap.get_driver()
     if driver == DriverKey.NETCDF_UGRID:
         ret = cls._convert_from_ugrid_(field)
     elif driver == DriverKey.NETCDF_ESMF_UNSTRUCT:
         ret = field.copy()
         # Coordinate variables were "sectioned" when loaded in. They need to be put back together before writing to
         # disk. Only do this if they have been sectioned which only occurs when the coordinate variable is retrieved
         # from the field.
         for toponame, topo in dmap.iter_topologies():
             yname = topo.get_variable(DMK.Y)
             xname = topo.get_variable(DMK.X)
             if xname != yname:
                 yvar = topo.get_variable(DMK.Y, parent=field)
                 new_coords = np.hstack(
                     (topo.get_variable(DMK.X,
                                        parent=field).v().reshape(-1, 1),
                      yvar.v().reshape(-1, 1)))
                 assert new_coords.shape[1] == 2
                 new_dimensions = (field[yname].dimensions[0],
                                   Dimension(name='coordDim', size=2))
                 new_name = yname[0:-2]
                 ret.add_variable(
                     Variable(name=new_name,
                              dimensions=new_dimensions,
                              value=new_coords,
                              attrs=yvar.attrs))
                 ret.remove_variable(yname)
                 ret.remove_variable(xname)
     return ret
Esempio n. 15
0
    def test_variable_scatter(self):
        var_value = np.arange(5, dtype=float) + 50
        var_mask = np.array([True, True, False, True, False])

        dest_dist = OcgDist()
        five = dest_dist.create_dimension('five', 5, src_idx=np.arange(5), dist=True)
        bounds = dest_dist.create_dimension('bounds', 2)
        dest_dist.update_dimension_bounds()

        if MPI_RANK == 0:
            local_dim = Dimension('local', 5, src_idx=np.arange(5))
            dim_src_idx = local_dim._src_idx.copy()

            var = Variable('the_five', value=var_value, mask=var_mask, dimensions=five.name)
            var.set_extrapolated_bounds('the_five_bounds', 'bounds')
            var_bounds_value = var.bounds.get_value()
        else:
            var, var_bounds_value, dim_src_idx = [None] * 3

        svar = variable_scatter(var, dest_dist)

        var_bounds_value = MPI_COMM.bcast(var_bounds_value)
        dim_src_idx = MPI_COMM.bcast(dim_src_idx)

        if MPI_RANK > 1:
            self.assertIsNone(svar.get_value())
            self.assertTrue(svar.is_empty)
        else:
            dest_dim = dest_dist.get_dimension('five')
            self.assertNumpyAll(var_value[slice(*dest_dim.bounds_local)], svar.get_value())
            self.assertNumpyAll(var_mask[slice(*dest_dim.bounds_local)], svar.get_mask())
            self.assertNumpyAll(var_bounds_value[slice(*dest_dim.bounds_local)], svar.bounds.get_value())
            self.assertNumpyAll(dim_src_idx[slice(*dest_dim.bounds_local)], svar.dimensions[0]._src_idx)
            self.assertNumpyAll(dim_src_idx[slice(*dest_dim.bounds_local)], svar.bounds.dimensions[0]._src_idx)
Esempio n. 16
0
 def test_system_create_many_large_dimensions(self):
     count = 10000
     dims = [None] * count
     for idx in range(count):
         dims[idx] = Dimension(str(idx), size=500000000, src_idx='auto')
     sliced_dims = [None] * len(dims)
     for idx in range(count):
         sliced_dims[idx] = dims[idx][50000:490000000]
Esempio n. 17
0
 def add_data_variable_to_grid(grid):
     ydim, xdim = grid.dimensions
     tdim = Dimension(name='time', size=None)
     value = np.random.rand(31, ydim.size, xdim.size)
     data = Variable(name='data', dimensions=[tdim, ydim, xdim], value=value)
     tvar = TemporalVariable(name='time', value=list(range(31)), dimensions=tdim, attrs={'axis': 'T'})
     grid.parent.add_variable(data)
     grid.parent.add_variable(tvar)
Esempio n. 18
0
    def test_variable_scatter_ndimensions(self):

        r = Dimension('realization', 3)
        t = Dimension('time', 365)
        l = Dimension('level', 10)
        y = Dimension('y', 90, dist=True)
        x = Dimension('x', 360, dist=True)

        dimensions = [r, t, l, y, x]

        dest_mpi = OcgDist()
        for d in dimensions:
            dest_mpi.add_dimension(d)
        dest_mpi.update_dimension_bounds()

        if MPI_RANK == 0:
            local_dimensions = deepcopy(dimensions)
            for l in local_dimensions:
                l.dist = False
            var = Variable('tas', dimensions=local_dimensions)
        else:
            var = None

        svar = variable_scatter(var, dest_mpi)

        self.assertTrue(svar.dist)
        self.assertIsNotNone(svar)

        if MPI_SIZE == 2:
            self.assertEqual(svar.shape, (3, 365, 10, 90, 180))
Esempio n. 19
0
    def test_set_extrapolated_bounds_empty(self):
        """Test bounds extrapolation works on empty objects."""

        dimx = Dimension('x', 2, is_empty=True, dist=True)
        x = Variable('x', dimensions=dimx)
        y = Variable('3', dimensions=Dimension('y', 3))
        grid = Grid(x, y)

        self.assertTrue(dimx.is_empty)
        self.assertTrue(x.is_empty)
        self.assertTrue(grid.is_empty)
        self.assertFalse(grid.has_bounds)
        self.assertEqual(grid.abstraction, 'point')

        grid.set_extrapolated_bounds('xbnds', 'ybnds', 'bounds')
        self.assertEqual(grid.abstraction, 'polygon')
        self.assertTrue(grid.has_bounds)
        self.assertTrue(grid.is_empty)
Esempio n. 20
0
    def test_copy(self):
        sd = self.get_dimension(src_idx=np.arange(10))
        self.assertIsNotNone(sd._src_idx)
        sd2 = sd.copy()
        self.assertTrue(np.may_share_memory(sd._src_idx, sd2._src_idx))
        sd3 = sd2[2:5]
        self.assertEqual(sd, sd2)
        self.assertNotEqual(sd2, sd3)
        self.assertTrue(np.may_share_memory(sd2._src_idx, sd._src_idx))
        self.assertTrue(np.may_share_memory(sd2._src_idx, sd3._src_idx))
        self.assertTrue(np.may_share_memory(sd3._src_idx, sd._src_idx))

        # Test setting new values on object.
        dim = Dimension('five', 5)
        cdim = dim.copy()
        cdim._name = 'six'
        self.assertEqual(dim.name, 'five')
        self.assertEqual(cdim.name, 'six')
Esempio n. 21
0
    def test_copy(self):
        sd = self.get_dimension(src_idx=np.arange(10))
        self.assertIsNotNone(sd._src_idx)
        sd2 = sd.copy()
        self.assertTrue(np.may_share_memory(sd._src_idx, sd2._src_idx))
        sd3 = sd2[2:5]
        self.assertEqual(sd, sd2)
        self.assertNotEqual(sd2, sd3)
        self.assertTrue(np.may_share_memory(sd2._src_idx, sd._src_idx))
        self.assertTrue(np.may_share_memory(sd2._src_idx, sd3._src_idx))
        self.assertTrue(np.may_share_memory(sd3._src_idx, sd._src_idx))

        # Test setting new values on object.
        dim = Dimension('five', 5)
        cdim = dim.copy()
        cdim._name = 'six'
        self.assertEqual(dim.name, 'five')
        self.assertEqual(cdim.name, 'six')
Esempio n. 22
0
    def test_create_dimensions(self):
        driver = self.get_driver()
        actual = driver.create_dist().mapping[MPI_RANK]
        desired = {None: {
            'variables': {},
            'dimensions': {
                'ocgis_ngeom': Dimension(name='ocgis_ngeom', size=51, size_current=51, dist=True, src_idx='auto')},
            'groups': {}}}

        self.assertEqual(actual, desired)
Esempio n. 23
0
 def get_OcgDist_01(self):
     s = Dimension('first_dist', size=5, dist=True, src_idx='auto')
     ompi = OcgDist()
     ompi.add_dimension(s)
     ompi.create_dimension('not_dist', size=8, dist=False)
     ompi.create_dimension('another_dist', size=6, dist=True)
     ompi.create_dimension('another_not_dist', size=100, dist=False)
     ompi.create_dimension('coordinate_reference_system', size=0)
     self.assertIsNotNone(s._src_idx)
     return ompi
Esempio n. 24
0
    def test_get_nonempty_ranks(self):
        from ocgis.variable.dimension import Dimension
        comm, rank, size = get_standard_comm_state()

        if size not in [1, 3]:
            raise SkipTest('MPI_SIZE != 1 or 3')

        target = Dimension('a')
        live_ranks = get_nonempty_ranks(target, vm)
        if MPI_RANK == 0:
            self.assertEqual(live_ranks, tuple(range(size)))

        if MPI_SIZE == 3:
            targets = {0: Dimension('a', is_empty=True, dist=True),
                       1: Dimension('a'),
                       2: Dimension('a')}
            with vm.scoped('ner', vm.ranks):
                live_ranks = get_nonempty_ranks(targets[MPI_RANK], vm)
            self.assertEqual(live_ranks, (1, 2))
Esempio n. 25
0
    def _get_dimensions_main_(self, group_metadata):
        """
        :param dict group_metadata: Metadata dictionary for the target group.
        :return: A sequence of dimension objects.
        :rtype: sequence
        """

        gmd = group_metadata['dimensions']
        dims = [Dimension(dref['name'], size=dref['size'], src_idx='auto') for dref in list(gmd.values())]
        return tuple(dims)
Esempio n. 26
0
    def test_init_source_name(self):
        dim = Dimension('foo', source_name='actual_foo')
        self.assertEqual(dim.source_name, 'actual_foo')

        dim = Dimension('foo')
        dim.set_name('new_foo')
        self.assertEqual(dim.source_name, 'foo')
Esempio n. 27
0
 def test_get_dimensions(self):
     driver = self.get_driver()
     actual = driver.get_dist().mapping[MPI_RANK]
     desired = {None: {
         'variables': {'STATE_FIPS': {'dimensions': ('ocgis_geom',)},
                       'STATE_ABBR': {'dimensions': ('ocgis_geom',)},
                       'UGID': {'dimensions': ('ocgis_geom',)},
                       'ID': {'dimensions': ('ocgis_geom',)},
                       'STATE_NAME': {'dimensions': ('ocgis_geom',)}},
         'dimensions': {
             'ocgis_geom': Dimension(name='ocgis_geom', size=51, size_current=51, dist=True, src_idx='auto')},
         'groups': {}}}
     self.assertEqual(actual, desired)
Esempio n. 28
0
 def get_ocgfield_example(self):
     dtime = Dimension(name='time')
     t = TemporalVariable(value=[1, 2, 3, 4], name='the_time', dimensions=dtime, dtype=float)
     t.set_extrapolated_bounds('the_time_bounds', 'bounds')
     lon = Variable(value=[30., 40., 50., 60.], name='longitude', dimensions='lon')
     lat = Variable(value=[-10., -20., -30., -40., -50.], name='latitude', dimensions='lat')
     tas_shape = [t.shape[0], lat.shape[0], lon.shape[0]]
     tas = Variable(value=np.arange(reduce_multiply(tas_shape)).reshape(*tas_shape),
                    dimensions=(dtime, 'lat', 'lon'), name='tas')
     time_related = Variable(value=[7, 8, 9, 10], name='time_related', dimensions=dtime)
     garbage1 = Variable(value=[66, 67, 68], dimensions='three', name='garbage1')
     dmap = {'time': {'variable': t.name},
             'x': {'variable': lon.name, DimensionMapKey.DIMENSION: [lon.dimensions[0].name]},
             'y': {'variable': lat.name, DimensionMapKey.DIMENSION: [lat.dimensions[0].name]}}
     field = Field(variables=[t, lon, lat, tas, garbage1, time_related], dimension_map=dmap, is_data=tas.name)
     return field
Esempio n. 29
0
def get_dimensions_from_netcdf_metadata(metadata, desired_dimensions):
    new_dimensions = []
    for dim_name in desired_dimensions:
        dim = metadata['dimensions'][dim_name]
        dim_length = dim['size']
        if dim['isunlimited']:
            length = None
            length_current = dim_length
        else:
            length = dim_length
            length_current = None
        # tdk: identify best method to remove the need to set 'auto' when creating a source index
        # new_dim = Dimension(dim_name, size=length, size_current=length_current)
        new_dim = Dimension(dim_name,
                            size=length,
                            size_current=length_current,
                            src_idx='auto')
        new_dimensions.append(new_dim)
    return new_dimensions
Esempio n. 30
0
    def test_init(self):
        dim = Dimension('foo')
        self.assertEqual(dim.name, 'foo')
        self.assertIsNone(dim.size)
        self.assertIsNone(dim.size_current)
        self.assertTrue(dim.is_unlimited)
        self.assertEqual(len(dim), 0)
        self.assertEqual(dim.bounds_local, (0, len(dim)))
        self.assertEqual(dim.bounds_global, dim.bounds_local)

        dim = Dimension('foo', size=23)
        self.assertEqual(dim.size, 23)

        src_idx = np.arange(0, 10, dtype=DataType.DIMENSION_SRC_INDEX)
        dim = self.get_dimension(src_idx=src_idx)
        self.assertNumpyAll(dim._src_idx, src_idx)
        self.assertEqual(dim._src_idx.shape[0], 10)

        # Test distributed dimensions require and size definition.
        with self.assertRaises(ValueError):
            Dimension('foo', dist=True)

        # Test without size definition and a source index.
        for src_idx in ['auto', 'ato', [0, 1, 2]]:
            try:
                dim = Dimension('foo', src_idx=src_idx)
            except ValueError:
                self.assertNotEqual(src_idx, 'auto')
            else:
                self.assertIsNone(dim._src_idx)

        # Test a unique identifier.
        dim = Dimension('foo', uid=10)
        self.assertEqual(dim.uid, 10)

        # Test using a tuple with conversion required.
        desired = (0, 5)
        dim = Dimension('test', 5, src_idx=list(desired))
        self.assertEqual(dim._src_idx, desired)

        # Test bounds are the default source index type.
        dim = Dimension('test', 8, src_idx='auto')
        self.assertEqual(dim._src_idx, (0, 8))
Esempio n. 31
0
    def test_convert_to_geometry_coordinates_polygons(self):
        grid = create_gridxy_global(resolution=45.0)
        geom = grid.get_abstraction_geometry()
        geom.reshape(Dimension('n_elements', geom.size))

        keywords = dict(pack=[True, False],
                        repeat_last_node=[False, True],
                        start_index=[0, 1])
        for k in self.iter_product_keywords(keywords):
            actual = geom.convert_to(pack=k.pack,
                                     repeat_last_node=k.repeat_last_node,
                                     start_index=k.start_index)
            self.assertEqual(actual.cindex.attrs['start_index'], k.start_index)
            self.assertEqual(actual.start_index, k.start_index)
            self.assertEqual(actual.cindex.get_value()[0].min(), k.start_index)
            self.assertEqual(actual.packed, k.pack)
            self.assertIsNotNone(actual.cindex)

            for actual_geom, desired_geom in zip(
                    actual.get_geometry_iterable(),
                    geom.get_value().flat):
                self.assertEqual(actual_geom[1], desired_geom)
Esempio n. 32
0
File: base.py Progetto: huard/ocgis
    def create_dimensions(group_metadata):
        """
        Create dimension objects. The key may differ from the dimension name. In which case, we can assume the dimension
        is being renamed.

        :param dict group_metadata: Metadata dictionary for the target group.
        :rtype: list
        """
        gmd = group_metadata.get('dimensions', {})
        dims = {}
        for k, v in gmd.items():
            size = v['size']
            if v.get('isunlimited', False):
                size_current = size
                size = None
            else:
                size_current = None
            dims[k] = Dimension(v.get('name', k),
                                size=size,
                                size_current=size_current,
                                src_idx='auto',
                                source_name=k)
        return dims
Esempio n. 33
0
 def test_is_matched_by_alias(self):
     dim = Dimension('non_standard_time')
     dim.append_alias('time')
     self.assertTrue(dim.is_matched_by_alias('time'))
Esempio n. 34
0
    def get_unioned(self,
                    dimensions=None,
                    union_dimension=None,
                    spatial_average=None,
                    root=0):
        """
        Unions _unmasked_ geometry objects. Collective across the current :class:`~ocgis.OcgVM`.
        """
        # TODO: optimize!

        # Get dimension names and lengths for the dimensions to union.
        if dimensions is None:
            dimensions = self.dimensions
        dimension_names = get_dimension_names(dimensions)
        dimension_lengths = [
            len(self.parent.dimensions[dn]) for dn in dimension_names
        ]

        # Get the variables to spatial average.
        if spatial_average is not None:
            variable_names_to_weight = get_variable_names(spatial_average)
        else:
            variable_names_to_weight = []

        # Get the new dimensions for the geometry variable. The union dimension is always the last dimension.
        if union_dimension is None:
            from ocgis.variable.dimension import Dimension
            union_dimension = Dimension(
                constants.DimensionName.UNIONED_GEOMETRY, 1)
        new_dimensions = []
        for dim in self.dimensions:
            if dim.name not in dimension_names:
                new_dimensions.append(dim)
        new_dimensions.append(union_dimension)

        # Configure the return variable.
        ret = self.copy()
        if spatial_average is None:
            ret = ret.extract()
        ret.set_mask(None)
        ret.set_value(None)
        ret.set_dimensions(new_dimensions)
        ret.allocate_value()

        # Destination indices in the return variable are filled with non-masked, unioned geometries.
        for dst_indices in product(
                *
            [list(range(dl)) for dl in get_dimension_lengths(new_dimensions)]):
            dst_slc = {
                new_dimensions[ii].name: dst_indices[ii]
                for ii in range(len(new_dimensions))
            }

            # Select the geometries to union skipping any masked geometries.
            to_union = deque()
            for indices in product(
                    *[list(range(dl)) for dl in dimension_lengths]):
                dslc = {
                    dimension_names[ii]: indices[ii]
                    for ii in range(len(dimension_names))
                }
                sub = self[dslc]
                sub_mask = sub.get_mask()
                if sub_mask is None:
                    to_union.append(sub.get_value().flatten()[0])
                else:
                    if not sub_mask.flatten()[0]:
                        to_union.append(sub.get_value().flatten()[0])

            # Execute the union operation.
            processed_to_union = deque()
            for geom in to_union:
                if isinstance(geom, MultiPolygon) or isinstance(
                        geom, MultiPoint):
                    for element in geom:
                        processed_to_union.append(element)
                else:
                    processed_to_union.append(geom)
            unioned = cascaded_union(processed_to_union)

            # Pull unioned geometries and union again for the final unioned geometry.
            if vm.size > 1:
                unioned_gathered = vm.gather(unioned)
                if vm.rank == root:
                    unioned = cascaded_union(unioned_gathered)

            # Fill the return geometry variable value with the unioned geometry.
            to_fill = ret[dst_slc].get_value()
            to_fill[0] = unioned

        # Spatial average shared dimensions.
        if spatial_average is not None:
            # Get source data to weight.
            for var_to_weight in filter(
                    lambda ii: ii.name in variable_names_to_weight,
                    list(self.parent.values())):
                # Holds sizes of dimensions to iterate. These dimension are not squeezed by the weighted averaging.
                range_to_itr = []
                # Holds the names of dimensions to squeeze.
                names_to_itr = []
                # Dimension names that are squeezed. Also the dimensions for the weight matrix.
                names_to_slice_all = []
                for dn in var_to_weight.dimensions:
                    if dn.name in self.dimension_names:
                        names_to_slice_all.append(dn.name)
                    else:
                        range_to_itr.append(len(dn))
                        names_to_itr.append(dn.name)

                # Reference the weights on the source geometry variable.
                weights = self[{
                    nsa: slice(None)
                    for nsa in names_to_slice_all
                }].weights

                # Path if there are iteration dimensions. Checks for axes ordering in addition.
                if len(range_to_itr) > 0:
                    # New dimensions for the spatially averaged variable. Unioned dimension is always last. Remove the
                    # dimensions aggregated by the weighted average.
                    new_dimensions = [
                        dim for dim in var_to_weight.dimensions
                        if dim.name not in dimension_names
                    ]
                    new_dimensions.append(union_dimension)

                    # Prepare the spatially averaged variable.
                    target = ret.parent[var_to_weight.name]
                    target.set_mask(None)
                    target.set_value(None)
                    target.set_dimensions(new_dimensions)
                    target.allocate_value()

                    # Swap weight axes to make sure they align with the target variable.
                    swap_chain = get_swap_chain(dimension_names,
                                                names_to_slice_all)
                    if len(swap_chain) > 0:
                        weights = weights.copy()
                    for sc in swap_chain:
                        weights = weights.swapaxes(*sc)

                    # The main weighting loop. Can get quite intensive with many, large iteration dimensions.
                    len_names_to_itr = len(names_to_itr)
                    slice_none = slice(None)
                    squeeze_out = [
                        ii for ii, dim in enumerate(var_to_weight.dimensions)
                        if dim.name in names_to_itr
                    ]
                    should_squeeze = True if len(squeeze_out) > 0 else False
                    np_squeeze = np.squeeze
                    np_atleast_1d = np.atleast_1d
                    np_ma_average = np.ma.average
                    for nonweighted_indices in product(
                            *[list(range(ri)) for ri in range_to_itr]):
                        w_slc = {
                            names_to_itr[ii]: nonweighted_indices[ii]
                            for ii in range(len_names_to_itr)
                        }
                        for nsa in names_to_slice_all:
                            w_slc[nsa] = slice_none
                        data_to_weight = var_to_weight[w_slc].get_masked_value(
                        )
                        if should_squeeze:
                            data_to_weight = np_squeeze(
                                data_to_weight, axis=tuple(squeeze_out))
                        weighted_value = np_atleast_1d(
                            np_ma_average(data_to_weight, weights=weights))
                        target[w_slc].get_value()[:] = weighted_value
                else:
                    target_to_weight = var_to_weight.get_masked_value()
                    # Sort to minimize floating point sum errors.
                    target_to_weight = target_to_weight.flatten()
                    weights = weights.flatten()
                    sindices = np.argsort(target_to_weight)
                    target_to_weight = target_to_weight[sindices]
                    weights = weights[sindices]

                    weighted_value = np.atleast_1d(
                        np.ma.average(target_to_weight, weights=weights))
                    target = ret.parent[var_to_weight.name]
                    target.set_mask(None)
                    target.set_value(None)
                    target.set_dimensions(new_dimensions)
                    target.set_value(weighted_value)

            # Collect areas of live ranks and convert to weights.
            if vm.size > 1:
                # If there is no area information (points for example, we need to use counts).
                if ret.area.data[0].max() == 0:
                    weight_or_proxy = float(self.size)
                else:
                    weight_or_proxy = ret.area.data[0]

                if vm.rank != root:
                    vm.comm.send(weight_or_proxy, dest=root)
                else:
                    live_rank_areas = [weight_or_proxy]
                    for tner in vm.ranks:
                        if tner != vm.rank:
                            recv_area = vm.comm.recv(source=tner)
                            live_rank_areas.append(recv_area)
                    live_rank_areas = np.array(live_rank_areas)

                    rank_weights = live_rank_areas / np.max(live_rank_areas)

                for var_to_weight in filter(
                        lambda ii: ii.name in variable_names_to_weight,
                        list(ret.parent.values())):
                    dimensions_to_itr = [
                        dim.name for dim in var_to_weight.dimensions
                        if dim.name != union_dimension.name
                    ]
                    slc = {union_dimension.name: 0}
                    for idx_slc in var_to_weight.iter_dict_slices(
                            dimensions=dimensions_to_itr):
                        idx_slc.update(slc)
                        to_weight = var_to_weight[idx_slc].get_value().flatten(
                        )[0]
                        if vm.rank == root:
                            collected_to_weight = [to_weight]
                        if not vm.rank == root:
                            vm.comm.send(to_weight, dest=root)
                        else:
                            for tner in vm.ranks:
                                if not tner == root:
                                    recv_to_weight = vm.comm.recv(source=tner)
                                    collected_to_weight.append(recv_to_weight)

                            # Sort to minimize floating point sum errors.
                            collected_to_weight = np.array(collected_to_weight)
                            sindices = np.argsort(collected_to_weight)
                            collected_to_weight = collected_to_weight[sindices]
                            rank_weights = rank_weights[sindices]

                            weighted = np.atleast_1d(
                                np.ma.average(collected_to_weight,
                                              weights=rank_weights))
                            var_to_weight[idx_slc].get_value()[:] = weighted
        if vm.rank == root:
            return ret
        else:
            return
Esempio n. 35
0
 def test_bounds_local(self):
     dim = Dimension('a', 5)
     dim.bounds_local = [0, 2]
     self.assertEqual(dim.bounds_local, (0, 2))