def _cube_to_GridInfo(cube, center=False, resolution=None):
    # This is a simplified version of an equivalent function/method in PR #26.
    # It is anticipated that this function will be replaced by the one in PR #26.
    #
    # Returns a GridInfo object describing the horizontal grid of the cube.
    # This may be inherited from code written for the rectilinear regridding scheme.
    lon, lat = cube.coord(axis="x"), cube.coord(axis="y")
    #  Checks may cover units, coord systems (e.g. rotated pole), contiguous bounds.
    if cube.coord_system() is None:
        crs = None
    else:
        crs = cube.coord_system().as_cartopy_crs()
    londim, latdim = len(lon.shape), len(lat.shape)
    assert londim == latdim
    assert londim in (1, 2)
    if londim == 1:
        # Ensure coords come from a proper grid.
        assert isinstance(lon, iris.coords.DimCoord)
        assert isinstance(lat, iris.coords.DimCoord)
        circular = lon.circular
        # TODO: perform checks on lat/lon.
    elif londim == 2:
        assert cube.coord_dims(lon) == cube.coord_dims(lat)
        assert lon.is_contiguous()
        assert lat.is_contiguous()
        # 2D coords must be AuxCoords, which do not have a circular attribute.
        circular = False
    lon_bound_array = lon.contiguous_bounds()
    lon_bound_array = lon.units.convert(lon_bound_array, Unit("degrees"))
    lat_bound_array = lat.contiguous_bounds()
    lat_bound_array = lat.units.convert(lat_bound_array, Unit("degrees"))
    if resolution is None:
        grid_info = GridInfo(
            lon.points,
            lat.points,
            lon_bound_array,
            lat_bound_array,
            crs=crs,
            circular=circular,
            center=center,
        )
    else:
        grid_info = RefinedGridInfo(
            lon_bound_array,
            lat_bound_array,
            crs=crs,
            resolution=resolution,
        )
    return grid_info
Beispiel #2
0
def _create_cf_grid_mapping(dataset, cube, cf_var):
    """
    Create CF-netCDF grid mapping variable and associated CF-netCDF
    data variable grid mapping attribute. 
    
    """
    cs = cube.coord_system('HorizontalCS')
    
    if cs is not None:
        if isinstance(cs, iris.coord_systems.LatLonCS):
            cf_grid_name = 'rotated_latitude_longitude' if cs.has_rotated_pole() else 'latitude_longitude'
            
            if cf_grid_name not in dataset.variables:
                cf_var.grid_mapping = cf_grid_name
                cf_var_grid = dataset.createVariable(cf_grid_name, np.int32)
                cf_var_grid.grid_mapping_name = cf_grid_name
                cf_var_grid.longitude_of_prime_meridian = 0.0
    
                if cs.datum:
                    cf_var_grid.semi_major_axis = cs.datum.semi_major_axis
                    cf_var_grid.semi_minor_axis = cs.datum.semi_minor_axis
                
                if cs.has_rotated_pole():
                    if cs.n_pole:
                        cf_var_grid.grid_north_pole_latitude = cs.n_pole.latitude
                        cf_var_grid.grid_north_pole_longitude = cs.n_pole.longitude
                        
                    cf_var_grid.north_pole_grid_longitude = cs.reference_longitude
            else:
                # Reference previously created grid mapping
                cf_var.grid_mapping = cf_grid_name
        else:
            warnings.warn('Unable to represent the horizontal coordinate system. The coordinate system type %r is not yet implemented.' % type(cs))
Beispiel #3
0
def _map_common(draw_method_name, arg_func, mode, cube, data, *args, **kwargs):
    """
    Draw the given cube on a map using its points or bounds.

    "Mode" parameter will switch functionality between POINT or BOUND plotting.

    """
    # get the 2d x and 2d y from the CS
    if mode == iris.coords.POINT_MODE:
        x, y = cartography.get_xy_grids(cube)
    else:
        try:
            x, y = cartography.get_xy_contiguous_bounded_grids(cube)
        # Exception translation.
        except iris.exceptions.CoordinateMultiDimError:
            raise ValueError("Could not get XY grid from bounds. "
                             "X or Y coordinate not 1D.")
        except ValueError:
            raise ValueError("Could not get XY grid from bounds. "
                             "X or Y coordinate doesn't have 2 bounds "
                             "per point.")

    # take a copy of the data so that we can make modifications to it
    data = data.copy()

    # If we are global, then append the first column of data the array to the
    # last (and add 360 degrees) NOTE: if it is found that this block of code
    # is useful in anywhere other than this plotting routine, it may be better
    # placed in the CS.
    x_coord = cube.coord(axis="X")
    if getattr(x_coord, 'circular', False):
        _, direction = iris.util.monotonic(x_coord.points,
                                           return_direction=True)
        y = np.append(y, y[:, 0:1], axis=1)
        x = np.append(x, x[:, 0:1] + 360 * direction, axis=1)
        data = ma.concatenate([data, data[:, 0:1]], axis=1)

    # Replace non-cartopy subplot/axes with a cartopy alternative.
    cs = cube.coord_system('CoordSystem')
    if cs:
        cartopy_proj = cs.as_cartopy_projection()
    else:
        cartopy_proj = cartopy.crs.PlateCarree()
    ax = _get_cartopy_axes(cartopy_proj)

    draw_method = getattr(ax, draw_method_name)

    # Set the "from transform" keyword.
    # NB. While cartopy doesn't support spherical contours, just use the
    # projection as the source CRS.
    assert 'transform' not in kwargs, 'Transform keyword is not allowed.'
    kwargs['transform'] = cartopy_proj

    if arg_func is not None:
        new_args, kwargs = arg_func(x, y, data, *args, **kwargs)
    else:
        new_args = (x, y, data) + args

    # Draw the contour lines/filled contours.
    return draw_method(*new_args, **kwargs)
Beispiel #4
0
    def _check_both_conversions(self, cube):
        lats, lons = iris.analysis.cartography.get_lat_lon_grids(cube)
        plt.scatter(lons, lats)
        self.check_graphic()

        n_pole = cube.coord_system('LatLonCS').n_pole
        rlons, rlats = iris.analysis.cartography.rotate_pole(lons, lats, n_pole.longitude, n_pole.latitude)
        plt.scatter(rlons, rlats)
        self.check_graphic()
Beispiel #5
0
    def _check_both_conversions(self, cube):
        rlons, rlats = iris.analysis.cartography.get_xy_grids(cube)
        rcs = cube.coord_system('RotatedGeogCS')
        x, y = iris.analysis.cartography.unrotate_pole(
            rlons, rlats, rcs.grid_north_pole_longitude,
            rcs.grid_north_pole_latitude)
        plt.scatter(x, y)
        self.check_graphic()

        plt.scatter(rlons, rlats)
        self.check_graphic()
Beispiel #6
0
    def _check_both_conversions(self, cube):
        rlons, rlats = iris.analysis.cartography.get_xy_grids(cube)
        rcs = cube.coord_system('RotatedGeogCS')
        x, y = iris.analysis.cartography.unrotate_pole(
            rlons, rlats, rcs.grid_north_pole_longitude,
            rcs.grid_north_pole_latitude)
        plt.scatter(x, y)
        self.check_graphic()

        plt.scatter(rlons, rlats)
        self.check_graphic()
Beispiel #7
0
def default_projection(cube):
    """
    Return the primary map projection for the given cube.

    Using the returned projection, one can create a cartopy map with::

        import matplotlib.pyplot as plt
        ax = plt.ax(projection=default_projection(cube))

    """
    # XXX logic seems flawed, but it is what map_setup did...
    cs = cube.coord_system("CoordSystem")
    projection = cs.as_cartopy_projection() if cs else None
    return projection
Beispiel #8
0
def default_projection(cube):
    """
    Return the primary map projection for the given cube.

    Using the returned projection, one can create a cartopy map with::

        import matplotlib.pyplot as plt
        ax = plt.ax(projection=default_projection(cube))

    """
    # XXX logic seems flawed, but it is what map_setup did...
    cs = cube.coord_system("CoordSystem")
    projection = cs.as_cartopy_projection() if cs else None
    return projection
Beispiel #9
0
 def _check_both_conversions(self, cube, index):
     rlons, rlats = iris.analysis.cartography.get_xy_grids(cube)
     rcs = cube.coord_system('RotatedGeogCS')
     x, y = iris.analysis.cartography.unrotate_pole(
         rlons, rlats, rcs.grid_north_pole_longitude,
         rcs.grid_north_pole_latitude)
     self.assertDataAlmostEqual(
         x, ('analysis', 'rotated_pole.{}.x.json'.format(index)))
     self.assertDataAlmostEqual(
         y, ('analysis', 'rotated_pole.{}.y.json'.format(index)))
     self.assertDataAlmostEqual(
         rlons, ('analysis', 'rotated_pole.{}.rlon.json'.format(index)))
     self.assertDataAlmostEqual(
         rlats, ('analysis', 'rotated_pole.{}.rlat.json'.format(index)))
Beispiel #10
0
 def _check_both_conversions(self, cube, index):
     rlons, rlats = iris.analysis.cartography.get_xy_grids(cube)
     rcs = cube.coord_system('RotatedGeogCS')
     x, y = iris.analysis.cartography.unrotate_pole(
         rlons, rlats, rcs.grid_north_pole_longitude,
         rcs.grid_north_pole_latitude)
     self.assertDataAlmostEqual(x, ('analysis',
                                    'rotated_pole.{}.x.json'.format(index)))
     self.assertDataAlmostEqual(y, ('analysis',
                                    'rotated_pole.{}.y.json'.format(index)))
     self.assertDataAlmostEqual(rlons,
                                ('analysis',
                                 'rotated_pole.{}.rlon.json'.format(index)))
     self.assertDataAlmostEqual(rlats,
                                ('analysis',
                                 'rotated_pole.{}.rlat.json'.format(index)))
Beispiel #11
0
def _create_cf_grid_mapping(dataset, cube, cf_var):
    """
    Create CF-netCDF grid mapping variable and associated CF-netCDF
    data variable grid mapping attribute.

    """
    # TODO: What if there's more than one CoordSystem?
    cs = cube.coord_system('CoordSystem')
    if cs is not None:

        # Grid var not yet created?
        if cs.grid_mapping_name not in dataset.variables:
            cf_var_grid = dataset.createVariable(cs.grid_mapping_name, np.int32)
            cf_var_grid.grid_mapping_name = cs.grid_mapping_name

            # latlon
            if isinstance(cs, iris.coord_systems.GeogCS):
                cf_var_grid.longitude_of_prime_meridian = cs.longitude_of_prime_meridian
                cf_var_grid.semi_major_axis = cs.semi_major_axis
                cf_var_grid.semi_minor_axis = cs.semi_minor_axis

            # rotated latlon
            elif isinstance(cs, iris.coord_systems.RotatedGeogCS):
                if cs.ellipsoid:
                    cf_var_grid.longitude_of_prime_meridian = cs.ellipsoid.longitude_of_prime_meridian
                    cf_var_grid.semi_major_axis = cs.ellipsoid.semi_major_axis
                    cf_var_grid.semi_minor_axis = cs.ellipsoid.semi_minor_axis
                cf_var_grid.grid_north_pole_latitude = cs.grid_north_pole_latitude
                cf_var_grid.grid_north_pole_longitude = cs.grid_north_pole_longitude
                cf_var_grid.north_pole_grid_longitude = cs.north_pole_grid_longitude

            # tmerc
            elif isinstance(cs, iris.coord_systems.TransverseMercator):
                warnings.warn('TransverseMercator coordinate system not yet handled')

            # osgb (a specific tmerc)
            elif isinstance(cs, iris.coord_systems.OSGB):
                warnings.warn('OSGB coordinate system not yet handled')

            # other
            else:
                warnings.warn('Unable to represent the horizontal coordinate system. The coordinate system type %r is not yet implemented.' % type(cs))

        # Refer to grid var
        cf_var.grid_mapping = cs.grid_mapping_name
