Advanced DeepSee Modeling Guide
Defining Plugins
[Back] [Next]
Go to:

This chapter describes how to define plugins, which are a specialized form of KPI. It discusses the following:

Before reading this chapter, be sure to read the previous chapters on KPIs.
For a comparison of plugins with other kinds of model elements, see the chapter Summary of Model Options in Defining DeepSee Models.
A plugin is a class that defines one or more computations to use in the Analyzer and in queries. A plugin has the following features:
Plugins are especially appropriate for complex or time-consuming computations. For example, you might have a computation that uses several different parts of the source record, as well as external information; a plugin would be suitable in this case.
How Plugins Can Be Used
Depending on the plugin class, you can use it in some or all of the following ways:
Available Plugin Classes
The %DeepSee.PlugIn package provides several plugin classes for you to use in calculated measures. These classes are as follows:
Another sample plugin class is DeepSee.Model.KPIs.PluginDemo, in the SAMPLES namespace. This plugin class is defined with PLUGINTYPE as "Pivot" and thus can be used directly.
Samples That Demonstrate Plugins
In the SAMPLES namespace, see the dashboards in the KPIs & Plugins folder:
Requirements for a Simple Plugin
To define a simple plugin, create a class as follows:
Implementing %OnCompute()
For each pivot table cell where the plugin is used, the plugin executes the listing query and then executes the %OnCompute method. This method has the following signature:
Method %OnCompute(pSQLRS As %SQL.StatementResult, pFactCount As %Integer) As %Status
In your implementation of this method, do the following:
  1. Iterate through the statement result. To do so, use the %Next() method of this instance.
  2. As needed, retrieve values for each row. The statement result instance (pSQLRS) provides one property for each field in the listing query; the name of the property is the same as the field name.
    For example, in the previous section, %OnGetListingSQL() retrieves a single field, MxTextScore. In this case, pSQLRS has a property named MxTextScore.
  3. Perform the desired computations.
  4. Set the properties of the plugin instance, as described in the previous chapter. At a minimum, set the following properties:
For example:
 // place answer in KPI output
 Set ..%seriesCount = 1
 Set ..%seriesNames(1) = "PluginDemo"
 //set Count property of KPI -- just use received pFactCount
 Set ..%data(1,"PatientCount") = pFactCount
 // iterate through result set to get HighScoreCount 
 set n = 0
 Set highcount = 0
 While (pSQLRS.%Next(.tSC)) {
   If $$$ISERR(tSC) Quit
   set n = n + 1

   Set testscore = pSQLRS.MxTestScore
   if (testscore>95) {
     Set highcount = highcount + 1

 Set ..%data(1,"HighScoreCount") = highcount
This is an extract from DeepSee.Model.KPIs.PluginDemo in SAMPLES, which is available in the Analyzer for use with the Patients cube.
Indicating State of Completion
Plugins are executed asynchronously. When a query containing plugins is executed, the query can be complete before the plugins have completed execution. In this case, there are cells whose results are pending. Within these cells, you can display the plugin current status (as the string n% complete). To do so, within %OnCompute(), periodically invoke the %SetPercentComplete() instance method; the argument is an integer between 0 and 100. For example, you could do the following while iterating through the statement result:
    // update pct complete
    If (n#100 = 0) {
        Do ..%SetPercentComplete(100*(n/pFactCount))
The appropriate approach depends on the logic in %OnCompute(). In some cases, the majority of the computation time might occur outside of this iteration.
The pivot table automatically refreshes when the results are available.
Creating a Plugin for Multiple Cubes
The previous sections describe how to create a plugin that can be used with a single cube or subject area. You can also create a plugin that can be used in multiple cubes. In practice, this is difficult to do because it is usually necessary to programmatically determine the fields to query.
To create a plugin that you can use with multiple cubes, use the following additional instructions:
For examples, see %DeepSee.PlugIn.Median and %DeepSee.PlugIn.Percentile.
Determining the Listing Fields Programmatically
If the query for the plugin specifies LISTINGSOURCE as "FactTable", there are additional tools that enable you to programmatically determine the fields to use in %OnGetListingSQL(). You can do the following:
For examples, see %DeepSee.PlugIn.Median and %DeepSee.PlugIn.Percentile. Also see the class reference for the %DeepSee.Utils class.
Filtering the Listing
Plugins provide a feature that is not available in other scenarios: namely, the ability to specify which records to use when a detail listing is displayed. By default, when a user requests a detail listing for a given cell or set of cells in the results, DeepSee displays a listing that shows all the records associated with those cells. In some cases, however, it is preferable to show a subset of them. For example, the sample DeepSee.Model.KPIs.PluginDemo has a plugin property called HighScoreCount. The following shows an example MDX query that uses this plugin property as a measure:
SELECT NON EMPTY {[Measures].[%COUNT],%KPI("PluginDemo","HighScoreCount",,"%CONTEXT")} ON 0,NON EMPTY [AllerSevD].[H1].[Allergy Severities].Members ON 1 FROM [PATIENTS]
                       Patient Count       HighScoreCount
1 Nil known allergi               158                   12
2 Minor                           113                    7
3 Moderate                        103                    5
4 Life-threatening                133                    9
5 Inactive                        122                    8
6 Unable to determi               119                    6
7 No Data Available               385                   29
Consider the row for Nil known allergies. If you display a listing for either cell, by default, DeepSee displays a listing that consists of 158 records, because there are 158 patients with no known allergies. But the purpose of the HighScoreCount measure is to count the patients with scores above a given threshold, so when we display the detail listing for the cell HighScoreCount in this row, we might prefer to see only the patients with scores above that threshold.
To apply this sort of filtering to a plugin, include the following logic in your implementation of %OnCompute(), for any source class ID that should be shown in the listing:
   set ..%data("IDLIST",pluginProperty,sourceClassID) = ""
Where pluginProperty is the name of the plugin property that should use this filtering, and sourceClassID is the ID in the source class. (The ID should be a source class ID even if plugin otherwise uses the fact class. To make the source class ID available to the plugin, add %sourceId to the field list.)
For example, edit the sample DeepSee.Model.KPIs.PluginDemo, find the part of %OnCompute() that sets the highcount variable, and modify it as follows:
        if (testscore>95) {
            Set highcount = highcount + 1
            Set tHighScoreId = pSQLRS.sourceId
            Set ..%data("IDLIST","HighScoreCount",tHighScoreId)=""
This change filters the listing when the HighScoreCount plugin property is used. When other plugin properties are used, the listing is not filtered. A given plugin could define separate filtering for each plugin property that it defines.
For a given plugin property, if %data("IDLIST",pluginProperty) is not defined, the listing shows all the records associated with the given cell or cells.
Available Error Logging
If a plugin encounters an error, DeepSee writes to the error log file in the manager’s directory. The name of this file is DeepSeeTasks_namespace.log.
Defining a Calculated Member That Uses a Plugin
For any plugin (and any other KPI), you can create a calculated member that retrieves values from it. Then users can drag and drop this member within the Analyzer. To create such a calculated member: