Skip to content

Commit

Permalink
Fixes for issue 65 with nan elements for d0 calculation (josephhardin…
Browse files Browse the repository at this point in the history
…ee#88)

* This adds some error catching code for cases where D0 is being calculated with arrays that contain nans, or single elements that are above zero. Also some more unit tests are added to stop regression of this in the future.
  • Loading branch information
josephhardinee authored Jan 3, 2020
1 parent 8af937a commit 92e54e5
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ matrix:
# python: "3.7-dev"
before_install:
- pip install pytest pytest-cov
- pip install coverage==4.5.4
- pip install coveralls
install: source continuous_integration/install.sh
script: eval xvfb-run python -m pytest $PYTEST_ARGS
#script: eval xvfb-run nosetests $NOSE_ARGS
after_success:
- coveralls
# - coveralls
- if [[ "$DOC_BUILD" == "true" ]]; then cd $TRAVIS_BUILD_DIR; source continuous_integration/build_docs.sh;
fi
3 changes: 2 additions & 1 deletion continuous_integration/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ fi

# install coverage modules
if [[ "$COVERALLS" == "true" ]]; then
pip install python-coveralls
pip install 'coverage<5.0'
pip install coveralls
fi

pip install -e .
11 changes: 9 additions & 2 deletions pydsd/DropSizeDistribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,10 +399,17 @@ def _calculate_D0(self, N):
rho_w = 1e-3
W_const = rho_w * np.pi / 6.0

if np.sum(N) == 0:
if np.nansum(N) == 0:
return 0

cum_W = W_const * np.cumsum(
if (
np.count_nonzero(N[np.isfinite(N)]) == 1
): # If there is only one nonzero/nan element, return that diameter.
return self.diameter["data"][
np.nanargmax(N)
] # This gets around weirdness with only one valid point.

cum_W = W_const * np.nancumsum(
[
N[k] * self.spread["data"][k] * (self.diameter["data"][k] ** 3)
for k in range(0, len(N))
Expand Down
20 changes: 20 additions & 0 deletions pydsd/tests/test_DropSizeDistribution.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import os.path
import numpy as np

from ..aux_readers import ARM_Vdis_Reader
from ..io.NetCDFWriter import write_netcdf
Expand Down Expand Up @@ -30,3 +31,22 @@ def test_changing_canting_angle_updates_value(self, two_dvd_open_test_file):

def test_canting_angle_has_default_value(self, two_dvd_open_test_file):
assert "canting_angle" in two_dvd_open_test_file.scattering_params.keys()

def test_calculating_D0_with_nan_actually_works(self, two_dvd_open_test_file):
two_dvd_open_test_file.fields["Nd"]["data"][0, 0] = np.nan # Force a nan error
two_dvd_open_test_file.fields["Nd"]["data"][0, 1] = 5

two_dvd_open_test_file.calculate_dsd_parameterization()
assert two_dvd_open_test_file.fields["D0"]["data"][0] != np.nan
assert (
two_dvd_open_test_file.fields["D0"]["data"][0]
== two_dvd_open_test_file.diameter["data"][1]
)

def test_calculating_D0_returns_correct_values(self, two_dvd_open_test_file):
two_dvd_open_test_file.fields["Nd"]["data"][0, 0] = 1 # Force a nan error
two_dvd_open_test_file.fields["Nd"]["data"][0, 1] = 2
two_dvd_open_test_file.calculate_dsd_parameterization()
assert np.isclose(
two_dvd_open_test_file.fields["D0"]["data"][0], .198, rtol=.01
) # One percent tolerance is closer than my hand calcs.

0 comments on commit 92e54e5

Please sign in to comment.