Example #1
0
def main():
    # Enable a future option, to ensure that the netcdf load works the same way
    # as in future Iris versions.
    iris.FUTURE.netcdf_promote = True

    # Load some test data.
    fname = iris.sample_data_path('A1B_north_america.nc')
    cube = iris.load_cube(fname)

    # Extract a single time series at a latitude and longitude point.
    location = next(cube.slices(['time']))

    # Calculate a polynomial fit to the data at this time series.
    x_points = location.coord('time').points
    y_points = location.data
    degree = 2

    p = np.polyfit(x_points, y_points, degree)
    y_fitted = np.polyval(p, x_points)

    # Add the polynomial fit values to the time series to take
    # full advantage of Iris plotting functionality.
    long_name = 'degree_{}_polynomial_fit_of_{}'.format(degree, cube.name())
    fit = iris.coords.AuxCoord(y_fitted, long_name=long_name,
                               units=location.units)
    location.add_aux_coord(fit, 0)

    qplt.plot(location.coord('time'), location, label='data')
    qplt.plot(location.coord('time'),
              location.coord(long_name),
              'g-', label='polynomial fit')
    plt.legend(loc='best')
    plt.title('Trend of US air temperature over time')

    qplt.show()
Example #2
0
def runme():

    # Load a cube into Iris
    filename = iris.sample_data_path("A1B.2098.pp")
    cube = iris.load_cube(filename)
    cube.coord(axis="x").guess_bounds()
    cube.coord(axis="y").guess_bounds()

    # Plot the cube with Iris, just to see it.
    qplt.contourf(cube)
    qplt.plt.gca().coastlines()
    qplt.show()

    # Export as GeoTIFF (shouldn't have to write to a physical file)
    iris.experimental.raster.export_geotiff(cube, 'temp.geotiff')
    data = open('temp.geotiff', "rb").read()

    # Publish to geoserver
    server = "localhost:8082"
    username, password = '******', 'geoserver'
    connect_to_server(server, username, password)

    workspace = "iris_test_ws"
    if not exists_workspace(server, workspace):
        create_workspace(server, workspace)

    coveragestore = "iris_test_cs"
    if not exists_coveragestore(server, workspace, coveragestore):
        create_coveragestore(server, workspace, coveragestore)

    filename = "file.geotiff"
    upload_file(server, workspace, coveragestore, filename, data)

    # Tell geoserver it's global EPSG:4326. Shouldn't need this eventually.
    coverage = coveragestore  # (they get the same name from geoserver)
    data = '<coverage>'\
                '<srs>EPSG:4326</srs>'\
                '<nativeCRS>EPSG:4326</nativeCRS>'\
                ' <nativeBoundingBox>'\
                    '<minx>-180.0</minx>'\
                    '<maxx>180.0</maxx>'\
                    '<miny>-90.0</miny>'\
                    '<maxy>90.0</maxy>'\
                    '<crs>EPSG:4326</crs>'\
                '</nativeBoundingBox>'\
                '<enabled>true</enabled>'\
            '</coverage>'
    update_coverage(server, workspace, coveragestore, coverage, data)

    # Use the new WMS service as a background image!
    wms_server = '{server}/{workspace}/wms?service=WMS'.format(
        server=server, workspace=workspace)
    layers = '{workspace}:{coveragestore}'.format(workspace=workspace,
                                                  coveragestore=coveragestore)

    plt.axes(projection=ccrs.PlateCarree())
    plt.gca().set_extent([-40, 40, 20, 80])
    wms_image(wms_server, layers)
    plt.gca().coastlines()
    plt.show()
Example #3
0
def main():
    # Load some test data.
    fname = iris.sample_data_path("A1B_north_america.nc")
    cube = iris.load_cube(fname)

    # Extract a single time series at a latitude and longitude point.
    location = next(cube.slices(["time"]))

    # Calculate a polynomial fit to the data at this time series.
    x_points = location.coord("time").points
    y_points = location.data
    degree = 2

    p = np.polyfit(x_points, y_points, degree)
    y_fitted = np.polyval(p, x_points)

    # Add the polynomial fit values to the time series to take
    # full advantage of Iris plotting functionality.
    long_name = "degree_{}_polynomial_fit_of_{}".format(degree, cube.name())
    fit = iris.coords.AuxCoord(y_fitted,
                               long_name=long_name,
                               units=location.units)
    location.add_aux_coord(fit, 0)

    qplt.plot(location.coord("time"), location, label="data")
    qplt.plot(
        location.coord("time"),
        location.coord(long_name),
        "g-",
        label="polynomial fit",
    )
    plt.legend(loc="best")
    plt.title("Trend of US air temperature over time")

    qplt.show()
