Analytic Templates

Hierarchical Analytic Template: Defining the Analytic's Input/Output Structure

The analytic template defines the input and output structures required by the analytic. This reference describes how the input and output structure is defined for an hierarchical analytic template.

The analytic template name (hierarchical, descriptive) describes the data format type you are working with. Hierarchical data format is input and output data that can be arbitrarily nested.

An analytic run by the Analytics Runtime engine must have a template conforming to the specification described in the Hierarchical Analytic Template Structure Reference. The template is then uploaded to the Analytics Catalog as an artifact and assigned "Template" type.

Consider an analytic that takes an input JSON structure similar to the following.

{
    "data": {
        "timeseries": {
            "time_stamp": [ <list of input time stamp values> ],
            "column1": [<list of double values> ],
            "column2": [<list of double values> ]
        }
    },
    "constants": {
        "constant1": <constant value>
    }
}

The following is an example with sample data.

{
    "data": {
        "timeseries": {
            "time_stamp": [ 000003242, 000004242, 000005242 ],
            "column1": [ 10.0, 20.0, 30.0 ],
            "column2": [ 1.0, 2.0, 3.0 ]
        }
    },
    "constants": {
        "constant1": 55
    }
}

The analytic produces output similar to the following.

{
    "data": {
        "timeseries": {
            "time_stamp": [ <list of time stamp values> ],
            "results": [ <list of values> ]
        }
    }
}

The following is an example with sample data.

{
    "data": {
        "timeseries": {
            "time_stamp": [ 000003242, 000004242, 000005242 ],
            "results": [ 10.0, 20.0, 30.0 ]
        }
    }
}

The following is a JSON sample template that can be used to define the input and output structures.

{
    "analyticName": "analyticWith2ColumnsAnd1Constant",
    "analyticVersion": "V1.0",
    "inputPortDefinitions": [
        {
            "portType": "COMPOSITE",
            "portName": "data",
            "variable": false,
            "childrenPorts": [
                {
                    "portName": "timeseries",
                    "portType": "TIMESERIES_ARRAY",
                    "required": true,
                    "variable": false,
                    "columns": [
                        {
                            "portName": "column1",
                            "portType": "FIELD",
                            "variable": false,
                            "dataType": "DOUBLE_ARRAY",
                            "required": true
                        },
                        {
                            "portName": "column2",
                            "portType": "FIELD",
                            "variable": false,
                            "dataType": "DOUBLE_ARRAY",
                            "required": true
                        }
                    ]
                }
            ]
        },
        {
            "portType": "COMPOSITE",
            "portName": "constants",
            "childrenPorts": [
                {
                    "portType": "FIELD",
                    "portName": "constant1",
                    "variable": false,
                    "dataType": "DOUBLE",
                    "required": true
                }
            ]
        }
    ],
    "outputPortDefinitions": [
        {
            "portName": "data",
            "portType": "COMPOSITE",
            "required": true,
            "variable": false,
            "childrenPorts": [
                {
                    "portName": "time_series",
                    "portType": "TIMESERIES_ARRAY",
                    "required": true,
                    "variable": false,
                    "columns": [
                        {
                            "portName": "results",
                            "portType": "FIELD",
                            "variable": false,
                            "dataType": "DOUBLE_ARRAY",
                            "required": true
                        }
                    ]
                }
            ]
        }
    ]
}

Descriptive Analytic Template: Defining the Analytic's Input/Output Structure

The analytic template defines the input and output structures required by the analytic. This reference describes how the input and output structure is defined for a descriptive analytic template.

The analytic template name (hierarchical, descriptive) describes the data format type you are working with. Descriptive data format is input and output data that is flat in structure but has self-describing attributes such as the data type and data size.

An analytic run by the Analytics Runtime engine must have a template conforming to the specification described in the Descriptive Analytic Template Structure Reference. The template is then uploaded to the Analytics Catalog as an artifact and assigned "Template" type.

Consider an analytic that takes an input JSON structure similar to the following.

{
    "internalRecords": [],
    "records": [
        {
            "type": "DOUBLE",
            "name": "constant1",
            "data": [<constant value>],
            "arraySizes": [1]
        }
    ],
    "timeSeriesRecords": [
        {
            "name": "time_series",
            "timestamps": [ <list of input time stamp values> ],
            "data": [
                {
                    "type": "DOUBLE",
                    "name": "numberArray1",
                    "data": [<list of double values>],
                    "arraySizes": [<size of data values>]
                },
                {
                    "type": "DOUBLE",
                    "name": "numberArray2",
                    "data": [<list of double values>],
                    "arraySizes": [<size of data values>]
                }
            ]
        }
    ]
}

The following is an example with sample data.

{
    "internalRecords": [],
    "records": [
        {
            "type": "DOUBLE",
            "name": "constant1",
            "data": [
                55.0
            ],
            "arraySizes": [
                1
            ]
        }
    ],
    "timeSeriesRecords": [
        {
            "name": "time_series",
            "timestamps": [
                "2016-02-17T18:27:49.601",
                "2016-02-17T18:27:49.602",
                "2016-02-17T18:27:49.603"
            ],
            "data": [
                {
                    "type": "DOUBLE",
                    "name": "numberArray1",
                    "data": [
                        1.0,
                        2.0,
                        3.0
                    ],
                    "arraySizes": [
                        3
                    ]
                },
                {
                    "type": "DOUBLE",
                    "name": "numberArray2",
                    "data": [
                        100.0,
                        200.0,
                        300.0
                    ],
                    "arraySizes": [
                        3
                    ]
                }
            ]
        }
    ]
}

The analytic produces output similar to the following.

{
  "internalRecords": [],
  "records": [],
  "timeSeriesRecords": [
    {
      "name": "time_series",
      "timestamps": [<list of time stamp values>],
      "data": [
        {
          "type": "DOUBLE",
          "name": "results",
          "data": [<list of values>],
          "arraySizes": [<size of values>]
        }
      ]
    }
  ]
}

The following is an example with sample data.

{
  "internalRecords": [],
  "records": [],
  "timeSeriesRecords": [
    {
      "name": "time_series",
      "timestamps": [
        "2016-02-17T18:27:49.601",
        "2016-02-17T18:27:49.602",
        "2016-02-17T18:27:49.603"
      ],
      "data": [
        {
          "type": "DOUBLE",
          "name": "results",
          "data": [
            101.0,
            202.0,
            303.0
          ],
          "arraySizes": [
            3
          ]
        }
      ]
    }
  ]
}

The following is a JSON sample template that can be used to define the input and output structures.

{
  "name": "TimeseriesAdder",
  "description": "",
  "packageName": "",
  "codeLanguage": "JAVA",
  "version": "1.0.0",
  "author": "Predix Analytics team",
  "inputDataPortDefinitions": [
    {
      "name": "time_series",
      "description": "",
      "dataType": "TimeSeries",
      "valueRequired": false,
      "variable": false,
      "arrayDimensions": 0
    },
    {
      "timeSeriesName": "time_series",
      "name": "numberArray1",
      "description": "",
      "dataType": "Double",
      "valueRequired": true,
      "variable": false,
      "arrayDimensions": 1
    },
    {
      "timeSeriesName": "time_series",
      "name": "numberArray2",
      "description": "",
      "dataType": "Double",
      "valueRequired": true,
      "variable": false,
      "arrayDimensions": 1
    }
  ],
  "constantDataPortDefinitions": [
    {
      "name": "constant1",
      "description": "",
      "dataType": "Double",
      "valueRequired": true,
      "variable": false,
      "arrayDimensions": 0
    }
  ],
  "outputDataPortDefinitions": [
    {
      "name": "time_series",
      "description": "",
      "dataType": "TimeSeries",
      "valueRequired": false,
      "variable": false,
      "arrayDimensions": 0
    },
    {
      "timeSeriesName": "time_series",
      "name": "results",
      "description": "",
      "dataType": "Double",
      "valueRequired": false,
      "variable": false,
      "arrayDimensions": 1
    }
  ]
}

Creating an Hierarchical Analytic Template

An analytic template defines the format of the input and output JSON structures. Follow these steps to create an hierarchical analytic template.

About This Task

