Ejemplo n.º 1
0
def test_vector_rotation_complex():
    x, y, angles_simple, angles_complex = rotate_vectors_data()
    rotated_x, rotated_y = rotate_vectors(x, y, angles_complex)
    expected_x = np.array([0.5981, -3.0083, -21.9203, -46.4615])
    expected_y = np.array([4.9641, 12.6471, 34.6482, 39.5263])
    np.testing.assert_almost_equal(rotated_x, expected_x, decimal=3)
    np.testing.assert_almost_equal(rotated_y, expected_y, decimal=3)
Ejemplo n.º 2
0
def gen_map(k):
    global t, index, cs, qv, tl, timeobj
    tindex = t[index]
    if cs is not None:
        cs.remove()
        qv.remove()
    time_str = timeobj.time_str(tindex)
    tl.set_text(time_str)
    mscale = 1
    vscale = 15
    scale = 0.04
    lon_data = lons
    lat_data = lats

    print(tindex)
    print(time_str)
    u_rot, v_rot = interpolated_velocities(sgrid, points, ind, timeobj, tindex, sgrid.u, sgrid.v)
    u_rot, v_rot = rotate_vectors(u_rot, v_rot, angles)
    u_rot = u_rot.reshape(600, -1)
    v_rot = v_rot.reshape(600, -1)

    uv_vector_sum = vector_sum(u_rot, v_rot)

    kw = dict(scale=1.0 / scale, pivot='middle', width=0.003, color='black')
    cs = plt.pcolormesh(lon_data[::mscale, ::mscale],
                        lat_data[::mscale, ::mscale],
                        uv_vector_sum[::mscale, ::mscale], zorder=1, cmap=plt.cm.rainbow)
    qv = plt.quiver(lon_data[::vscale, ::vscale], lat_data[::vscale, ::vscale],
                    u_rot[::vscale, ::vscale], v_rot[::vscale, ::vscale], zorder=2, **kw)
    index += 1
    return cs, qv, tl
Ejemplo n.º 3
0
def gen_map(k):
    global t, index, cs, qv, tl, timeobj
    tindex = t[index]
    if cs is not None:
        cs.remove()
        qv.remove()
    time_str = timeobj.time_str(tindex)
    tl.set_text(time_str)
    mscale = 1
    vscale = 15
    scale = 0.04
    lon_data = lons
    lat_data = lats

    print tindex
    print time_str
    u_rot, v_rot = interpolated_velocities(sgrid, points, ind, timeobj, tindex, sgrid.u, sgrid.v)
    u_rot, v_rot = rotate_vectors(u_rot, v_rot, angles)
    u_rot = u_rot.reshape(600, -1)
    v_rot = v_rot.reshape(600, -1)

    uv_vector_sum = vector_sum(u_rot, v_rot)

    kw = dict(scale=1.0 / scale, pivot='middle', width=0.003, color='black')
    cs = plt.pcolormesh(lon_data[::mscale, ::mscale],
                        lat_data[::mscale, ::mscale],
                        uv_vector_sum[::mscale, ::mscale], zorder=1, cmap=plt.cm.rainbow)
    qv = plt.quiver(lon_data[::vscale, ::vscale], lat_data[::vscale, ::vscale],
                    u_rot[::vscale, ::vscale], v_rot[::vscale, ::vscale], zorder=2, **kw)
    index += 1
    return cs, qv, tl
Ejemplo n.º 4
0
def f(time):
    '''
    time: float index
    '''
    vels = interpolated_velocities(
        sgrid,
        points,
        timeobj,
        time,
        sgrid.u,
        sgrid.v,
        # u_alphas,
        # v_alphas,
        # u_ind,
        # v_ind,
    )

    u_rot = vels[:, 0]
    v_rot = vels[:, 1]
    u_rot, v_rot = rotate_vectors(u_rot, v_rot, angles)
    u_rot = u_rot.reshape(600, -1)
    v_rot = v_rot.reshape(600, -1)

    uv_vector_sum = vector_sum(u_rot, v_rot)
    return uv_vector_sum