Example #4
0
def main():
    # Load the u and v components of wind from a pp file
    infile = iris.sample_data_path("wind_speed_lake_victoria.pp")

    uwind = iris.load_cube(infile, "x_wind")
    vwind = iris.load_cube(infile, "y_wind")

    ulon = uwind.coord("longitude")
    vlon = vwind.coord("longitude")

    # The longitude points go from 180 to 540, so subtract 360 from them
    ulon.points = ulon.points - 360.0
    vlon.points = vlon.points - 360.0

    # Create a cube containing the wind speed
    windspeed = (uwind**2 + vwind**2)**0.5
    windspeed.rename("windspeed")

    x = ulon.points
    y = uwind.coord("latitude").points
    u = uwind.data
    v = vwind.data

    # Set up axes to show the lake
    lakes = cfeat.NaturalEarthFeature("physical",
                                      "lakes",
                                      "50m",
                                      facecolor="none")

    plt.figure()
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.add_feature(lakes)

    # Get the coordinate reference system used by the data
    transform = ulon.coord_system.as_cartopy_projection()

    # Plot the wind speed as a contour plot
    qplt.contourf(windspeed, 20)

    # Add arrows to show the wind vectors
    plt.quiver(x, y, u, v, pivot="middle", transform=transform)

    plt.title("Wind speed over Lake Victoria")
    qplt.show()

    # Normalise the data for uniform arrow size
    u_norm = u / np.sqrt(u**2.0 + v**2.0)
    v_norm = v / np.sqrt(u**2.0 + v**2.0)

    plt.figure()
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.add_feature(lakes)

    qplt.contourf(windspeed, 20)

    plt.quiver(x, y, u_norm, v_norm, pivot="middle", transform=transform)

    plt.title("Wind speed over Lake Victoria")
    qplt.show()
Example #5
0
def runme():

    # Load a cube into Iris
    filename = iris.sample_data_path("A1B.2098.pp")
    cube = iris.load_cube(filename)
    cube.coord(axis="x").guess_bounds()
    cube.coord(axis="y").guess_bounds()

    # Plot the cube with Iris, just to see it.
    qplt.contourf(cube)
    qplt.plt.gca().coastlines()
    qplt.show()
    
    # Export as GeoTIFF (shouldn't have to write to a physical file)
    iris.experimental.raster.export_geotiff(cube, 'temp.geotiff')
    data = open('temp.geotiff', "rb").read()

    # Publish to geoserver
    server = "localhost:8082"
    username, password = '******', 'geoserver'
    connect_to_server(server, username, password)

    workspace = "iris_test_ws"
    if not exists_workspace(server, workspace):
        create_workspace(server, workspace)
    
    coveragestore = "iris_test_cs"
    if not exists_coveragestore(server, workspace, coveragestore):
        create_coveragestore(server, workspace, coveragestore)

    filename = "file.geotiff"
    upload_file(server, workspace, coveragestore, filename, data)
    
    # Tell geoserver it's global EPSG:4326. Shouldn't need this eventually.
    coverage = coveragestore  # (they get the same name from geoserver)
    data = '<coverage>'\
                '<srs>EPSG:4326</srs>'\
                '<nativeCRS>EPSG:4326</nativeCRS>'\
                ' <nativeBoundingBox>'\
                    '<minx>-180.0</minx>'\
                    '<maxx>180.0</maxx>'\
                    '<miny>-90.0</miny>'\
                    '<maxy>90.0</maxy>'\
                    '<crs>EPSG:4326</crs>'\
                '</nativeBoundingBox>'\
                '<enabled>true</enabled>'\
            '</coverage>'
    update_coverage(server, workspace, coveragestore, coverage, data)

    # Use the new WMS service as a background image!
    wms_server = '{server}/{workspace}/wms?service=WMS'.format(server=server, workspace=workspace)
    layers = '{workspace}:{coveragestore}'.format(workspace=workspace, coveragestore=coveragestore)
    
    plt.axes(projection=ccrs.PlateCarree())
    plt.gca().set_extent([-40, 40, 20, 80])
    wms_image(wms_server, layers)
    plt.gca().coastlines()
    plt.show()
Example #6
0
def main():
    # Load the u and v components of wind from a pp file
    infile = iris.sample_data_path('wind_speed_lake_victoria.pp')

    uwind = iris.load_cube(infile, 'x_wind')
    vwind = iris.load_cube(infile, 'y_wind')

    ulon = uwind.coord('longitude')
    vlon = vwind.coord('longitude')

    # The longitude points go from 180 to 540, so subtract 360 from them
    ulon.points = ulon.points - 360.0
    vlon.points = vlon.points - 360.0

    # Create a cube containing the wind speed
    windspeed = (uwind ** 2 + vwind ** 2) ** 0.5
    windspeed.rename('windspeed')

    x = ulon.points
    y = uwind.coord('latitude').points
    u = uwind.data
    v = vwind.data

    # Set up axes to show the lake
    lakes = cfeat.NaturalEarthFeature('physical', 'lakes', '50m',
                                      facecolor='none')

    plt.figure()
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.add_feature(lakes)

    # Get the coordinate reference system used by the data
    transform = ulon.coord_system.as_cartopy_projection()

    # Plot the wind speed as a contour plot
    qplt.contourf(windspeed, 20)

    # Add arrows to show the wind vectors
    plt.quiver(x, y, u, v, pivot='middle', transform=transform)

    plt.title("Wind speed over Lake Victoria")
    qplt.show()

    # Normalise the data for uniform arrow size
    u_norm = u / np.sqrt(u ** 2.0 + v ** 2.0)
    v_norm = v / np.sqrt(u ** 2.0 + v ** 2.0)

    plt.figure()
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.add_feature(lakes)

    qplt.contourf(windspeed, 20)

    plt.quiver(x, y, u_norm, v_norm, pivot='middle', transform=transform)

    plt.title("Wind speed over Lake Victoria")
    qplt.show()
def test_single_boxcar(target_point, tmpfile, source_data_function):
    '''Smooth a single point'''
    
    import iris.quickplot as qplt, matplotlib.pyplot as plt
    from gridsmoother import GridSmoother
    
    import os

    #lat,lon = target_point

    dlat = 180. / 1#CUBE_SHAPE[0]
    dlon = 360. / 1#CUBE_SHAPE[1]

    print "point lat = %s, lon = %s" % target_point

    assert int(target_point[0] / dlat) - target_point[0] / dlat < SMALL_NUMBER
    assert int(target_point[1] / dlon) - target_point[1] / dlon < SMALL_NUMBER
    
    print "dlat = %s, dlon = %s" % (dlat, dlon)
    
    #centre = (lat,lon)#(dlat / 2., dlon / 2.)
    source_cube = gen_or_load_2D(tmpfile , [source_data_function], ["unsmoothed data"], {"GS_centre_lat":target_point[0], 'GS_centre_lon':target_point[1]},nlat=180, nlon=360)[0]
    
    lat_width = 6.
    lon_width = 18.
    
    print "box car parameters: lat_width %s, lon_width %s" % (lat_width, lon_width)
    
    gs = GridSmoother()
    filename= "boxcar_%s_x_%s.json.gz" % (lon_width,lat_width)
    if os.path.exists(filename):
        gs.load(filename)
    else:
        gs.build_boxcar_lat_lon(source_cube, lat_width, lon_width)
        gs.save(filename)
    
    smoothed_cube = gs.smooth_2d_cube(source_cube)
               
    if PLOT:
        import cartopy.crs as ccrs
        fig = plt.figure()
        subpl = fig.add_subplot(111, projection=ccrs.PlateCarree())
    
        qplt.pcolormesh(smoothed_cube, cmap='Reds')
        qplt.outline(smoothed_cube)
#        subpl.add_artist(plt.Circle(target_point, smoothing_width, edgecolor='blue', facecolor='none', transform=ccrs.PlateCarree()))
        
        for i, lat in enumerate(smoothed_cube.coord('latitude').points):
            for j, lon in enumerate(smoothed_cube.coord('longitude').points):
                if smoothed_cube.data[i, j] > 0:
                    plt.text(lon, lat, smoothed_cube.data[i, j] ** -1, transform=ccrs.PlateCarree(), ha='center', va='center')
        
        qplt.plt.gca().coastlines()
        qplt.show()
Example #8
0
def main():
    cube1 = iris.load_cube(iris.sample_data_path("ostia_monthly.nc"))
    # Slice into cube to retrieve data for the inset map showing the
    # data region
    region = cube1[-1, :, :]
    # Average over latitude to reduce cube to 1 dimension
    plot_line = region.collapsed("latitude", iris.analysis.MEAN)

    # Open a window for plotting
    fig = plt.figure()
    # Add a single subplot (axes). Could also use "ax_main = plt.subplot()"
    ax_main = fig.add_subplot(1, 1, 1)
    # Produce a quick plot of the 1D cube
    qplt.plot(plot_line)

    # Set x limits to match the data
    ax_main.set_xlim(0, plot_line.coord("longitude").points.max())
    # Adjust the y limits so that the inset map won't clash with main plot
    ax_main.set_ylim(294, 310)
    ax_main.set_title("Meridional Mean Temperature")
    # Add grid lines
    ax_main.grid()

    # Add a second set of axes specifying the fractional coordinates within
    # the figure with bottom left corner at x=0.55, y=0.58 with width
    # 0.3 and height 0.25.
    # Also specify the projection
    ax_sub = fig.add_axes(
        [0.55, 0.58, 0.3, 0.25],
        projection=ccrs.Mollweide(central_longitude=180),
    )

    # Use iris.plot (iplt) here so colour bar properties can be specified
    # Also use a sequential colour scheme to reduce confusion for those with
    # colour-blindness
    iplt.pcolormesh(region, cmap="Blues")
    # Manually set the orientation and tick marks on your colour bar
    ticklist = np.linspace(np.min(region.data), np.max(region.data), 4)
    plt.colorbar(orientation="horizontal", ticks=ticklist)
    ax_sub.set_title("Data Region")
    # Add coastlines
    ax_sub.coastlines()
    # request to show entire map, using the colour mesh on the data region only
    ax_sub.set_global()

    qplt.show()
Example #9
0
def main():
    # Load the data
    with iris.FUTURE.context(netcdf_promote=True):
        cube1 = iris.load_cube(iris.sample_data_path('ostia_monthly.nc'))
    # Slice into cube to retrieve data for the inset map showing the
    # data region
    region = cube1[-1, :, :]
    # Average over latitude to reduce cube to 1 dimension
    plot_line = region.collapsed('latitude', iris.analysis.MEAN)

    # Open a window for plotting
    fig = plt.figure()
    # Add a single subplot (axes). Could also use "ax_main = plt.subplot()"
    ax_main = fig.add_subplot(1, 1, 1)
    # Produce a quick plot of the 1D cube
    qplt.plot(plot_line)

    # Set x limits to match the data
    ax_main.set_xlim(0, plot_line.coord('longitude').points.max())
    # Adjust the y limits so that the inset map won't clash with main plot
    ax_main.set_ylim(294, 310)
    ax_main.set_title('Meridional Mean Temperature')
    # Add grid lines
    ax_main.grid()

    # Add a second set of axes specifying the fractional coordinates within
    # the figure with bottom left corner at x=0.55, y=0.58 with width
    # 0.3 and height 0.25.
    # Also specify the projection
    ax_sub = fig.add_axes([0.55, 0.58, 0.3, 0.25],
                          projection=ccrs.Mollweide(central_longitude=180))

    # Use iris.plot (iplt) here so colour bar properties can be specified
    # Also use a sequential colour scheme to reduce confusion for those with
    # colour-blindness
    iplt.pcolormesh(region, cmap='Blues')
    # Manually set the orientation and tick marks on your colour bar
    ticklist = np.linspace(np.min(region.data), np.max(region.data), 4)
    plt.colorbar(orientation='horizontal', ticks=ticklist)
    ax_sub.set_title('Data Region')
    # Add coastlines
    ax_sub.coastlines()
    # request to show entire map, using the colour mesh on the data region only
    ax_sub.set_global()

    qplt.show()
Example #10
0
def main():
    # Load the u and v components of wind from a pp file.
    infile = iris.sample_data_path("wind_speed_lake_victoria.pp")

    uwind = iris.load_cube(infile, "x_wind")
    vwind = iris.load_cube(infile, "y_wind")

    # Create a cube containing the wind speed.
    windspeed = (uwind ** 2 + vwind ** 2) ** 0.5
    windspeed.rename("windspeed")

    # Plot the wind speed as a contour plot.
    qplt.contourf(windspeed, 20)

    # Show the lake on the current axes.
    lakes = cfeat.NaturalEarthFeature(
        "physical", "lakes", "50m", facecolor="none"
    )
    plt.gca().add_feature(lakes)

    # Add arrows to show the wind vectors.
    iplt.quiver(uwind, vwind, pivot="middle")

    plt.title("Wind speed over Lake Victoria")
    qplt.show()

    # Normalise the data for uniform arrow size.
    u_norm = uwind / windspeed
    v_norm = vwind / windspeed

    # Make a new figure for the normalised plot.
    plt.figure()

    qplt.contourf(windspeed, 20)
    plt.gca().add_feature(lakes)
    iplt.quiver(u_norm, v_norm, pivot="middle")

    plt.title("Wind speed over Lake Victoria")
    qplt.show()
Example #11
0
def main():
    # Load the u and v components of wind from a pp file
    infile = iris.sample_data_path("wind_speed_lake_victoria.pp")

    uwind = iris.load_cube(infile, "x_wind")
    vwind = iris.load_cube(infile, "y_wind")

    uwind.convert_units("knot")
    vwind.convert_units("knot")

    # To illustrate the full range of barbs, scale the wind speed up to pretend
    # that a storm is passing over
    magnitude = (uwind**2 + vwind**2)**0.5
    magnitude.convert_units("knot")
    max_speed = magnitude.collapsed(("latitude", "longitude"),
                                    iris.analysis.MAX).data
    max_desired = 65

    uwind = uwind / max_speed * max_desired
    vwind = vwind / max_speed * max_desired

    # Create a cube containing the wind speed
    windspeed = (uwind**2 + vwind**2)**0.5
    windspeed.rename("windspeed")
    windspeed.convert_units("knot")

    plt.figure()

    # Plot the wind speed as a contour plot
    qplt.contourf(windspeed)

    # Add wind barbs except for the outermost values which overhang the edge
    # of the plot if left
    iplt.barbs(uwind[1:-1, 1:-1], vwind[1:-1, 1:-1], pivot="middle", length=6)

    plt.title("Wind speed during a simulated storm")
    qplt.show()
Example #12
0
psi_SM = calc_MOC_from_T(T_SM)


fig = plt.figure()
ax1 = fig.add_subplot(311)
qplt.pcolormesh(psi_Eul[0,:],vmin=-30,vmax=30)
ax1 = fig.add_subplot(312)
qplt.pcolormesh(psi_GM[0,:],vmin=-30,vmax=30)
ax1 = fig.add_subplot(313)
qplt.pcolormesh(psi_SM[0,:],vmin=-30,vmax=30)



fig = plt.figure()
qplt.pcolormesh(psi_Eul[0,:]+psi_GM[0,:]+psi_SM[0,:],vmin=-30,vmax=30)
qplt.show()

#qplt.pcolormesh(psi_cube[0,:],vmin=-30,vmax=30)
#qplt.show()


psi_cube = psi_Eul+psi_GM
iris.save(psi_cube, '/RESEARCH/chapter3/data/newCO2_control_800/derived/MOC.nc')
#iris.save(psi_cube, '/RESEARCH/chapter3/data/newCO2_control_800/derived/MOC.nc')

'''
#for iv in v:
#    iv.remove_coord(iv.aux_coords[0])
#    iv.remove_coord(iv.aux_coords[0])
#    iv.attributes = {}
#v = v.concatenate_cube()
Example #13
0
#--------------------------------------------
# Load some data:
fname = iris.sample_data_path('air_temp.pp')
acube = iris.load_cube(fname)
print acube.__repr__()
# <iris 'Cube' of air_temperature / (K) (latitude: 73; longitude: 96)>

# Makes it a bit more comprehensible:
acube.convert_units("Celsius")
#--------------------------------------------


#--------------------------------------------
# The simplest plot possible:
qplt.contourf(acube)  ; qplt.show()
#--------------------------------------------


#--------------------------------------------
# But we need to add coastlines really.
# (contourf has discrete levels by default,
#  whereas pcolormesh defaults to a continuous range.)
qplt.contourf(acube)    ; qplt.plt.gca().coastlines()  ;  qplt.show()
qplt.pcolormesh(acube)  ; qplt.plt.gca().coastlines()  ;  qplt.show()
#--------------------------------------------


#--------------------------------------------
# In fact, qplt plots are still pretty customizable 
# without having to use other plotting packages:
Example #14
0
for year in [1983,]:
    print('################## {0!s}\n'.format(year))
    time1=datetime.datetime(year=year,month=1,day=1,hour=0,minute=0,second=0)
    time2=datetime.datetime(year=year,month=12,day=31,hour=23,minute=59,second=59)
    descriptor['times']=(time1,time2)
    descriptor['fileout1']=descriptor['basedir']+descriptor['source']+\
                        '/anom_std/'+descriptor['var_name']+\
                        '_'+str(descriptor['level'])+'_'+str(year)+'_'+\
                        descriptor['filter']+'.nc'

    aa=da.TimeFilter(descriptor,verbose=VERBOSE)
    aa.time_filter()

if PLOT:
    print('# Plot')
    time_constraint=iris.Constraint(time = lambda cell: time1 <= cell <= time2)
    tol=0.1
    lon0=0.0
    lon_constraint=iris.Constraint(longitude = lambda cell: lon0-tol <= cell <= lon0+tol)
    lat0=55.0
    lat_constraint=iris.Constraint(latitude = lambda cell: lat0-tol <= cell <= lat0+tol)
    with iris.FUTURE.context(cell_datetime_objects=True):
        x1=aa.data_in.extract(time_constraint & lon_constraint & lat_constraint)
    x2=aa.data_out.extract(lon_constraint & lat_constraint)
    qplt.plot(x1,label='in')
    qplt.plot(x2,label='out')
    plt.legend()
    plt.axis('tight')
    qplt.show()
    
def test_single_point(target_point, tmpfile, source_data_function, num_expected_distinct_values=2):
    '''Smooth a single point'''
    
    import iris.quickplot as qplt, matplotlib.pyplot as plt
    from gridsmoother import GridSmoother
    
    import os

    #lat,lon = target_point

    dlat = 180. / CUBE_SHAPE[0]
    dlon = 360. / CUBE_SHAPE[1]

    print "point lat = %s, lon = %s" % target_point

    assert int(target_point[0] / dlat) - target_point[0] / dlat < SMALL_NUMBER
    assert int(target_point[1] / dlon) - target_point[1] / dlon < SMALL_NUMBER
    
    print "dlat = %s, dlon = %s" % (dlat, dlon)
    
    #centre = (lat,lon)#(dlat / 2., dlon / 2.)
    source_cube = gen_or_load_2D(tmpfile , [source_data_function], ["unsmoothed data"], {"GS_centre_lat":target_point[0], 'GS_centre_lon':target_point[1]})[0]
    
    for smoothing_width in np.arange(2.0, 5, 0.5) * dlat:
        print "smoothing_width: ", smoothing_width
        
        gs = GridSmoother()
        filename = 'smoothing_%s.json.gz' % smoothing_width
        
        smoothing_function = lambda s: (s <= smoothing_width) * 1.0
        if os.path.exists(filename):
            gs.load(filename)
        else:
            gs.build(source_cube, smoothing_function)
            gs.save('smoothing_%s.json.gz' % smoothing_width)

        smoothed_cube = gs.smooth_2d_cube(source_cube)
        
        assert np.isclose(smoothed_cube.data.sum(), source_cube.data.sum(), atol=SMALL_NUMBER)

        #will fail for smoothing functions other than a hard cut off:
        if num_expected_distinct_values is not None:
            assert len(set(smoothed_cube.data.ravel().tolist())) == num_expected_distinct_values
        
        for i, j in zip(*np.where(smoothed_cube.data > 0.0)):
            assert smoothing_function(angular_separation(source_cube.coord('latitude').points[i],
                                                         source_cube.coord('longitude').points[j],
                                                         *target_point)
                                      ) > 0.
        
        for i, j in zip(*np.where(smoothed_cube.data == 0.0)):
            assert smoothing_function(angular_separation(source_cube.coord('latitude').points[i],
                                                         source_cube.coord('longitude').points[j],
                                                         *target_point)
                                      ) == 0.
        
        if PLOT:
            import cartopy.crs as ccrs
            fig = plt.figure()
            subpl = fig.add_subplot(111, projection=ccrs.PlateCarree())
        
            qplt.pcolormesh(smoothed_cube, cmap='Reds')
            qplt.outline(smoothed_cube)
            subpl.add_artist(plt.Circle(target_point, smoothing_width, edgecolor='blue', facecolor='none', transform=ccrs.PlateCarree()))
            
            for i, lat in enumerate(smoothed_cube.coord('latitude').points):
                for j, lon in enumerate(smoothed_cube.coord('longitude').points):
                    if smoothed_cube.data[i, j] > 0:
                        plt.text(lon, lat, smoothed_cube.data[i, j] ** -1, transform=ccrs.PlateCarree(), ha='center', va='center')
            
            qplt.plt.gca().coastlines()
            qplt.show()