Beispiel #12
0
    def _create_cf_grid_mapping(self, cube, cf_var_cube):
        """
        Create CF-netCDF grid mapping variable and associated CF-netCDF
        data variable grid mapping attribute.

        Args:

        * cube (:class:`iris.cube.Cube`) or cubelist
          (:class:`iris.cube.CubeList`):
            A :class:`iris.cube.Cube`, :class:`iris.cube.CubeList` or list of
            cubes to be saved to a netCDF file.
        * cf_var_cube (:class:`netcdf.netcdf_variable`):
            cf variable cube representation.

        Returns:
            None

        """
        cs = cube.coord_system('CoordSystem')
        if cs is not None:
            # Grid var not yet created?
            if cs not in self._coord_systems:
                while cs.grid_mapping_name in self._dataset.variables:
                    cs.grid_mapping_name = (
                        self._increment_name(cs.grid_mapping_name))

                cf_var_grid = self._dataset.createVariable(
                    cs.grid_mapping_name, np.int32)
                cf_var_grid.grid_mapping_name = cs.grid_mapping_name

                # latlon
                if isinstance(cs, iris.coord_systems.GeogCS):
                    cf_var_grid.longitude_of_prime_meridian = (
                        cs.longitude_of_prime_meridian)
                    cf_var_grid.semi_major_axis = cs.semi_major_axis
                    cf_var_grid.semi_minor_axis = cs.semi_minor_axis

                # rotated latlon
                elif isinstance(cs, iris.coord_systems.RotatedGeogCS):
                    if cs.ellipsoid:
                        cf_var_grid.longitude_of_prime_meridian = (
                            cs.ellipsoid.longitude_of_prime_meridian)
                        cf_var_grid.semi_major_axis = (
                            cs.ellipsoid.semi_major_axis)
                        cf_var_grid.semi_minor_axis = (
                            cs.ellipsoid.semi_minor_axis)
                    cf_var_grid.grid_north_pole_latitude = (
                        cs.grid_north_pole_latitude)
                    cf_var_grid.grid_north_pole_longitude = (
                        cs.grid_north_pole_longitude)
                    cf_var_grid.north_pole_grid_longitude = (
                        cs.north_pole_grid_longitude)

                # tmerc
                elif isinstance(cs, iris.coord_systems.TransverseMercator):
                    warnings.warn('TransverseMercator coordinate system not '
                                  'yet handled')

                # osgb (a specific tmerc)
                elif isinstance(cs, iris.coord_systems.OSGB):
                    warnings.warn('OSGB coordinate system not yet handled')

                # other
                else:
                    warnings.warn('Unable to represent the horizontal '
                                  'coordinate system. The coordinate system '
                                  'type %r is not yet implemented.' % type(cs))

                self._coord_systems.append(cs)

            # Refer to grid var
            cf_var_cube.grid_mapping = cs.grid_mapping_name
Beispiel #13
0
    def _create_cf_grid_mapping(self, cube, cf_var_cube):
        """
        Create CF-netCDF grid mapping variable and associated CF-netCDF
        data variable grid mapping attribute.

        Args:

        * cube (:class:`iris.cube.Cube`) or cubelist
          (:class:`iris.cube.CubeList`):
            A :class:`iris.cube.Cube`, :class:`iris.cube.CubeList` or list of
            cubes to be saved to a netCDF file.
        * cf_var_cube (:class:`netcdf.netcdf_variable`):
            cf variable cube representation.

        Returns:
            None

        """
        cs = cube.coord_system('CoordSystem')
        if cs is not None:
            # Grid var not yet created?
            if cs not in self._coord_systems:
                while cs.grid_mapping_name in self._dataset.variables:
                    cs.grid_mapping_name = (
                        self._increment_name(cs.grid_mapping_name))

                cf_var_grid = self._dataset.createVariable(
                    cs.grid_mapping_name, np.int32)
                cf_var_grid.grid_mapping_name = cs.grid_mapping_name

                # latlon
                if isinstance(cs, iris.coord_systems.GeogCS):
                    cf_var_grid.longitude_of_prime_meridian = (
                        cs.longitude_of_prime_meridian)
                    cf_var_grid.semi_major_axis = cs.semi_major_axis
                    cf_var_grid.semi_minor_axis = cs.semi_minor_axis

                # rotated latlon
                elif isinstance(cs, iris.coord_systems.RotatedGeogCS):
                    if cs.ellipsoid:
                        cf_var_grid.longitude_of_prime_meridian = (
                            cs.ellipsoid.longitude_of_prime_meridian)
                        cf_var_grid.semi_major_axis = (
                            cs.ellipsoid.semi_major_axis)
                        cf_var_grid.semi_minor_axis = (
                            cs.ellipsoid.semi_minor_axis)
                    cf_var_grid.grid_north_pole_latitude = (
                        cs.grid_north_pole_latitude)
                    cf_var_grid.grid_north_pole_longitude = (
                        cs.grid_north_pole_longitude)
                    cf_var_grid.north_pole_grid_longitude = (
                        cs.north_pole_grid_longitude)

                # tmerc
                elif isinstance(cs, iris.coord_systems.TransverseMercator):
                    warnings.warn('TransverseMercator coordinate system not '
                                  'yet handled')

                # osgb (a specific tmerc)
                elif isinstance(cs, iris.coord_systems.OSGB):
                    warnings.warn('OSGB coordinate system not yet handled')

                # other
                else:
                    warnings.warn('Unable to represent the horizontal '
                                  'coordinate system. The coordinate system '
                                  'type %r is not yet implemented.' % type(cs))

                self._coord_systems.append(cs)

            # Refer to grid var
            cf_var_cube.grid_mapping = cs.grid_mapping_name