Things to know on coregistration structure - GlacioHack/xdem GitHub Wiki
Whether we want to add a new method, or do some maintenance, here's a list of things that are good to know.
If not the case, first get a user-oriented introduction to the working of these classes in xDEM's documentation.
Summary of Coreg class structure
The parent Coreg class implements core methods fit(), apply() (and others) shared across all coregistration subclasses, and initiates a meta dictionary through its __init__ which stores any metadata inputs/outputs about the method. The fit() and apply() methods re-direct to non-public functions _fit_rst_rst, _fit_rst_pts and _fit_pts_pts for fitting (raster-raster, raster-point or point-point input) and _apply_rst or _apply_pts. These functions are meant to be overridden in subclasses implementing a specific coregistration, such as NuthKaab or Deramp.
The AffineCoreg subclass of Coreg is the parent class for all coregistration methods that can be described by an affine transformation. All AffineCoreg subclasses will use the same apply_matrix functions for any raster or point input, and thus have no _apply_ function to implement. Only the _fit_xxx functions have to be implemented.
The BiasCorr subclass of Coreg is the parent class for all coregistration/correction methods that can be described by binning data and/or fitting a function with any number of bias variables (which can range from raster coordinates or terrain attributes, to any user-input variables). Their _fit_xxx functions thus re-directs to a single BiasCorr._fit_rst_rst_and_rst_pts function that calls the Coreg._bin_and_or_fit_nd binning and fitting method, and a single BiasCorr._apply_rst. Thus, to implement a new BiasCorr subclass, only specific fitting and binning parameters in the class __init__, and the derivation of bias variables in _fit_xxx/apply_xxx have to be implemented. For instance, Deramp forces its fit_func to be a 2D polynomial, and in _fit_xxx it derives its bias variable as the 2D coordinates of the DEM.
The CoregPipeline and BlockwiseCoreg subclasses of Coreg override the fit() and apply() method to perform those in a pipeline or per-block, but then rely on the same inheritance to the _fit_xxx and _apply_xxx of a given subclass.
Common core functions and metadata
Most Coreg.fit methods rely on the same core functions:
- The
coreg.base._preprocess_pts_rst_subsamplemethod is used to consistently extract a valid subsample of a raster-raster or raster-point input, to pass to the coregistration algorithm; a special case iscoreg.affine._preprocess_pts_rst_subsample_interpolatorwhich returns an interpolator for computationally efficiency of certain affine methods, - The
coreg.base._bin_or_and_fit_ndmethod is used to consistently perform binning and/or fitting with any auxiliary variables (for allAffineCoregmethod requiring optimization, and allBiasCorrmethods),
All Coreg method define their metadata by passing a single dictionary to Coreg.__init__, which will automatically sort the dictionary keys into a nested structure defined by CoregDict.
Steps to add a new Coreg subclass
- Add a new subclass either as
AffineCoregorBiasCorr:class MyCoreg(AffineCoreg): - Define its arguments in its
__init__method and callsuper().__init__with a dictionary of these arguments: thesubsampleargument is mandatory and common to all classes (seecoreg.base.InRandomDict), the generic bin and fit arguments are recommended if possible with the method (seecoreg.base.InFitOrBinDict, and the generic iteration arguments if relevant also (seecoreg.base.InIterativeDict). Any other argument specific to that method has to be added tocoreg.base.InSpecificDict. - Add a string description of new specific arguments in
coreg.base.dict_key_to_str, to be displayed inCoreg.info(), - Add the
_fit_xxxfunction, using the common core function described above for subsampling + performing a bin/fit. For aBiasCorrsubclass, the function should derive bias variables and end by pointing towardsBiasCorr._fit_rst_rst_and_rst_pts. For anAffineCoregsubclass, the function should end by storing the output affine matrix in the metadata, as done in other affine classes. - (Only for
BiasCorrsubclasses) Add the derivation of the bias variables in an_apply_xxxfunction, which then points toBiasCorr._apply_rst_pts.
Structure of iterative affine coregistration core functions
For affine coregistrations, class functions ultimately call an independent core function such as icp() or nuth_kaab(), that also have their own internal structure to ensure consistent behaviour. Those re-use a set of _preprocess_ functions, and utilize the _iterate_method function to iterate through their own _xxx_iteration_step() function. This iteration step always calls a _xxx_fit() step aiming at optimizing their _xxx_fit_func().
Here's a flowchart overview of that structure below, examplified for ICP: