-
Notifications
You must be signed in to change notification settings - Fork 85
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
Update decision tree to include an option for handling masked points #2035
base: master
Are you sure you want to change the base?
Changes from 4 commits
83df6be
72d9162
718b555
3071fe2
3742dc9
8b34882
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,20 +81,90 @@ def hail_cube() -> Cube: | |
return cube | ||
|
||
|
||
@pytest.fixture() | ||
def cloud_top_temp() -> Cube: | ||
""" | ||
Set up a cloud top temperature, deterministic cube. | ||
""" | ||
data = np.full((7, 3), dtype=np.float32, fill_value=250) | ||
cube = set_up_variable_cube( | ||
data, | ||
name="cloud_top_temperature", | ||
units="K", | ||
time=dt(2017, 10, 10, 12, 0), | ||
frt=dt(2017, 10, 10, 11, 0), | ||
) | ||
return cube | ||
|
||
|
||
@pytest.fixture() | ||
def cloud_base_temp() -> Cube: | ||
""" | ||
Set up a cloud base temperature, deterministic cube. | ||
""" | ||
data = np.full((7, 3), dtype=np.float32, fill_value=270) | ||
cube = set_up_variable_cube( | ||
data, | ||
name="cloud_base_temperature", | ||
units="K", | ||
time=dt(2017, 10, 10, 12, 0), | ||
frt=dt(2017, 10, 10, 11, 0), | ||
) | ||
return cube | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"masked_data", ("no_mask", "mask_precip", "mask_cloud_top", "mask_cloud_base") | ||
) | ||
@pytest.mark.parametrize( | ||
"precip_fill,hail_fill,expected", ((1, 1, 2), (1, 0, 1), (0, 0, 0), (0, 1, 0)) | ||
) | ||
def test_non_probablistic_tree( | ||
precip_cube, hail_cube, precip_fill, hail_fill, expected | ||
precip_cube, | ||
hail_cube, | ||
cloud_top_temp, | ||
cloud_base_temp, | ||
precip_fill, | ||
hail_fill, | ||
expected, | ||
masked_data, | ||
): | ||
"""Test that ApplyDecisionTree correctly manages a decision tree with deterministic | ||
inputs""" | ||
inputs. Also check that if data is masked the output will be masked unless the | ||
node includes an if_masked setting.""" | ||
|
||
expected_array = np.full_like(precip_cube.data, expected) | ||
|
||
if masked_data == "mask_precip": | ||
# Test that if there is no if_masked setting in the decision tree, the output | ||
# will be masked | ||
precip_mask = np.full_like(precip_cube.data, False) | ||
precip_mask[0, 0] = True | ||
precip_cube.data = np.ma.masked_array(precip_cube.data, mask=precip_mask) | ||
|
||
expected_mask = np.full_like(precip_cube.data, False) | ||
expected_mask[0, 0] = True | ||
expected = np.ma.masked_array(expected_array, mask=expected_mask) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is suspicious. The test at the end looks at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated the decision tree slightly so the if masked will go to false rather than true which would stop this test passing. |
||
elif masked_data == "mask_cloud_top": | ||
# Testing if there is an if_masked setting in the decision tree going to a | ||
# different node than if_true or if_false | ||
cloud_mask = np.full_like(cloud_top_temp.data, False) | ||
cloud_mask[0, 0] = True | ||
cloud_top_temp.data = np.ma.masked_array(cloud_top_temp.data, mask=cloud_mask) | ||
expected_array[0, 0] = 0 | ||
elif masked_data == "mask_cloud_base": | ||
# Testing if there is an if_masked setting in the decision tree going to | ||
# the same node as if_true | ||
cloud_mask = np.full_like(cloud_base_temp.data, False) | ||
cloud_mask[0, 0] = True | ||
cloud_base_temp.data = np.ma.masked_array(cloud_base_temp.data, mask=cloud_mask) | ||
|
||
precip_cube.data.fill(precip_fill) | ||
hail_cube.data.fill(hail_fill) | ||
result = ApplyDecisionTree(decision_tree=deterministic_diagnostic_tree())( | ||
iris.cube.CubeList([precip_cube, hail_cube]) | ||
iris.cube.CubeList([precip_cube, hail_cube, cloud_top_temp, cloud_base_temp]) | ||
) | ||
assert np.all(result.data == expected) | ||
assert np.all(result.data == expected_array) | ||
MoseleyS marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
def test_non_probablistic_tree_missing_data(hail_cube): | ||
|
@@ -554,6 +624,7 @@ def test_basic(self): | |
self.assertIsInstance(result, list) | ||
self.assertEqual(len(result), 2) | ||
self.assertIsInstance(result[0], list) | ||
|
||
for i in range(2): | ||
constraint_exp = expected[0][i][0] | ||
constraint_res = result[0][i][0] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should have a unit test that demonstrates this new behaviour explicitly, rather than via the
if_masked
functionality.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've separated the masked data tests into their own test rather than parameterising it which I think is what you were asking for?