For more details on how to define a port, see Hierarchical Analytic Template Structure Reference.

Procedure

  1. Complete the analyticName, analyticVersion, and comment fields in the JSON structure.
  2. Define the analytic's input ports in the inputPortDefinitions array of the template.
  3. Define the analytic's output ports in the outputPortDefinitions array of the template.
  4. Define the data structure of each input and output port, including the portName, portType, and any additional properties. Each port represents one JSON node in the actual analytic data.
  5. Define the analytic's input model ports in the inputModelDefinitions array of the template if using an analytic that uses a trained model.

Sample Hierarchical Analytic Template Structure

The template will follow this basic structure.

{
    "analyticName": <analytic_name>,
    "analyticVersion": <analytic_version>,
    "comment": [<comment>],
    "inputPortDefinitions": [ ],
    "inputModelDefinitions": [ ],
    "outputPortDefinitions": [ ]
}

Creating a Descriptive Analytic Template

An analytic template defines the format of the input and output JSON structures. Follow these steps to create a descriptive analytic template.

About This Task

For more details on how to define a port, see Descriptive Analytic Template Structure Reference.

Procedure

  1. Complete the name, description, packageNamecodeLanguage, version, and author fields in the JSON structure.
  2. Define the analytic's input ports in the inputDataPortDefinitions array of the template.
  3. Define the analytic's constant ports in the constantDataPortDefinitions array of the template.
  4. Define the analytic's output ports in the outputDataPortDefinitions array of the template.
  5. Define the data structure of each input, constant, and output port, including the name, dataType, arrayDimensions, timeSeriesName, and any additional properties.

Sample Descriptive Analytic Template Structure

The template will follow this basic structure.

{
    "name" : <String>,
    "description" : <String>,
    "packageName" : <String>,
    "codeLanguage" : <String>,
    "version" : <String>,
    "author" : <String>,
    "inputDataPortDefinitions" : [<List of DataPortDefinition>],
    "constantDataPortDefinitions" : [<List of DataPortDefinition>],
    "outputDataPortDefinitions" : [<List of DataPortDefinition>]
}

Hierarchical Analytic Template Structure Reference

An analytic template defines the format of the input and output JSON structures. This reference describes how the JSON objects in an hierarchical analytic template are used to generate the input structure required by the analytic.

Overview

The analytic template name (hierarchical, descriptive) describes the data format type you are working with. Hierarchical data format is input and output data that can be arbitrarily nested.

Each analytic has one template that is stored in the Analytics Catalog. The template is a JSON structure. For more information about JSON terminology, see http://www.json.org.

Type: AnalyticTemplate

This is the overall structure of an hierarchical analytic template.

{
    "analyticName":<string>,
    "analyticVersion":<string>,
    "comment":[<string>],
    "inputPortDefinitions":[<List of PortDefinition>],
    "inputModelDefinitions":[<List of InputModel>],
    "outputPortDefinitions":[<List of PortDefinition>]
}

See the following table for a description of the elements in an AnalyticTemplate.

FieldDescription
analyticNameInformational only. It does not correlate with any values in the input/output JSON structure.
analyticVersionInformational only. It does not correlate with any values in the input/output JSON structure.
comment(Optional) Informational only. An array of strings. It does not correlate with any values in the input/output JSON structure.
inputPortDefinitionsThe list of port definitions defining the top level JSON objects in the input.
inputModelDefinitions The names of input models needed by the analytic. The runtime will get these models (by name) from the orchestration configuration and pass them in to the analytic as a map of byte arrays.
outputPortDefinitionsThe list of port definitions defining the top level JSON objects in the output.

Type: PortDefinition

The inputPortDefinitions and outputPortDefinitions elements of the analytic template contain arrays of PortDefinitions that specify the inputs and outputs of the analytic. There are several types of PortDefinitions, but they all have the following elements in common.

{
    "comment":[<string>],
    "portName":<string>,
    "portType":<string>,
    "variable":<boolean>
}
Is extended by the following.
  • FieldPort
  • TimeseriesArrayPort
  • CompositePort

See the following table for a description of the elements in a PortDefinition.

FieldDescription
comment(Optional) Informational only. An array of strings. It does not correlate with any values in the input/output JSON structure.
portNameBecomes the name in the name,value pair in the analytic's input or output JSON object. Shows as {“<portName>”: in the JSON object for this port definition.
portTypeDefines the nature of the value part of this JSON object. Predix Analytics Services supports the following value types:
  • COMPOSITE type: the value is an inner JSON object defined by a list of inner PortDefinitions.
  • FIELD type: the value is a single value or array of values such that the value is obtained from the port-to-field map.
  • TIMESERIES_ARRAY: the value is a Predix Analytic Time Series JSON object (see Type: TimeseriesArrayPort).
variable(Optional) True when the value in the analytic's input or output JSON object is a JSON array. The array's values will be enclosed in [ ]. Default value is false.

Type: FieldPort

A FieldPort is a type of PortDefinition that holds the actual data values to be passed to/from the analytic. A FieldPort defines a leaf node in the analytic's JSON structure.

{
    "comment":[<string>],
    "portName":<string>,
    "portType":<string>,
    "variable":<boolean>,
    "engUnit":<string>,
    "dataType":<string>,
    "required":<boolean>,
    "timestampShared":<string>
}

Extends from PortDefinition.

FieldPort definitions correspond to "<port name>": <value determined at runtime (see Port-to-Field Map description)> pairs into the JSON structure.

In addition to the common elements of a PortDefinition, a FieldPort contains the following elements.

FieldDescription
engUnit(Optional, Reserved for future use) The engineering units of the data in this field.
dataTypeThe data type in which the analytic expects input data and produces output data. The framework will convert values to and from this data type between the analytic and the data source. Possible values are: 'LONG', 'INTEGER', 'DOUBLE', 'FLOAT', 'STRING', 'BOOLEAN', "BOOLEAN_ARRAY", 'LONG_ARRAY', 'INTEGER_ARRAY', 'DOUBLE_ARRAY', 'FLOAT_ARRAY', 'STRING_ARRAY'.
required(Optional) Whether or not this field is required.
timestampSharedWhether data includes separate timestamps for each indexed block of generated data for variable input port.
  • false: if separate timestamps block is needed for variable input port.
  • true: if separate timestamp block is not needed.

Type: TimeseriesArrayPort

A TimeseriesArrayPort is a type of PortDefinition that is used to define a JSON structure that represents a time series data table. This is the overall structure of a TimeseriesArrayPort.

{
    "comment": [<string>],
    "portName": <string>,
    "portType": <string>,
    "variable": <boolean>,
    "columns": [<List of FieldPorts>]
}

Extends from PortDefinition.

In addition to the common elements of a PortDefinition, a TimeseriesArrayPort holds an array of FieldPorts called columns.

Field: columns

Contains FieldPort column definitions where each FieldPort column is an array data type. The generated JSON structure will contain one JSON array for each FieldPort column and an additional 'time_stamp' array object containing the timestamps of the table values, as the example shows below.

Note: All columns in the time series array will share the same time stamps. The quality attribute from Time Series is not supported.
{
    “<timeseries array port name>” : {
        “time_stamp” : [<timestamp values associated with field port values>],
        [<list of JSON objects for the field port definitions>]
    }
}
Note: The time series values for each of the field port definitions must contain the same set of time stamps. If they do not, the platform will trigger an error.

Type: CompositePort

A CompositePort is a type of PortDefinition that contains other PortDefinitions. This is the overall structure of a CompositePort.

{
    "comment":[<string>],
    "portName":<string>,
    "portType":<string>,
    "variable":<boolean>,
    "childrenPorts":[<List of PortDefinition>]
}

Extends from: PortDefinition.

In addition to the common elements of a PortDefinition, a CompositePort holds an array of childrenPorts.

Field: childrenPorts
Contains a list of inner (children) PortDefinitions. When the variable flag is false, the generated JSON object (corresponding to the composite port) will contain each child port as a direct child node of the composite port, following this pattern.
{
    “<composite port name>”: {
        <JSON structure from the Port-to-Field Map for the first child port definition>, 
		
        ...
		
        <JSON structure from the Port-to-Field Map for the last child port definition>
    } 
}
When the variable flag is true, the generated JSON object (corresponding to the composite port) will wrap the child nodes in an array under the composite port, following this pattern.
{
    "<composite port name>" : [
        {
            <JSON structure from Port-to-Field Map for the first child>,
            
            ...,
            
            <JSON structure from Port-to-Field Map for the last child>,        
        },
        
        ...,
        
        {
            <JSON structure from Port-to-Field Map for the first child>,
            
            ...,
            
            <JSON structure from Port-to-Field Map for the last child>,        
        }
    ]
}

Type: InputModel

An InputModel is a named byte array that the analytic uses in its processing. The values for the model are managed as part of an orchestration configuration and are associated with an asset context.

{ "modelPortName": <string>,
 "comments" : [<string>] }

See the following table for a description of the elements in an InputModel.

FieldDescription
modelPortNameThe name the analytic uses to pull the model from the map of byte arrays.
comment(Optional) Comments describing the model.

Template Examples

Analytic templates are used at runtime in conjunction with port-to-field map configurations to control the runtime engine's handling of the analytic input and output. See Samples of Hierarchical Analytic Templates and Port-to-Field Maps.

Descriptive Analytic Template Structure Reference

An analytic template defines the format of the input and output JSON structures. This reference describes how the JSON objects in a descriptive analytic template are used to generate the input structure required by the analytic.

Overview

The analytic template name (hierarchical, descriptive) describes the data format type you are working with. Descriptive data format is input and output data that is flat in structure but has self-describing attributes such as the data type and data size.

Each analytic has one template that is stored in the Analytics Catalog. The template is a JSON structure. For more information about JSON terminology, see http://www.json.org.

Type: AnalyticTemplate

This is the overall structure of a descriptive analytic template.

{
    "name" : <String>,
    "description" : <String>,
    "packageName" : <String>,
    "codeLanguage" : <String>,
    "version" : <String>,
    "author" : <String>,
    "inputDataPortDefinitions" : [<List of DataPortDefinition>],
    "constantDataPortDefinitions" : [<List of DataPortDefinition>],
    "outputDataPortDefinitions" : [<List of DataPortDefinition>]
}
FieldDescription
nameName of the analytic. Must be alphanumeric and must start with a letter.
descriptionDescription of the analytic. It can be in HTML format. However, no image tags are allowed.
packageNameReserved for future use.
codeLanguageReserved for future use.
versionVersion of the analytic.
authorAuthor of the analytic.
inputDataPortDefinitionsList of input port definitions
constantDataPortDefinitionsList of constant port definitions.
outputDataPortDefinitionsList of output port definitions.

Type: DataPortDefinition

The inputDataPortDefinitions, constantDataPortDefinitions and outputDataPortDefinitions elements of the analytic template contain arrays of DataPortDefinition that specify the inputs, constants and outputs of the analytic.

{
    "timeSeriesName" : <String>,
    "name" : <String>,
    "description" : <String>,
    "dataType" : <String>,
    "variable" : <Boolean>,
    "arrayDimensions" : <Integer>,
    "validators" : [<List of String>]
}

See the following table for a description of the elements in a DataPortDefinition.

FieldDescription
timeSeriesNameLeave field blank for non-timeseries port definition. For timeseries port definition this is the name of the timeseries
namePort name.
descriptionDescription of the data port.
dataTypeThe data type in which the analytic expects input data and produces output data. The framework will convert values to and from this data type between the analytic and the data source. Possible values are: DOUBLE, INTEGER, LONG, STRING, BOOLEAN, DATETIME, DATE, TIME, CUSTOM, TIMESERIES.
variableSet value to true if port can have a variable number of ports at runtime.
arrayDimensionsIndicate the number of dimensions (i.e. 0 is a single value, 1 is a 1-dimensional array, 2 is a 2-dimensional array, etc.).
validatorsReserved for future use.

Template Examples

Analytic templates are used at runtime in conjunction with Port-to-Field Map configurations to control the runtime engine's handling of the analytic input and output. See Samples of Descriptive Analytic Templates and Port-to-Field Maps.