Ejemplo n.º 5
0
def test_vector_rotation_complex():
    x, y, angles_simple, angles_complex = rotate_vectors_data()
    rotated_x, rotated_y = rotate_vectors(x, y, angles_complex)
    expected_x = np.array([0.5981, -3.0083, -21.9203, -46.4615])
    expected_y = np.array([4.9641, 12.6471, 34.6482, 39.5263])
    np.testing.assert_almost_equal(rotated_x, expected_x, decimal=3)
    np.testing.assert_almost_equal(rotated_y, expected_y, decimal=3)
Ejemplo n.º 6
0
def test_vector_rotation_simple():
    x, y, angles_simple, angles_complex = rotate_vectors_data()
    rotated_x, rotated_y = rotate_vectors(x, y, angles_simple)

    expected_x = np.array([3, -12, 9, -60])
    expected_y = np.array([4, 5, 40, 11])

    np.testing.assert_almost_equal(rotated_x, expected_x, decimal=3)
    np.testing.assert_almost_equal(rotated_y, expected_y, decimal=3)
Ejemplo n.º 7
0
def test_vector_rotation_simple():
    x, y, angles_simple, angles_complex = rotate_vectors_data()
    rotated_x, rotated_y = rotate_vectors(x, y, angles_simple)

    expected_x = np.array([3, -12, 9, -60])
    expected_y = np.array([4, 5, 40, 11])

    np.testing.assert_almost_equal(rotated_x, expected_x, decimal=3)
    np.testing.assert_almost_equal(rotated_y, expected_y, decimal=3)
Ejemplo n.º 8
0
def f(time):
    '''
    time: float index
    '''
    vels = interpolated_velocities(
        sgrid, points, timeobj, time, sgrid.u, sgrid.v, u_alphas, v_alphas, u_ind, v_ind)

    u_rot = vels[:, 0]
    v_rot = vels[:, 1]
    u_rot, v_rot = rotate_vectors(u_rot, v_rot, angles)
    u_rot = u_rot.reshape(600, -1)
    v_rot = v_rot.reshape(600, -1)

    uv_vector_sum = vector_sum(u_rot, v_rot)
    return uv_vector_sum
Ejemplo n.º 9
0
# In[6]:

from pysgrid.processing_2d import avg_to_cell_center

u = avg_to_cell_center(u, sgrid.u.center_axis)
v = avg_to_cell_center(v, sgrid.v.center_axis)


# - rotate_vectors

# In[7]:

from pysgrid.processing_2d import rotate_vectors

angles = nc.variables[sgrid.angle.variable][sgrid.angle.center_slicing]
u, v = rotate_vectors(u, v, angles)


# - vector_sum

# In[8]:

from pysgrid.processing_2d import vector_sum

speed = vector_sum(u, v)


# We need to get the grid cell centers before plotting.
# A high level object could use pysgrid's API to get the cell centers and its coordinates variable names.

