Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splitting wind direction to sin and cos in labels #184

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 13 additions & 2 deletions usl_pipeline/cloud_functions/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,19 @@ def _process_wrf_label_and_metadata(fd: IO[bytes]) -> Tuple[NDArray, FeatureMeta
if var == "wspd_wdir10":
# TODO: Split wind dir to sin/cos components
wspd10, wdir10 = wrf.getvar(nc, "wspd_wdir10")
label_components.append(numpy.swapaxes(wspd10, 0, 1))
label_components.append(numpy.swapaxes(wdir10, 0, 1))
# Convert wind direction from degrees to radians
wdir10_rad = numpy.deg2rad(wdir10)
# Split wind direction into sin and cos components
wind_dir_sin = numpy.sin(wdir10_rad)
wind_dir_cos = numpy.cos(wdir10_rad)
# Append wind speed and sin/cos of wind direction as labels
label_components.append(numpy.swapaxes(wspd10, 0, 1)) # wind speed
label_components.append(
numpy.swapaxes(wind_dir_sin, 0, 1)
) # sin(wind_dir)
label_components.append(
numpy.swapaxes(wind_dir_cos, 0, 1)
) # cos(wind_dir)
else:
label = wrf.getvar(nc, var)
# Ensure order of dimension axes are: (west_east, south_north)
Expand Down
19 changes: 12 additions & 7 deletions usl_pipeline/cloud_functions/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,9 +1230,11 @@ def test_build_wrf_label_matrix(
# Mock out the values that wrf-python will derive and return
rh2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
t2 = [[10, 20, 30], [40, 50, 60], [70, 80, 90]]

# Mock wind speed and direction, with wind speed and direction (degrees)
wspd_wdir10 = [
[[11, 11, 11], [11, 11, 11], [11, 11, 11]],
[[22, 22, 22], [22, 22, 22], [22, 22, 22]],
[[11, 11, 11], [11, 11, 11], [11, 11, 11]], # wind speed
[[0, 90, 180], [270, 0, 90], [180, 270, 0]], # wind direction
]

mock_wrf_getvar.side_effect = [
Expand All @@ -1241,7 +1243,7 @@ def test_build_wrf_label_matrix(
wspd_wdir10,
]
mock_wrf_getvar.reset_mock()

# Call the main function to process the data
main.build_wrf_label_matrix(
functions_framework.CloudEvent(
{"source": "test", "type": "event"},
Expand Down Expand Up @@ -1270,14 +1272,17 @@ def test_build_wrf_label_matrix(
# Ensure we attempted to upload a serialized label matrix
mock_label_blob.upload_from_file.assert_called_once_with(mock.ANY)
uploaded_array = numpy.load(mock_label_blob.upload_from_file.call_args[0][0])
# Expected array should be all required vars extracted, lon/lat axis reordered, and
# stacked
# Calculate the expected sine and cosine of wind direction
wdir10_rad = numpy.deg2rad(wspd_wdir10[1]) # Convert to radians
wind_dir_sin = numpy.sin(wdir10_rad) # Compute sine of direction
wind_dir_cos = numpy.cos(wdir10_rad) # Compute cosine of direction
expected_array = numpy.dstack(
[
numpy.swapaxes(rh2, 0, 1),
numpy.swapaxes(t2, 0, 1),
numpy.swapaxes(wspd_wdir10[0], 0, 1),
numpy.swapaxes(wspd_wdir10[1], 0, 1),
numpy.swapaxes(wspd_wdir10[0], 0, 1), # wind speed
numpy.swapaxes(wind_dir_sin, 0, 1), # sine of wind direction
numpy.swapaxes(wind_dir_cos, 0, 1), # cosine of wind direction
]
)
numpy.testing.assert_array_equal(uploaded_array, expected_array)
Expand Down
Loading