Improvements for ApplicationEngine
What changes will be made and why they would make a better Orfeo ToolBox?
The OTB Application are now used very often, so it is important to keep the ApplicationEngine code clean. This RFC proposes small enhancements that will simplify the code base, and also new services available from the C++ ApplicationEngine API but also wrapped into the Python API.
High level description
The following are small improvement to the ApplicationEngine module:
Handling of "UserValue" flag: the optional boolean in 3rd argument of the functions SetParameterString/SetParameterInt/... is not very convenient. I think it is possible to get rid of it using a simple state flag "IsInPrivateDo" in the Application class. This flag would be set to ON during calls to DoInit(), DoUpdateParameters() and DoExecute(). During these calls, the values set on parameters are always "Automatic" values. Outside these calls, we can assume that the values set on parameters come from the user.
Merging "UserValue" and "AutomaticValue" flags: why do we have both ? I believe we could choose the convention : UserValue = not(AutomaticValue). The initial default value of a parameter would be considered "automatic". We could remove 1 of these 2 flags, there are already enough in the Parameter class.
Handling of the m_Active flag: this flag should be handled mostly by the Parameters themselves in the ApplicationEngine module. For instance the call to EnableParameter() in otb::Wrapper::CommandLineLauncher::LoadParameters() should not be here, but rather in each "param->SetValue(string)". In a similar way, in otb::Wrapper::Application::SetParameterUserValue(), the call to EnableParameter() should not be here (in addition, it will always switch ON an EmptyParameter). The benefit is also to guarantee the same behaviour on CLI / GUI /Python.
Refactor the ParameterType_Empty: there are a lot of special cases for this parameter because its value (a boolean flag) and its Active flag are actually the same. For instance, in the current state of ApplicationEngine, it is impossible to have an Empty parameter with Role_Output. This parameter should have its value stored in a specific flag, proper functions Application::Set/GetParameterBool(), and maybe easy conversions to/from string and integer values. Maybe a specific ParameterType_Boolean can be added...
String getters and setters for all parameters: it would be nice if all the parameters could be set using a common Application::SetParameterString(), or SetParameterStringList(). Same remark for getters. It would remove some long sections of if/elseif/elseif/... in the CommandLineLauncher but also in the Input/OutputXML parameters.
Move m_IsChecked to QtWrappers: in the Parameter base class, the flag m_IsChecked is only used by QtWrapper, so it should be moved outside ApplicationEngine.
Improve architecture of Parameters: there is also room for improvement in the architecture of Parameters. There is a lot of code that is duplicated between similar parameter types, we should consider a better class architecture to gather common features between parameters with similar behaviour.
Remove enum m_DefaultValueMode: in the Parameter base class, the enum m_DefaultValueMode is never used in OTB. We could check if other external projects use it. We could get rid of it.
If you see other potential improvements to the core of this module, feel free to give your idea.
The following are a list of new services for ApplicationEngine framework:
Streaming and output information: this is a set of service that let you have insights on what output the application will generate, and what pieces of the input you need to generate a piece of the output.
- Get the output information: given a parameter key corresponding to an OutputImageParameter, retrieve the output size, spacing, origin, projection, geom file and so on
- Get the requested input regions: given a parameter key corresponding to an OutputImageParameter, and a region corresponding to a piece of this output, get for each InputImageParameter the region required to produce that piece of output. The application could also return the estimated amount of RAM needed to compute that piece.
Attach metadata to numpy array interface: the numpy array interface to application is useless in many cases because it only allows to pass the pixel buffer, and no metadata. Many OTB filters need additional metadata (such as origin, spacing, size, projection and geom file) to be able to process the data.
Get rid of ComplexParameterInput/OutputImage: there is no reason to have a separate complex image parameter. This makes most application incompatible with complex images (such as ExtractROI for instance). It would be better to be able to detect complex images with InputImageParameter, and to add new output types for OutputImageParameter (cint, cfloat, ...). Check Request_for_changes-125:_Merge_Complex_and_standard_Image_Parameter
Set/get all parameters at once through a dictionnary in Pyton API: this is a small helper for large application with many parameters to set.
Get proper logging / progress reporting in Python: self explanatory.
Register/free filter resources: provide a way to register filters and free them at the end of the application processing to avoid retaining memory. Check improvements to fix bug #1475 (closed)
Interface with OGR Python wrappers: GDAL/OGR provides Python wrappers for vector data. It would be useful to import them in OTB Applications (into ParameterType_VectorData). Solution for vectors defined as ParameterType_InputFilename ?
Stop button for Graphic Interface: Be able to stop a running application.
Risks and benefits
The main risk is to break existing applications, so we need to focus on compatibility. In the end, the ApplicationEngine will have a cleaner code base and new useful features.
Alternatives for implementations
Who will be developing the proposed changes?
Work can be split, different contributors expected.