Add support for more parametrization in coregistration#759
Draft
rhugonnet wants to merge 27 commits intoGlacioHack:mainfrom
Draft
Add support for more parametrization in coregistration#759rhugonnet wants to merge 27 commits intoGlacioHack:mainfrom
rhugonnet wants to merge 27 commits intoGlacioHack:mainfrom
Conversation
This was referenced Jul 18, 2025
Member
Author
|
@belletva @marinebcht The changes of this PR, specifically the addition of the internal In short: Point-point coregistrations (such as Maybe, in #873, we just leave the work to |
3 tasks
Merged
…new uncertainty module replacing spatialstats
…new uncertainty module replacing spatialstats
…tch + Refine uncertainty tests
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds support for many new parametrizations as well as uncertainty propagation for coregistration, which required to start the restructuration of the uncertainty module (previously
spatialstats; see #378).Details
This PR adds several options and optimizations to affine coregistrations, namely:
toleranceargument is replaced bytolerance_translation,tolerance_rotation(andtolerance_objectiveforCPD), and (internally) the coregistration algorithms now all compute the associated statistics at each iteration (magnitude of change in translation, rotation, objective function) and the iteration stops only when all tolerances are reached,trim_residualsoption is added to all methods for outlier filtering, including four sub-options:trim_central_statistic,trim_spread_statistic,trim_spread_coverage, which describe how the trimming is done (for instance median +/- 3NMAD), andtrim_iterativeto either perform the trimming only once, or by re-computing the trimming statistic iteratively until all outliers are removed,fit_optimizeris removed in favor offit_minimizer(more generic for optimizer supports, can vary loss function details more easily for instance) and the default consequently changes fromscipy.optimize.curve_fit()toscipy.optimize.least_squares()(takes residuals = Y - f(X) as input, instead of X and Y independently). For this adaptation to work, we mirror some defaults ofcurve_fit(): for example, if undefined, the initial values are set as an array of ones (required argument forleast_squares),ICPold support for a "lsq_linearized"fit_minimizeris moved to an argumentlinearized=True, which corresponds the linearization (Taylor expansion) of the "point-to-plane" optimisation from Low (2004). This linearization now also supports anyfit_minimizer(previously a plain NumPy least-square matrix calculation),DhMinimizemethod is deprecated in favor of alinearized=Falseargument inLZD(and, to keep the old behaviour, would have to passonly_translation=Trueand original optimizer/loss functions, because the newLZD(linearized=False)now supports rotations as well!). They are actually the same method (both doing a "Least Z-difference" i.e. LZD), with the Rosenholm and Torlegard (1988) formulation being the linearized version; this greatly improves the consistency of naming/arguments in the package,CPDnamed "local surface geometry" (LSG) is added through the argumentlsg=True. The LSG variant uses the local normals to better constrain the optimization (like "point-to-plane" does for ICP).anisotropicargument is added toICPandCPDto optionally perform automated weighting along the axes X/Y/Z, with strategies "xy_vs_z" and "per_axis". This is very useful to better constrain all rotations/translations for data that has very different extents in X/Y and Z (for instance a DEM that is 50km long, but with only 1km of elevation range),sampling_strategyargument is added for point-point methods (ICP,CPD) which describes how a raster is converted to point cloud before coregistration: It can be set to "same_xy" (both inputs are subsampled at the same X/Y), or "independent" (both inputs are independently subsampled at different random points) or "iterative_same_xy" (both inputs are re-subsampled at the same X/Y every iteration of the algorithm by interpolating the raster input). The new "independent" sampling option required the addition of a new_subsamplefunction logic which works on all inputs,reproj_same_gridargument is added for preprocessing the input datasets inCoreg.fit(), it is set asTruefor bias-correction, butFalsefor affine coregistrations (because point-point registration can work even if the datasets don't overlap in Z coordinate, so reprojection should not be enforced). This change adds the requirement to pass independently aref_transformandtba_transformto subfunctions (previously a singletransformvalid for both grids, which were always reprojected), so this is modified for allCoreg._fit_rst_rstsubfunctions.last_iterationsaving the last iteration number, anditeration_statssaving the iteration statistics compared to each tolerance) were derived but not saved in the final.metauntil now. We now store these statistics, which can be printed ininfo()by users.Finally, being finalized, this PR adds:
LZDwith generalized least squares and total least squares implementation, requiring a new optional dependency (GPyTorch).Resolves #596
TO-DO:
reproj_same_grid(and change boolean to actual value infit()).DhMinimizeintoLZD?LSG-CPD(uses normals) for a fair comparison of the three algorithms,ICPsolve with same minimizers,_iterate_methodprints following Limit the number of decimal places when displaying floats with NumPy #760 (comment),