Data analysis framework

A number of abstract classes are available to implement user triggered data analysis tasks. 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 four abstract classes from which an actual implementation must derive:

  • MAnalysisControl is the “broker” between the actor that triggers the analysis and an MAnalysisDataSource that implements the actual analysis algorithm. The actor instructs an analysis control to run the analysis, afterwards the control updates a result dock’s display with the result via an MAnalysisDisplay (see below).

  • MAnalysisDataSource is a specialised MScheduledDataSource that implements the data analysis algorithm. The result is stored in an MAnalysisResult.

  • MAnalysisResult is a specialised 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.

  • MAnalysisDisplay owns the UI widget for one analysis result and knows how to update it. Each MAnalysisControl creates instances of a derived MAnalysisDisplay to decouple the UI from the pipeline logic in the control; the display is placed into a dock widget, which owns and deletes it when the dock is destroyed.

For implementing a new data analysis algorithm, you must inherit from all four classes.

  • First, derive from MAnalysisResult and add member variables that store the data you need to store in your analysis result. Make sure to override the calculateMemorySize_KiB() method to ensure correct behaviour of the memory manager. The abstract class already contains a member 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 MAnalysisDataSource. As for any data source, you need to implement the methods produceData() and createTaskGraph(). Special to the analysis data sources is that the request received by these two methods is prepared by your implementation of 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.

  • Create a display widget by deriving from MAnalysisDisplay, implementing title() (the title shown on the result dock) and updateResult() (called with a lease to your derived MAnalysisResult whenever a new result is available, to update the widget’s contents – this could be as simple as printing a line of text or as involved as drawing a complex figure). Optionally override clear() to reset the widget to report no result.

  • Your analysis control class derived from MAnalysisControl needs to implement a number of methods as well.

    • createDisplay() needs to return a new instance of the MAnalysisDisplay subclass you implemented above. Depending on whether persistentDock() returns true (the default) or false, this is called once and the same dock/display is reused for every result, or a new dock and display are created for every result (e.g. for side-by-side comparisons).

    • createAnalysisSource() simply needs to return a new instance of your class.

    • 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 run() each time the actor triggers an analysis.

    • 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.

  • The actor finally needs to call the method MAnalysisControl::run(). This will cause the control to talk to the actor, prepare the request, run the analysis, and update the result dock’s display with the result.

Examples

  • MValueExtractionAnalysis takes a position in 3-D 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. This is currently only implemented for isosurfaces in the raycaster actor.

  • 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.