Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4ca99ae
Specify in docstrings how it works when T>2 (#101)
dnerini Jul 25, 2019
8946cdc
Change variable name
dnerini Jul 25, 2019
b26c774
Set private methods as public
dnerini Jul 25, 2019
8e4234d
Fix auto_summary
dnerini Jul 25, 2019
81f37ff
Rename methods
dnerini Jul 25, 2019
fe95a6d
Pass optional params as dict
dnerini Jul 25, 2019
72d1cff
Improve docstrings
dnerini Jul 25, 2019
f993832
Improve docstrings
dnerini Jul 25, 2019
207703e
Improve docstrings
dnerini Jul 25, 2019
c944f4c
Improve docstrings
dnerini Jul 25, 2019
6e1a6f4
Simplify syntax, improve docstrings
dnerini Jul 26, 2019
ebc0605
Remove option to include extra_vectors
dnerini Jul 26, 2019
30ca79b
Move 8-bit conversion down 1 level
dnerini Jul 26, 2019
89fb53d
Refactor outlier detection
dnerini Aug 9, 2019
5cd283e
Change method name
dnerini Aug 9, 2019
d39766e
Improve docstrings, refactor variable checks
dnerini Aug 9, 2019
3f55af6
Fix nvar
dnerini Aug 9, 2019
ca002da
Refactor declustering
dnerini Aug 9, 2019
1d270aa
Fix inputs
dnerini Aug 9, 2019
21b7f0a
Fix typo
dnerini Aug 9, 2019
485b504
Merge branch 'refactor_LK' into decorators
aperezhortal Aug 10, 2019
e9cd4c5
Add decorator to check the input_images shape
aperezhortal Aug 10, 2019
e007b56
Add keyword to check ndims only
aperezhortal Aug 10, 2019
5c1bc3f
Add darts to input shape tests
aperezhortal Aug 10, 2019
3450561
Remove unused variables
aperezhortal Aug 10, 2019
0b15f99
Change input variable name
dnerini Aug 12, 2019
f3a2a84
Refacator interpolation routine
dnerini Aug 12, 2019
c775a37
Use x,y and u,v as 2d array
dnerini Aug 12, 2019
88d1e02
Use numpy.empty instead of lists
dnerini Aug 12, 2019
e990431
Use numpy.empty instead of lists (part 2)
dnerini Aug 12, 2019
3585c4f
Improve usage of MaskedArray
dnerini Aug 12, 2019
6d98028
Add interpolate module
dnerini Aug 12, 2019
d22db79
Fix interface
dnerini Aug 12, 2019
3d7800a
Move decluster method to interpolation module
dnerini Aug 13, 2019
87bf732
Improve docstrings
dnerini Aug 13, 2019
da9625b
Move interpolate to utils
dnerini Aug 13, 2019
07743ab
Reorganize modules
dnerini Aug 13, 2019
1b282c1
Fix utils.interface
dnerini Aug 13, 2019
adcbe30
Refactor interfaces
dnerini Aug 13, 2019
d62d653
Update tests
dnerini Aug 13, 2019
96ec87e
Update utils doc
dnerini Aug 13, 2019
984291b
Improve docstrings
dnerini Aug 13, 2019
8f2d3a0
Update a wrapper function to look like the wrapped function
aperezhortal Aug 13, 2019
4085dbf
Code formating
aperezhortal Aug 15, 2019
8935dee
Improve LK docstrings
dnerini Aug 16, 2019
43fb57f
Allow for arbitrary number of dimensions
dnerini Aug 16, 2019
0ace92b
Improve docstrings
dnerini Aug 16, 2019
35fd3e7
Fix wrongly deleted line
dnerini Aug 16, 2019
32cffa0
Add check that the images don't contain only zero values
pulkkins Aug 16, 2019
3b961f9
Add zero precipitation test for proesmans function
aperezhortal Aug 16, 2019
878054c
Add test for proesmans's input arguments
aperezhortal Aug 16, 2019
bf51705
More small docstring improvements
dnerini Aug 16, 2019
bc85aee
Change coordinate normalization
dnerini Aug 19, 2019
5cd0584
Fix arguments
dnerini Aug 19, 2019
3ccb17f
Add reference
dnerini Aug 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/source/pysteps_reference/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ Implementation of miscellaneous utility functions.

.. automodule:: pysteps.utils.interface
.. automodule:: pysteps.utils.arrays
.. automodule:: pysteps.utils.cleansing
.. automodule:: pysteps.utils.conversion
.. automodule:: pysteps.utils.dimension
.. automodule:: pysteps.utils.fft
.. automodule:: pysteps.utils.images
.. automodule:: pysteps.utils.interpolate
.. automodule:: pysteps.utils.spectral
.. automodule:: pysteps.utils.transformation
62 changes: 46 additions & 16 deletions examples/LK_buffer_mask.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# -*- coding: utf-8 -*-
"""
Handling of no-data in Lucas-Kanade
===================================

Areas of missing data in radar images are typically caused by visibility limits
such as beam blockage and the radar coverage itself. These artifacts can mislead
such as beam blockage and the radar coverage itself. These artifacts can mislead
the echo tracking algorithms. For instance, precipitation leaving the domain
might be erroneously detected as having nearly stationary velocity.

This example shows how the Lucas-Kanade algorithm can be tuned to avoid the
erroneous interpretation of velocities near the maximum range of the radars by
buffering the no-data mask in the radar image in order to exclude all vectors
This example shows how the Lucas-Kanade algorithm can be tuned to avoid the
erroneous interpretation of velocities near the maximum range of the radars by
buffering the no-data mask in the radar image in order to exclude all vectors
detected nearby no-data areas.
"""

Expand Down Expand Up @@ -71,7 +72,9 @@
mask[~np.isnan(ref_mm)] = np.nan

# Log-transform the data [dBR]
R, metadata = transformation.dB_transform(R, metadata, threshold=0.1, zerovalue=-15.0)
R, metadata = transformation.dB_transform(
R, metadata, threshold=0.1, zerovalue=-15.0
)

# Keep the reference frame in dBR (for plotting purposes)
ref_dbr = R[0].copy()
Expand Down Expand Up @@ -109,10 +112,20 @@
R.data[R.mask] = np.nan

# Use default settings (i.e., no buffering of the radar mask)
x, y, u, v = LK_optflow(R, dense=False, buffer_mask=0, quality_level_ST=0.1)
fd_kwargs1 = {"buffer_mask":0}
xy, uv = LK_optflow(R, dense=False, fd_kwargs=fd_kwargs1)
plt.imshow(ref_dbr, cmap=plt.get_cmap("Greys"))
plt.imshow(mask, cmap=colors.ListedColormap(["black"]), alpha=0.5)
plt.quiver(x, y, u, v, color="red", angles="xy", scale_units="xy", scale=0.2)
plt.quiver(
xy[:, 0],
xy[:, 1],
uv[:, 0],
uv[:, 1],
color="red",
angles="xy",
scale_units="xy",
scale=0.2,
)
circle = plt.Circle((620, 245), 100, color="b", clip_on=False, fill=False)
plt.gca().add_artist(circle)
plt.title("buffer_mask = 0 (default)")
Expand All @@ -129,13 +142,24 @@
# 'x,y,u,v = LK_optflow(.....)'.

# with buffer
x, y, u, v = LK_optflow(R, dense=False, buffer_mask=20, quality_level_ST=0.2)
buffer = 10
fd_kwargs2 = {"buffer_mask":buffer}
xy, uv = LK_optflow(R, dense=False, fd_kwargs=fd_kwargs2)
plt.imshow(ref_dbr, cmap=plt.get_cmap("Greys"))
plt.imshow(mask, cmap=colors.ListedColormap(["black"]), alpha=0.5)
plt.quiver(x, y, u, v, color="red", angles="xy", scale_units="xy", scale=0.2)
plt.quiver(
xy[:, 0],
xy[:, 1],
uv[:, 0],
uv[:, 1],
color="red",
angles="xy",
scale_units="xy",
scale=0.2,
)
circle = plt.Circle((620, 245), 100, color="b", clip_on=False, fill=False)
plt.gca().add_artist(circle)
plt.title("buffer_mask = 20")
plt.title("buffer_mask = %i" % buffer)
plt.show()

################################################################################
Expand All @@ -148,13 +172,13 @@
# the negative bias that is introduced by the the erroneous interpretation of
# velocities near the maximum range of the radars.

UV1 = LK_optflow(R, dense=True, buffer_mask=0, quality_level_ST=0.1)
UV2 = LK_optflow(R, dense=True, buffer_mask=20, quality_level_ST=0.2)
UV1 = LK_optflow(R, dense=True, fd_kwargs=fd_kwargs1)
UV2 = LK_optflow(R, dense=True, fd_kwargs=fd_kwargs2)

V1 = np.sqrt(UV1[0] ** 2 + UV1[1] ** 2)
V2 = np.sqrt(UV2[0] ** 2 + UV2[1] ** 2)

plt.imshow((V1 - V2) / V2, cmap=cm.RdBu_r, vmin=-0.1, vmax=0.1)
plt.imshow((V1 - V2) / V2, cmap=cm.RdBu_r, vmin=-0.5, vmax=0.5)
plt.colorbar(fraction=0.04, pad=0.04)
plt.title("Relative difference in motion speed")
plt.show()
Expand Down Expand Up @@ -184,7 +208,13 @@

# Find the veriyfing observations in the archive
fns = io.archive.find_by_date(
date, root_path, path_fmt, fn_pattern, fn_ext, timestep=5, num_next_files=12
date,
root_path,
path_fmt,
fn_pattern,
fn_ext,
timestep=5,
num_next_files=12,
)

# Read and convert the radar composites
Expand All @@ -200,8 +230,8 @@
score_2.append(skill(R_f2[i, :, :], R_o[i + 1, :, :])["corr_s"])

x = (np.arange(12) + 1) * 5 # [min]
plt.plot(x, score_1, label="no mask buffer")
plt.plot(x, score_2, label="with mask buffer")
plt.plot(x, score_1, label="buffer_mask = 0")
plt.plot(x, score_2, label="buffer_mask = %i" % buffer)
plt.legend()
plt.xlabel("Lead time [min]")
plt.ylabel("Corr. coeff. []")
Expand Down
56 changes: 56 additions & 0 deletions pysteps/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""
pysteps.decorators
==================

Decorators used to define reusable building blocks that can change or extend
the behavior of some functions in pysteps.

.. autosummary::
:toctree: ../generated/

check_motion_input_image
"""
from functools import wraps

import numpy as np


def check_input_frames(minimum_input_frames=2,
maximum_input_frames=np.inf,
just_ndim=False):
"""
Check that the input_images used as inputs in the optical-flow
methods has the correct shape (t, x, y ).
"""

def _check_input_frames(motion_method_func):
@wraps(motion_method_func)
def new_function(*args, **kwargs):
"""
Return new function with the checks prepended to the
target motion_method_func function.
"""

input_images = args[0]
if input_images.ndim != 3:
raise ValueError(
"input_images dimension mismatch.\n"
f"input_images.shape: {str(input_images.shape)}\n"
"(t, x, y ) dimensions expected"
)

if not just_ndim:
num_of_frames = input_images.shape[0]

if minimum_input_frames < num_of_frames > maximum_input_frames:
raise ValueError(
f"input_images frames {num_of_frames} mismatch.\n"
f"Minimum frames: {minimum_input_frames}\n"
f"Maximum frames: {maximum_input_frames}\n"
)

return motion_method_func(*args, **kwargs)

return new_function

return _check_input_frames
Loading