# In[9]:
Ejemplo n.º 10
0
    def getmap(self, layer, request):
        time_index, time_value = self.nearest_time(layer, request.GET['time'])
        wgs84_bbox = request.GET['wgs84_bbox']

        with self.dataset() as nc:
            cached_sg = from_ncfile(self.topology_file)
            lon_name, lat_name = cached_sg.face_coordinates
            lon_obj = getattr(cached_sg, lon_name)
            lat_obj = getattr(cached_sg, lat_name)
            centers = cached_sg.centers
            lon = centers[..., 0][lon_obj.center_slicing]
            lat = centers[..., 1][lat_obj.center_slicing]

            if isinstance(layer, Layer):
                data_obj = getattr(cached_sg, layer.access_name)
                raw_var = nc.variables[layer.access_name]
                if len(raw_var.shape) == 4:
                    z_index, z_value = self.nearest_z(layer,
                                                      request.GET['elevation'])
                    raw_data = raw_var[time_index, z_index,
                                       data_obj.center_slicing[-2],
                                       data_obj.center_slicing[-1]]
                elif len(raw_var.shape) == 3:
                    raw_data = raw_var[time_index, data_obj.center_slicing[-2],
                                       data_obj.center_slicing[-1]]
                elif len(raw_var.shape) == 2:
                    raw_data = raw_var[data_obj.center_slicing]
                else:
                    raise BaseException(
                        'Unable to trim variable {0} data.'.format(
                            layer.access_name))
                # handle edge variables
                if data_obj.location is not None and 'edge' in data_obj.location:
                    raw_data = avg_to_cell_center(raw_data,
                                                  data_obj.center_axis)

                if request.GET['image_type'] == 'pcolor':
                    return mpl_handler.pcolormesh_response(lon,
                                                           lat,
                                                           data=raw_data,
                                                           request=request)
                elif request.GET['image_type'] in [
                        'filledhatches', 'hatches', 'filledcontours',
                        'contours'
                ]:
                    return mpl_handler.contouring_response(lon,
                                                           lat,
                                                           data=raw_data,
                                                           request=request)
                else:
                    raise NotImplementedError(
                        'Image type "{}" is not supported.'.format(
                            request.GET['image_type']))

            elif isinstance(layer, VirtualLayer):
                x_var = None
                y_var = None
                raw_vars = []
                for l in layer.layers:
                    data_obj = getattr(cached_sg, l.access_name)
                    raw_var = nc.variables[l.access_name]
                    raw_vars.append(raw_var)
                    if len(raw_var.shape) == 4:
                        z_index, z_value = self.nearest_z(
                            layer, request.GET['elevation'])
                        raw_data = raw_var[time_index, z_index,
                                           data_obj.center_slicing[-2],
                                           data_obj.center_slicing[-1]]
                    elif len(raw_var.shape) == 3:
                        raw_data = raw_var[time_index,
                                           data_obj.center_slicing[-2],
                                           data_obj.center_slicing[-1]]
                    elif len(raw_var.shape) == 2:
                        raw_data = raw_var[data_obj.center_slicing]
                    else:
                        raise BaseException(
                            'Unable to trim variable {0} data.'.format(
                                l.access_name))

                    raw_data = avg_to_cell_center(raw_data,
                                                  data_obj.center_axis)
                    if x_var is None:
                        if data_obj.vector_axis and data_obj.vector_axis.lower(
                        ) == 'x':
                            x_var = raw_data
                        elif data_obj.center_axis == 1:
                            x_var = raw_data

                    if y_var is None:
                        if data_obj.vector_axis and data_obj.vector_axis.lower(
                        ) == 'y':
                            y_var = raw_data
                        elif data_obj.center_axis == 0:
                            y_var = raw_data

                if x_var is None or y_var is None:
                    raise BaseException(
                        'Unable to determine x and y variables.')

                dim_lengths = [len(v.dimensions) for v in raw_vars]
                if len(list(set(dim_lengths))) != 1:
                    raise AttributeError(
                        'One or both of the specified variables has screwed up dimensions.'
                    )

                if request.GET['image_type'] == 'vectors':
                    angles = cached_sg.angles[lon_obj.center_slicing]
                    vectorstep = request.GET['vectorstep']
                    # don't do this if the vectorstep is 1; let's save a microsecond or two
                    # it's identical to getting all the data
                    if vectorstep > 1:
                        data_dim = len(lon.shape)
                        step_slice = (
                            np.s_[::vectorstep],
                        ) * data_dim  # make sure the vector step is used for all applicable dimensions
                        lon = lon[step_slice]
                        lat = lat[step_slice]
                        x_var = x_var[step_slice]
                        y_var = y_var[step_slice]
                        angles = angles[step_slice]
                    vectorscale = request.GET['vectorscale']
                    padding_factor = calc_safety_factor(vectorscale)
                    # figure out the average distance between lat/lon points
                    # do the math after taking into the vectorstep if specified
                    spatial_idx_padding = calc_lon_lat_padding(
                        lon, lat, padding_factor)
                    spatial_idx = data_handler.lat_lon_subset_idx(
                        lon,
                        lat,
                        lonmin=wgs84_bbox.minx,
                        latmin=wgs84_bbox.miny,
                        lonmax=wgs84_bbox.maxx,
                        latmax=wgs84_bbox.maxy,
                        padding=spatial_idx_padding)
                    subset_lon = self._spatial_data_subset(lon, spatial_idx)
                    subset_lat = self._spatial_data_subset(lat, spatial_idx)
                    # rotate vectors
                    x_rot, y_rot = rotate_vectors(x_var, y_var, angles)
                    spatial_subset_x_rot = self._spatial_data_subset(
                        x_rot, spatial_idx)
                    spatial_subset_y_rot = self._spatial_data_subset(
                        y_rot, spatial_idx)
                    return mpl_handler.quiver_response(subset_lon, subset_lat,
                                                       spatial_subset_x_rot,
                                                       spatial_subset_y_rot,
                                                       request, vectorscale)
                else:
                    raise NotImplementedError(
                        'Image type "{}" is not supported.'.format(
                            request.GET['image_type']))
Ejemplo n.º 11
0
#     points, sgrid.u, slices=[time_idx, v_idx])
interp_u = sgrid.interpolate_var_to_points(points,
                                           sgrid.u[time_idx, v_idx],
                                           slices=None)
interp_v = sgrid.interpolate_var_to_points(points,
                                           sgrid.v,
                                           slices=[time_idx, v_idx])

# rotation is still ugly...
from pysgrid.processing_2d import rotate_vectors, vector_sum
from pysgrid.processing_2d import vector_sum

ind = sgrid.locate_faces(points)
ang_ind = ind + [1, 1]
angles = sgrid.angles[:][ang_ind[:, 0], ang_ind[:, 1]]
u_rot, v_rot = rotate_vectors(interp_u, interp_v, angles)
u_rot = u_rot.reshape(600, -1)
v_rot = v_rot.reshape(600, -1)

uv_vector_sum = vector_sum(u_rot, v_rot)

import numpy as np
import matplotlib.pyplot as plt

import cartopy.crs as ccrs
from cartopy.io import shapereader
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER


def make_map(projection=ccrs.PlateCarree(), figsize=(20, 20)):
    fig, ax = plt.subplots(figsize=figsize,
Ejemplo n.º 12
0
    def getmap(self, layer, request):
        time_index, time_value = self.nearest_time(layer, request.GET['time'])
        wgs84_bbox = request.GET['wgs84_bbox']

        with self.dataset() as nc:
            cached_sg = from_ncfile(self.topology_file)
            lon_name, lat_name = cached_sg.face_coordinates
            lon_obj = getattr(cached_sg, lon_name)
            lat_obj = getattr(cached_sg, lat_name)
            centers = cached_sg.centers
            lon = centers[..., 0][lon_obj.center_slicing]
            lat = centers[..., 1][lat_obj.center_slicing]
            if request.GET['image_type'] == 'vectors':
                vectorstep = request.GET['vectorstep']
                vectorscale = request.GET['vectorscale']
                padding_factor = calc_safety_factor(vectorscale)
                spatial_idx_padding = calc_lon_lat_padding(lon, lat, padding_factor)
            else:
                spatial_idx_padding = 0.18
                vectorstep = None
            spatial_idx = data_handler.lat_lon_subset_idx(lon, lat,
                                                          lonmin=wgs84_bbox.minx,
                                                          latmin=wgs84_bbox.miny,
                                                          lonmax=wgs84_bbox.maxx,
                                                          latmax=wgs84_bbox.maxy,
                                                          padding=spatial_idx_padding
                                                         )
            subset_x = np.unique(spatial_idx[0])
            subset_y = np.unique(spatial_idx[1])
            if subset_x.shape == (0, ) and subset_y.shape == (0, ):
                return mpl_handler.empty_response()  # return an empty tile if subset contains no data
            else:
                x_min_idx = subset_x.min()
                x_max_idx = subset_x.max() + 1
                y_min_idx = subset_y.min()
                y_max_idx = subset_y.max() + 1
                lonlat_mask = np.ones(lon.shape)
                lonlat_mask[spatial_idx[0], spatial_idx[1]] = 0
                trimmed_lon = ma.masked_array(lon, mask=lonlat_mask).data[x_min_idx:x_max_idx:vectorstep, y_min_idx:y_max_idx:vectorstep]
                trimmed_lat = ma.masked_array(lat, mask=lonlat_mask).data[x_min_idx:x_max_idx:vectorstep, y_min_idx:y_max_idx:vectorstep]
                if isinstance(layer, Layer):
                    data_obj = getattr(cached_sg, layer.access_name)
                    raw_var = nc.variables[layer.access_name]
                    raw_data = self._retrieve_data(request=request,
                                                   nc_variable=raw_var,
                                                   sg_variable=data_obj,
                                                   layer=layer,
                                                   subset_x=subset_x,
                                                   subset_y=subset_y,
                                                   time_index=time_index,
                                                   vectorstep=1
                                                   )
                    # handle edge variables
                    if data_obj.location is not None and 'edge' in data_obj.location:
                        raw_data = avg_to_cell_center(raw_data, data_obj.center_axis)
                    if request.GET['image_type'] == 'pcolor':
                        return mpl_handler.pcolormesh_response(trimmed_lon, trimmed_lat, data=raw_data, request=request)
                    elif request.GET['image_type'] == 'filledcontours':
                        return mpl_handler.contourf_response(trimmed_lon, trimmed_lat, data=raw_data, request=request)
                    else:
                        raise NotImplementedError('Image type "{}" is not supported.'.format(request.GET['image_type']))
                elif isinstance(layer, VirtualLayer):
                    x_var = None
                    y_var = None
                    raw_vars = []
                    for l in layer.layers:
                        data_obj = getattr(cached_sg, l.access_name)
                        raw_var = nc.variables[l.access_name]
                        raw_vars.append(raw_var)
                        raw_data = self._retrieve_data(request=request,
                                                       nc_variable=raw_var,
                                                       sg_variable=data_obj,
                                                       layer=layer,
                                                       subset_x=subset_x,
                                                       subset_y=subset_y,
                                                       time_index=time_index,
                                                       vectorstep=vectorstep
                                                       )
                        raw_data = self._avg_to_cell_center(raw_data, data_obj.center_axis, vectorstep)
                        if x_var is None:
                            if data_obj.vector_axis and data_obj.vector_axis.lower() == 'x':
                                x_var = raw_data
                            elif data_obj.center_axis == 1:
                                x_var = raw_data
    
                        if y_var is None:
                            if data_obj.vector_axis and data_obj.vector_axis.lower() == 'y':
                                y_var = raw_data
                            elif data_obj.center_axis == 0:
                                y_var = raw_data
    
                    if x_var is None or y_var is None:
                        raise BaseException('Unable to determine x and y variables.')
    
                    dim_lengths = [ len(v.dimensions) for v in raw_vars ]
                    if len(list(set(dim_lengths))) != 1:
                        raise AttributeError('One or both of the specified variables has screwed up dimensions.')
    
                    if request.GET['image_type'] == 'vectors':
                        angles = cached_sg.angles[lon_obj.center_slicing]
                        trimmed_angles = ma.masked_array(angles, mask=lonlat_mask).data[x_min_idx:x_max_idx:vectorstep, y_min_idx:y_max_idx:vectorstep]
                        # rotate vectors
                        x_rot, y_rot = rotate_vectors(x_var, y_var, trimmed_angles)
                        return mpl_handler.quiver_response(trimmed_lon,
                                                           trimmed_lat,
                                                           x_rot,
                                                           y_rot,
                                                           request,
                                                           vectorscale
                                                           )
                    else:
                        raise NotImplementedError('Image type "{}" is not supported.'.format(request.GET['image_type']))
Ejemplo n.º 13
0
points = np.stack((lons, lats), axis=-1)

print(points.shape)
time_idx = 0
v_idx = 0

interp_u = sgrid.interpolate_var_to_points(
    points, sgrid.u[time_idx, v_idx], slices=None)
interp_v = sgrid.interpolate_var_to_points(
    points, sgrid.v, slices=[time_idx, v_idx])

ind = sgrid.locate_faces(points)
ang_ind = ind + [1, 1]
angles = sgrid.angles[:][ang_ind[:, 0], ang_ind[:, 1]]
u_rot, v_rot = rotate_vectors(interp_u, interp_v, angles)
u_rot = u_rot.reshape(600, -1)
v_rot = v_rot.reshape(600, -1)

uv_vector_sum = vector_sum(u_rot, v_rot)


def make_map(projection=ccrs.PlateCarree(), figsize=(20, 20)):
    fig, ax = plt.subplots(figsize=figsize,
                           subplot_kw=dict(projection=projection))
    gl = ax.gridlines(draw_labels=True)
    gl.xlabels_top = gl.ylabels_right = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    return fig, ax
Ejemplo n.º 14
0
# <codecell>

from pysgrid.processing_2d import avg_to_cell_center

u_avg = avg_to_cell_center(u_data, u_var.center_axis)
v_avg = avg_to_cell_center(v_data, v_var.center_axis)

# <markdowncell>

# ### Rotate vectors by angles

# <codecell>

from pysgrid.processing_2d import rotate_vectors

u_rot, v_rot = rotate_vectors(u_avg, v_avg, angles)

# <markdowncell>

# ### Speed

# <codecell>

from pysgrid.processing_2d import vector_sum

uv_vector_sum = vector_sum(u_rot, v_rot)

# <markdowncell>

# ### Lon, lat of the center grid
# 
Ejemplo n.º 15
0
u_velocity = nc.variables[u_var.variable]
v_velocity = nc.variables[v_var.variable]

v_idx = 0  # surface
time_idx = -1  # Last time step.

u = u_velocity[time_idx, v_idx, u_var.center_slicing[-2], u_var.center_slicing[-1]]
v = v_velocity[time_idx, v_idx, v_var.center_slicing[-2], v_var.center_slicing[-1]]


u = avg_to_cell_center(u, u_var.center_axis)
v = avg_to_cell_center(v, v_var.center_axis)


angles = nc.variables[sgrid.angle.variable][sgrid.angle.center_slicing]
u, v = rotate_vectors(u, v, angles)


speed = vector_sum(u, v)

\*\* CF convention does describe the angle variable for grids that needs rotation, but there is no action expected. For example, in the formula_terms, pysgrid must be improved to abstract that action when needed via a simpler method.

```xml
<entry id="angle_of_rotation_from_east_to_x">
    <canonical_units>degree</canonical_units>
    <grib></grib>
    <amip></amip>
    <description>The quantity with standard name angle_of_rotation_from_east_to_x is the angle, anticlockwise reckoned positive, between due East and (dr/di)jk, where r(i,j,k) is the vector 3D position of the point with coordinate indices (i,j,k).  It could be used for rotating vector fields between model space and latitude-longitude space.</description>
</entry>
```
Ejemplo n.º 16
0
 cached_var2 = getattr(cached_sg, var2_name)
 raw_var1 = canon_dataset.variables[var1_name]
 raw_var2 = canon_dataset.variables[var2_name]
 vertical_index, vertical = nearest_z(raw_var1, canon_dataset, z)
 print('Vertical: {0}'.format(vertical))
 var1_trimmed = raw_var1[time_idx, vertical_index, cached_var1.center_slicing[2], cached_var1.center_slicing[3]]
 var2_trimmed = raw_var2[time_idx, vertical_index, cached_var2.center_slicing[2], cached_var2.center_slicing[3]]
 var1_avg = avg_to_cell_center(var1_trimmed, cached_var1.center_axis)
 var2_avg = avg_to_cell_center(var2_trimmed, cached_var2.center_axis)
 if cached_var1.center_axis == 1 and cached_var2.center_axis == 0:
     x_var = var1_avg
     y_var = var2_avg
 else:
     x_var = var2_avg
     y_var = var1_avg
 x_rot, y_rot = rotate_vectors(x_var, y_var, angles)
 subset_x_rot = subset_data(x_rot, subset_idx)
 subset_y_rot = subset_data(y_rot, subset_idx)
 xy_vector_sum = vector_sum(subset_x_rot, subset_y_rot)
 # start experimental quiver_response section
 
 # end experimental quiver_response section
 
 fig = plt.figure(figsize=(12, 12))
 plt.subplot(111, aspect=(1.0/np.cos(np.mean(subset_lat)*np.pi/180.0)))
 q = plt.quiver(subset_lon[::SUB], 
                subset_lat[::SUB], 
                subset_x_rot[::SUB], 
                subset_y_rot[::SUB],
                xy_vector_sum[::SUB],
                scale=1.0/SCALE, 
s = from_nc_dataset(ds) 
u_var = s.u
v_var = s.v
u_velocity = ds.variables['u']
v_velocity = ds.variables['v']
u_data = u_velocity[TIME_INDEX, VERTICAL_INDEX, u_var.center_slicing[2], u_var.center_slicing[3]]
v_data = v_velocity[TIME_INDEX, VERTICAL_INDEX, v_var.center_slicing[2], v_var.center_slicing[3]]
angle_var = s.angle
angle_data = s.angles
angle_data_trimed = angle_data[angle_var.center_slicing]

u_avg = avg_to_cell_center(u_data, u_var.center_axis)
v_avg = avg_to_cell_center(v_data, v_var.center_axis)

u_rot, v_rot = rotate_vectors(u_avg, v_avg, angle_data_trimed)
uv_vector_sum = vector_sum(u_rot, v_rot)

cell_centers = s.centers
lon_var, lat_var = s.face_coordinates
lon_obj = getattr(s, lon_var)
lat_obj = getattr(s, lat_var)
lon_data = cell_centers[:, :, 0]
lat_data = cell_centers[:, :, 1]
lon_subset = lon_data[lon_obj.center_slicing]
lat_subset = lat_data[lat_obj.center_slicing]

fig = plt.figure(figsize=(12, 12))
plt.subplot(111, aspect=(1.0/np.cos(np.mean(lat_subset)*np.pi/180.0)))
q = plt.quiver(lon_subset[::SUB, ::SUB], 
               lat_subset[::SUB, ::SUB], 
Ejemplo n.º 18
0
    def getmap(self, layer, request):
        time_index, time_value = self.nearest_time(layer, request.GET['time'])
        wgs84_bbox = request.GET['wgs84_bbox']

        with self.dataset() as nc:
            cached_sg = from_ncfile(self.topology_file)
            lon_name, lat_name = cached_sg.face_coordinates
            lon_obj = getattr(cached_sg, lon_name)
            lat_obj = getattr(cached_sg, lat_name)
            centers = cached_sg.centers
            lon = centers[..., 0][lon_obj.center_slicing]
            lat = centers[..., 1][lat_obj.center_slicing]

            if isinstance(layer, Layer):
                data_obj = getattr(cached_sg, layer.access_name)
                raw_var = nc.variables[layer.access_name]
                if len(raw_var.shape) == 4:
                    z_index, z_value = self.nearest_z(layer, request.GET['elevation'])
                    raw_data = raw_var[time_index, z_index, data_obj.center_slicing[-2], data_obj.center_slicing[-1]]
                elif len(raw_var.shape) == 3:
                    raw_data = raw_var[time_index, data_obj.center_slicing[-2], data_obj.center_slicing[-1]]
                elif len(raw_var.shape) == 2:
                    raw_data = raw_var[data_obj.center_slicing]
                else:
                    raise BaseException('Unable to trim variable {0} data.'.format(layer.access_name))
                # handle edge variables
                if data_obj.location is not None and 'edge' in data_obj.location:
                    raw_data = avg_to_cell_center(raw_data, data_obj.center_axis)

                if request.GET['image_type'] == 'pcolor':
                    return mpl_handler.pcolormesh_response(lon, lat, data=raw_data, request=request)
                elif request.GET['image_type'] == 'filledcontours':
                    return mpl_handler.contourf_response(lon, lat, data=raw_data, request=request)
                else:
                    raise NotImplementedError('Image type "{}" is not supported.'.format(request.GET['image_type']))

            elif isinstance(layer, VirtualLayer):
                x_var = None
                y_var = None
                raw_vars = []
                for l in layer.layers:
                    data_obj = getattr(cached_sg, l.access_name)
                    raw_var = nc.variables[l.access_name]
                    raw_vars.append(raw_var)
                    if len(raw_var.shape) == 4:
                        z_index, z_value = self.nearest_z(layer, request.GET['elevation'])
                        raw_data = raw_var[time_index, z_index, data_obj.center_slicing[-2], data_obj.center_slicing[-1]]
                    elif len(raw_var.shape) == 3:
                        raw_data = raw_var[time_index, data_obj.center_slicing[-2], data_obj.center_slicing[-1]]
                    elif len(raw_var.shape) == 2:
                        raw_data = raw_var[data_obj.center_slicing]
                    else:
                        raise BaseException('Unable to trim variable {0} data.'.format(l.access_name))

                    raw_data = avg_to_cell_center(raw_data, data_obj.center_axis)
                    if x_var is None:
                        if data_obj.vector_axis and data_obj.vector_axis.lower() == 'x':
                            x_var = raw_data
                        elif data_obj.center_axis == 1:
                            x_var = raw_data

                    if y_var is None:
                        if data_obj.vector_axis and data_obj.vector_axis.lower() == 'y':
                            y_var = raw_data
                        elif data_obj.center_axis == 0:
                            y_var = raw_data

                if x_var is None or y_var is None:
                    raise BaseException('Unable to determine x and y variables.')

                dim_lengths = [ len(v.dimensions) for v in raw_vars ]
                if len(list(set(dim_lengths))) != 1:
                    raise AttributeError('One or both of the specified variables has screwed up dimensions.')

                if request.GET['image_type'] == 'vectors':
                    angles = cached_sg.angles[lon_obj.center_slicing]
                    vectorstep = request.GET['vectorstep']
                    # don't do this if the vectorstep is 1; let's save a microsecond or two
                    # it's identical to getting all the data
                    if vectorstep > 1:
                        data_dim = len(lon.shape)
                        step_slice = (np.s_[::vectorstep],) * data_dim  # make sure the vector step is used for all applicable dimensions
                        lon = lon[step_slice]
                        lat = lat[step_slice]
                        x_var = x_var[step_slice]
                        y_var = y_var[step_slice]
                        angles = angles[step_slice]
                    vectorscale = request.GET['vectorscale']
                    padding_factor = calc_safety_factor(vectorscale)
                    # figure out the average distance between lat/lon points
                    # do the math after taking into the vectorstep if specified
                    spatial_idx_padding = calc_lon_lat_padding(lon, lat, padding_factor)
                    spatial_idx = data_handler.lat_lon_subset_idx(lon, lat,
                                                                  lonmin=wgs84_bbox.minx,
                                                                  latmin=wgs84_bbox.miny,
                                                                  lonmax=wgs84_bbox.maxx,
                                                                  latmax=wgs84_bbox.maxy,
                                                                  padding=spatial_idx_padding
                                                                  )
                    subset_lon = self._spatial_data_subset(lon, spatial_idx)
                    subset_lat = self._spatial_data_subset(lat, spatial_idx)
                    # rotate vectors
                    x_rot, y_rot = rotate_vectors(x_var, y_var, angles)
                    spatial_subset_x_rot = self._spatial_data_subset(x_rot, spatial_idx)
                    spatial_subset_y_rot = self._spatial_data_subset(y_rot, spatial_idx)
                    return mpl_handler.quiver_response(subset_lon,
                                                       subset_lat,
                                                       spatial_subset_x_rot,
                                                       spatial_subset_y_rot,
                                                       request,
                                                       vectorscale
                                                       )
                else:
                    raise NotImplementedError('Image type "{}" is not supported.'.format(request.GET['image_type']))
cell_centers = sg.centers
lon_var_name, lat_var_name = sg.face_coordinates
lon_data = cell_centers[:, :, 0]
lat_data = cell_centers[:, :, 1]
lon_var_obj = getattr(sg, lon_var_name)
lat_var_obj = getattr(sg, lat_var_name)
lon_subset = lon_data[lon_var_obj.center_slicing]
lat_subset = lat_data[lat_var_obj.center_slicing]
angles = sg.angles[lon_var_obj.center_slicing]

u_data_trimmed = u_var[TIME_INDEX, VERTICAL_INDEX, sg_u.center_slicing[2], sg_u.center_slicing[3]]
v_data_trimmed = v_var[TIME_INDEX, VERTICAL_INDEX, sg_v.center_slicing[2], sg_v.center_slicing[3]]
u_data_avg = avg_to_cell_center(u_data_trimmed, sg_u.center_axis)
v_data_avg = avg_to_cell_center(v_data_trimmed, sg_v.center_axis)
u_rotated, v_rotated = rotate_vectors(u_data_avg, v_data_avg, angles)
uv_vector_sum = vector_sum(u_rotated, v_rotated)

fig = plt.figure(figsize=(12, 12))
plt.subplot(111, aspect=(1.0/np.cos(np.mean(lat_subset)*np.pi/180.0)))
q = plt.quiver(lon_subset[::SUB, ::SUB], 
               lat_subset[::SUB, ::SUB], 
               u_rotated[::SUB, ::SUB], 
               v_rotated[::SUB, ::SUB],
               uv_vector_sum[::SUB, ::SUB],
               scale=1.0/SCALE, 
               pivot='middle', 
               zorder=1e35, 
               width=0.003
              )