diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..93ce03fd --- /dev/null +++ b/.coveragerc @@ -0,0 +1,3 @@ +[run] +source=tobac +omit = tobac/tests/* diff --git a/.github/workflows/codecov-CI.yml b/.github/workflows/codecov-CI.yml new file mode 100644 index 00000000..4f9f1d4b --- /dev/null +++ b/.github/workflows/codecov-CI.yml @@ -0,0 +1,33 @@ +name: Codecov CI + +on: [push, pull_request] + +jobs: + run: + runs-on: ubuntu-latest + env: + OS: ubuntu-latest + PYTHON: '3.9' + steps: + - uses: actions/checkout@v2 + # Similar to MetPy install-conda action + - name: Set up conda + uses: conda-incubator/setup-miniconda@v2 + with: + miniforge-version: latest + miniforge-variant: mambaforge + channel-priority: strict + channels: conda-forge + show-channel-urls: true + use-only-tar-bz2: true + + - name: Install dependencies and generate report + shell: bash -l {0} + run: mamba install --quiet --yes --file conda-requirements.txt coverage pytest-cov && + python -m coverage run -m pytest --cov=./ --cov-report=xml + - name: Upload Coverage to Codecov + uses: codecov/codecov-action@v2 + with: + fail_ci_if_error: true + flags: unittests + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c8ea43f..70f4145f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ ### Tobac Changelog +_**Version 1.3.2:**_ + +**Bug fixes** + +- Fixed a bug with Feature Detection that caused it to fail when using `weighted_abs` position [#148](https://github.com/tobac-project/tobac/pull/148) +- Fixed a bug where adaptive_search within `linking_trackpy` was not working correctly [#140](https://github.com/tobac-project/tobac/pull/140) + +**Repository enhancements** + +- Added automatic code coverage reports [#124](https://github.com/tobac-project/tobac/pull/124) +- Added automatic building of readthedocs documentation on pull requests + + _**Version 1.3.1:**_ **Enhancements** diff --git a/setup.py b/setup.py index 458cae70..419145d2 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="tobac", - version="1.3.1", + version="1.3.2", description="Tracking and object-based analysis of clouds", url="http://github.com/tobac-project/tobac", author=[ diff --git a/tobac/feature_detection.py b/tobac/feature_detection.py index dea74933..69d2bd90 100644 --- a/tobac/feature_detection.py +++ b/tobac/feature_detection.py @@ -90,7 +90,7 @@ def feature_position( elif position_threshold == "weighted_abs": # get position as centre of identified region, weighted by absolute values if the field: - weights = abs(track_data[region_small]) + weights = abs(track_data_region[region_small]) if sum(weights) == 0: weights = None hdim1_index = np.average(hdim1_indices, weights=weights) diff --git a/tobac/tests/Dockerfile-coverage b/tobac/tests/Dockerfile-coverage new file mode 100644 index 00000000..165d659a --- /dev/null +++ b/tobac/tests/Dockerfile-coverage @@ -0,0 +1,15 @@ +FROM mambaorg/micromamba +ARG MAMBA_DOCKERFILE_ACTIVATE=1 + +RUN micromamba install -y -n base -c conda-forge numpy \ + scipy scikit-image pandas pytables matplotlib iris \ + cf-units xarray cartopy trackpy numba pytest pip \ + pytest-cov coverage + +COPY . ./ + +RUN pip install . + +RUN coverage run -m pytest --cov-report=xml &&\ + mv coverage.xml shared + diff --git a/tobac/tests/test_feature_detection.py b/tobac/tests/test_feature_detection.py index 86d668c5..0894b113 100644 --- a/tobac/tests/test_feature_detection.py +++ b/tobac/tests/test_feature_detection.py @@ -1,4 +1,4 @@ -import tobac.testing +import tobac.testing as tbtest import tobac.feature_detection as feat_detect import pytest @@ -8,7 +8,6 @@ def test_feature_detection_multithreshold_timestep(): Tests ```tobac.feature_detection.feature_detection_multithreshold_timestep """ import numpy as np - from tobac import testing from tobac import feature_detection # start by building a simple dataset with a single feature and seeing @@ -26,7 +25,7 @@ def test_feature_detection_multithreshold_timestep(): test_min_num = 2 test_data = np.zeros(test_dset_size) - test_data = testing.make_feature_blob( + test_data = tbtest.make_feature_blob( test_data, test_hdim_1_pt, test_hdim_2_pt, @@ -34,7 +33,7 @@ def test_feature_detection_multithreshold_timestep(): h2_size=test_hdim_2_sz, amplitude=test_amp, ) - test_data_iris = testing.make_dataset_from_arr(test_data, data_type="iris") + test_data_iris = tbtest.make_dataset_from_arr(test_data, data_type="iris") fd_output = feature_detection.feature_detection_multithreshold_timestep( test_data_iris, 0, threshold=test_threshs, n_min_threshold=test_min_num ) @@ -44,3 +43,35 @@ def test_feature_detection_multithreshold_timestep(): # Make sure that the location of the feature is correct assert fd_output.iloc[0]["hdim_1"] == pytest.approx(test_hdim_1_pt) assert fd_output.iloc[0]["hdim_2"] == pytest.approx(test_hdim_2_pt) + + +@pytest.mark.parametrize( + "position_threshold", [("center"), ("extreme"), ("weighted_diff"), ("weighted_abs")] +) +def test_feature_detection_position(position_threshold): + """ + Tests to make sure that all feature detection position_thresholds work. + """ + import numpy as np + + test_dset_size = (50, 50) + + test_data = np.zeros(test_dset_size) + + test_data[0:5, 0:5] = 3 + test_threshs = [ + 1.5, + ] + test_min_num = 2 + + test_data_iris = tbtest.make_dataset_from_arr(test_data, data_type="iris") + + fd_output = feat_detect.feature_detection_multithreshold_timestep( + test_data_iris, + 0, + threshold=test_threshs, + n_min_threshold=test_min_num, + position_threshold=position_threshold, + ) + + pass diff --git a/tobac/tracking.py b/tobac/tracking.py index 227eed79..1bc9b925 100644 --- a/tobac/tracking.py +++ b/tobac/tracking.py @@ -89,7 +89,12 @@ def linking_trackpy( # If subnetwork size given, set maximum subnet size if subnetwork_size is not None: - tp.linking.Linker.MAX_SUB_NET_SIZE = subnetwork_size + # Choose the right parameter depending on the use of adaptive search + if adaptive_step is None and adaptive_stop is None: + tp.linking.Linker.MAX_SUB_NET_SIZE = subnetwork_size + else: + tp.linking.Linker.MAX_SUB_NET_SIZE_ADAPTIVE = subnetwork_size + # deep copy to preserve features field: features_linking = deepcopy(features)