Difference between revisions of "Proposals:Calculators Architecture"

From KitwarePublic
Jump to navigationJump to search
(Created page with "= Proposal = A more flexible inverse transform API is needed in order to support numeric inverse transformation for transforms which do not have an analytical inverse. = Existin...")
 
Line 1: Line 1:
= Proposal =
= Proposal =
A more flexible inverse transform API is needed in order to support numeric inverse transformation for transforms which do not have an analytical inverse.
Decide on the best architecture for how to implement ITK Calculators. Should they derive from ProcessObject and be part of the pipeline, or should they inherit from Object and be separate from the pipeline?


= Existing API =
= Current Situation =  
* The inverse transformation functionality is available via the GetInverse method. The GetInverse method is not virtual, even though it is declared in the base class. The GetInverse method expects as its parameter a pointer to the forward transform object. The GetInverse method fills in the parameter list of the passed-in forward transform such that it would define the inverse transform.
* The inverse transformation functionality is also avaible via the deprecated BackTransform API (analogous to the TransformPoint, TransformVector and TransformCovariantVector forward transform API).


= Existing limitations =
Calculators:
* Since the GetInverse method requires that the type of the inverse transform must be the same as the type of the forward transform, the possibility of a numeric inverse transform is automatically precluded.
Based on Object()
* The fact that there is no virtual method for inverse transformations is a big limitation and inconvenience.
Must have a Compute()
* The identity transform does not provide any inverse transformation functionality at all.
Context specific Set/Get methods
Give examples:


= Proposed changes =
New code:
* The current GetInverse method may make perfect sense for transforms which are analytically invertible to a transform of the same type (Translation, Scale, Rotation, etc). It may make sense to keep this API intact.
Provides Compute() that calls Update()
* A virtual method declared at the base class should be provided that would return a pointer to a transform object. At the discretion of the forward transform, the inverse transform could be an analytic inverse or a numeric inverse.
Based on ProcessObject
* A new iterative inverse transform class must be defined. This class should be parameterized by the forward transform type. The numeric inverse can be implemented using the Newton-Raphson method for nonlinear systems of equations.
Also has Update, SetInput, GetOutput
* In order for the Newton-Raphson numeric inverse transform to be used, the forward transform API must define a method for evaluating the derivative of the transform with respect to the input image dimensions -- another Jacobian, different from the Jacobian currently provided by the forward transforms.
Do they have SetImage/GetThreshold methods also?


It makes some sense to implement the numeric inverse transform as a subclass of itk::Transform -- in order to provide a consistent API across forward and inverse transforms:
How to write a new calculator?
  template <typename TForwardTransform>
Drawbacks: Can't hot-swap calculators, pipeline overhead
  class NumericInverseTransform :
Calculators were designed to be fast and separate from pipeline structure
    public Transform<TForwardTransform::ScalarType,
Example: Otsu.  The only option is to call one from the other.  Cannot take advantage of inheritance.  Method need to be explicitly called on the one being instantiated.
                    TForwardTransform::OutputSpaceDimension,
Rename these new 10?
                    TForwardTransform::InputSpaceDimension>
Change name to have HistogramFilter in the name?
Take guts out and put them in real calculators that are called from the calculators?
Having layer above calculators to make the inputs and outputs more consistent


However, not all of the expected functionality associated with the forward itk::Transform class makes sense for a numeric inverse transform. For example, there is only one parameter that defines a numeric inverse -- a reference to the forward transform. Therefore, the GetParameters/SetParameters methods are meaningless.


The following addition is proposed for the itk::Transform interface:
= Existing limitations =


  // Return an inverse transform -- the derived class must decide what to do here.
= Proposed changes =
  // The default implementation throws an exception.
  virtual typename Transform<TScalarType,
                            NOutputDimensions,
                            NInputDimensions>::Pointer GetInverse() const;


The following forward transform interface is required by the Newton-Raphson solver.


  // evaluate F = T(x), J = dT/dx (another Jacobian):
  void Eval(const std::vector<ScalarType> & x,
            std::vector<ScalarType> & F,
            std::vector<std::vector<ScalarType> > & J) const;


= Current status =
= Current Status =  
I have a working implementation of the iterative numeric inverse using the numerical recipes code for the Newton-Raphson nonlinear solver. Currently, it is implemented within the deprecated BackTransform API (requiring minor modifications to the itk::Transform class). The inverse transform class does not derive from the itk::Transform class. This code is not up-to the ITK coding standards and will require some re-writing before being considered for inclusion into the ITK tree. Also, I am unclear whether the use of the numerical recipes code is allowed within ITK. If not, that will have to be rewritten as well.


{{ITK/Template/Footer}}
{{ITK/Template/Footer}}

Revision as of 15:53, 26 July 2013

Proposal

Decide on the best architecture for how to implement ITK Calculators. Should they derive from ProcessObject and be part of the pipeline, or should they inherit from Object and be separate from the pipeline?

Current Situation

Calculators: Based on Object() Must have a Compute() Context specific Set/Get methods Give examples:

New code: Provides Compute() that calls Update() Based on ProcessObject Also has Update, SetInput, GetOutput Do they have SetImage/GetThreshold methods also?

How to write a new calculator? Drawbacks: Can't hot-swap calculators, pipeline overhead Calculators were designed to be fast and separate from pipeline structure Example: Otsu. The only option is to call one from the other. Cannot take advantage of inheritance. Method need to be explicitly called on the one being instantiated. Rename these new 10? Change name to have HistogramFilter in the name? Take guts out and put them in real calculators that are called from the calculators? Having layer above calculators to make the inputs and outputs more consistent


Existing limitations

Proposed changes

Current Status



ITK: [Welcome | Site Map]