Skip to content

Commit

Permalink
Refactor GradientDescending to DhMinimize with generic inputs (#595)
Browse files Browse the repository at this point in the history
  • Loading branch information
rhugonnet authored Oct 6, 2024
1 parent 34e5049 commit 3287594
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 102 deletions.
6 changes: 3 additions & 3 deletions dev-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dependencies:
- numpy=1.*
- matplotlib=3.*
- pyproj>=3.4,<4
- rasterio>=1.3,<2
- rasterio>=1.3,<1.4
- scipy=1.*
- tqdm
- scikit-image=0.*
Expand All @@ -23,6 +23,7 @@ dependencies:
- richdem

# Test dependencies
- gdal # To test against GDAL
- pytest
- pytest-xdist
- pyyaml
Expand All @@ -43,10 +44,9 @@ dependencies:
- numpydoc

- pip:
# Optional dependency
- -e ./

# Optional dependencies
- noisyopt
# "Headless" needed for opencv to install without requiring system dependencies
- opencv-contrib-python-headless

Expand Down
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ dependencies:
- numpy=1.*
- matplotlib=3.*
- pyproj>=3.4,<4
- rasterio>=1.3,<2
- rasterio>=1.3,<1.4
- scipy=1.*
- tqdm
- scikit-image=0.*
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ numba==0.*
numpy==1.*
matplotlib==3.*
pyproj>=3.4,<4
rasterio>=1.3,<2
rasterio>=1.3,<1.4
scipy==1.*
tqdm
scikit-image==0.*
Expand Down
16 changes: 9 additions & 7 deletions tests/test_coreg/test_affine.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Functions to test the affine coregistrations."""
from __future__ import annotations

import warnings

import geopandas as gpd
import geoutils
import numpy as np
Expand Down Expand Up @@ -213,11 +215,11 @@ def test_raise_all_nans(self) -> None:

@pytest.mark.parametrize("fit_args", all_fit_args) # type: ignore
@pytest.mark.parametrize("shifts", [(20, 5, 2), (-50, 100, 2)]) # type: ignore
@pytest.mark.parametrize("coreg_method", [coreg.NuthKaab, coreg.GradientDescending, coreg.ICP]) # type: ignore
@pytest.mark.parametrize("coreg_method", [coreg.NuthKaab, coreg.DhMinimize, coreg.ICP]) # type: ignore
def test_coreg_translations__synthetic(self, fit_args, shifts, coreg_method) -> None:
"""
Test the horizontal/vertical shift coregistrations with synthetic shifted data. These tests include NuthKaab,
ICP and GradientDescending.
ICP and DhMinimize.
We test all combinaison of inputs: raster-raster, point-raster and raster-point.
Expand All @@ -227,7 +229,8 @@ def test_coreg_translations__synthetic(self, fit_args, shifts, coreg_method) ->
to be the right one; and that there is no other errors introduced in the process).
"""

# Initiate coregistration
warnings.filterwarnings("ignore", message="Covariance of the parameters*")

horizontal_coreg = coreg_method()

# Copy dictionary and remove inlier mask
Expand All @@ -249,7 +252,7 @@ def test_coreg_translations__synthetic(self, fit_args, shifts, coreg_method) ->
fit_shifts = [-horizontal_coreg.meta["outputs"]["affine"][k] for k in ["shift_x", "shift_y", "shift_z"]]

# ICP can be less precise than other methods
rtol = 10e-2 if coreg_method != coreg.ICP else 10e-1
rtol = 10e-2 if coreg_method == coreg.NuthKaab else 10e-1
assert np.allclose(shifts, fit_shifts, rtol=rtol)

# For a point cloud output, need to interpolate with the other DEM to get dh
Expand All @@ -274,14 +277,14 @@ def test_coreg_translations__synthetic(self, fit_args, shifts, coreg_method) ->

# Check applying the coregistration removes 99% of the variance (95% for ICP)
# Need to standardize by the elevation difference spread to avoid huge/small values close to infinity
tol = 0.01 if coreg_method != coreg.ICP else 0.05
tol = 0.01 if coreg_method == coreg.NuthKaab else 0.05
assert np.nanvar(dh / np.nanstd(init_dh)) < tol

@pytest.mark.parametrize(
"coreg_method__shift",
[
(coreg.NuthKaab, (9.202739, 2.735573, -1.97733)),
(coreg.GradientDescending, (10.0, 2.5, -1.964539)),
(coreg.DhMinimize, (10.0850892, 2.898166, -1.943001)),
(coreg.ICP, (8.73833, 1.584255, -1.943957)),
],
) # type: ignore
Expand All @@ -299,7 +302,6 @@ def test_coreg_translations__example(
# Get the coregistration method and expected shifts from the inputs
coreg_method, expected_shifts = coreg_method__shift

# Run co-registration
c = coreg_method(subsample=50000)
c.fit(ref, tba, inlier_mask=inlier_mask, verbose=verbose, random_state=42)

Expand Down
9 changes: 2 additions & 7 deletions tests/test_coreg/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,11 @@ def recursive_typeddict_items(typed_dict: Mapping[str, Any]) -> Iterable[str]:
# Assert all keys exist in the mapping key to str dictionary used for info
list_info_keys = list(dict_key_to_str.keys())

# TODO: Remove GradientDescending + ICP keys here once generic optimizer is used
# TODO: Remove ICP keys here once generic optimizer is used
# Temporary exceptions: pipeline/blockwise + gradientdescending/icp
list_exceptions = [
"step_meta",
"pipeline",
"x0",
"bounds",
"deltainit",
"deltatol",
"feps",
"rejection_scale",
"num_levels",
]
Expand Down Expand Up @@ -771,7 +766,7 @@ def test_pipeline__errors(self) -> None:

def test_pipeline_pts(self) -> None:

pipeline = coreg.NuthKaab() + coreg.GradientDescending()
pipeline = coreg.NuthKaab() + coreg.DhMinimize()
ref_points = self.ref.to_pointcloud(subsample=5000, random_state=42).ds
ref_points["E"] = ref_points.geometry.x
ref_points["N"] = ref_points.geometry.y
Expand Down
2 changes: 1 addition & 1 deletion xdem/coreg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from xdem.coreg.affine import ( # noqa
ICP,
AffineCoreg,
GradientDescending,
DhMinimize,
NuthKaab,
VerticalShift,
)
Expand Down
Loading

0 comments on commit 3287594

Please sign in to comment.