Data analysis framework ======================= A number of abstract classes are available to implement user triggered data analysis tasks. Such analysis computations are triggered by an actor with which the user has interacted. For example, the actor can allow the user to select a rendered isosurface and trigger some sort of computation that analyses the selected isosurface and displays the result in an additional graphic. Implementation -------------- The framework for such analysis tasks is implemented in ``abstractanalysis.h`` and consists of three abstract classes from which an actual implementation must derive: * :code:`MAnalysisControl` is the "broker" between the actor that triggers the analysis and an :code:`MAnalysisDataSource` that implements the actual analysis algorithm. The actor instructs an analysis control to run the analysis, afterwards the control will display the results of the analysis in a separate widget. * :code:`MAnalysisDataSource` is a specialised :code:`MScheduledDataSource` that implements the data analysis algorithm. The result is stored in an :code:`MAnalysisResult`. * :code:`MAnalysisResult` is a specialised :code:`MAbstractDataItem`. It stores the result of the analysis (which can be of any data type required by the analysis) and can be managed by a memory manager instance. For implementing a new data analysis algorithm, you must inherit from all three classes. * First, derive from :code:`MAnalysisResult` and add member variables that store the data you need to store in your analysis result. Make sure to overwrite the :code:`getMemorySize_kb()` method to ensure correct behaviour of the memory manager. The abstract class already contains a member :code:`textResult` that you can use to store a user-readable version of your analysis result as text. * Next, create a (draft) version of your analysis data source by deriving from :code:`MAnalysisDataSource`. As for any data source, you need to implement the methods :code:`produceData()` and :code:`createTaskGraph()`. Special to the analysis data sources is that the request received by these two methods is prepared by your implementation of :code:`MAnalysisControl::prepareRequest()` (see below). The analysis control "talks" to the actor and creates the request that corresponds to the actor's configuration and user input. The resulting request is then processed by the data source. * Your analysis control class derived from :code:`MAnalysisControl` needs to implement a number of methods as well. - The contructor needs to create a display widget (you need to implement one!) and call the super class methods :code:`setDisplayWidget()` and :code:`setDisplayTitle()`. - :code:`createAnalysisSource()` simply needs to return a new instance of your class. - :code:`updateAnalysisSourceInputs()` accesses the connected actor's data sources and creates links to those data sources that are also required by the data source. This method is called by the super class method :code:`run()` each time the actor triggers an analysis. - :code:`prepareRequest()` can also access all of the actor's configuration information (in particular the actor's NWP variables) and needs to assemble a request that is passed to your analysis data source. - :code:`displayResult()` needs to be able to take an analysis result (i.e. the object that you have derived from :code:`MAnalysisResult`) and display its contents in the display widget you have created. This could be as simple as printing a line of text and could be as involved as creating a complex figure. * The actor finally needs to call the method :code:`MAnalysisControl::run()`. This will cause the control to talk to the actor, prepare the request, run the analysis and display the result. Examples -------- * :code:`MValueExtractionAnalysis` takes a position in 3D space from an actor (e.g., the user clicks on an actor and the correspondig position is determined) and interpolates the values of all data fields (NWP variables) registered with the actor to this position. The result is output as text. * :code:`MRegionContributionAnalysis` identifies an isosurface of a probability field selected by the user in the raycaster actor and performs an ensemble analysis to determine which members have contributed to the selected probability region.