Creating event-based trace step templates

The procedure for creating a new trace step template has been explained before in section General approach. While the creation of signals and parameters is identical for all kinds of templates, the implementation of the actual analysis instructions is distinctly different.

As regards event-based trace step templates, the user can create his own Python functions (so-called Next functions) and tie them to signals. The purpose of tying Python functions to signals is that during a trace analysis ecu.test calls the Python functions passing on the concrete values of the signals to which the functions are tied. Please note that Next functions are only called at those timestamps at which one or more bound signals have a sample value.

In addition to those Python functions an Init and a Finalize function are available which can be called at the beginning and the end of each analysis run and be filled with Python code by the developer.

../../../../../_images/TraceStepTemplates_PythonEventBasedExample.png

The interfaces of the Init and Finalize functions:

def Init(dataContainer, parameters, report):
    ...
def Finalize(dataContainer, parameters, report):
    ...

On being called by ecu.test both functions receive two parameters:

dataContainer:

provides access to ecu.test variables. For a description of the interface of the object passed refer to the Trace Analysis API documentation.

parameters:

a Python dictionary containing the parameter values indicated in the trace step for each parameter defined in the template.

report:

allows access to the test report. The description of the interface of that object can be found in the Trace Analysis API documentation.

The interface of functions (Next functions) tied to signals is:

def Next(event, hold, dataContainer, parameters, report):
    ...

Those functions are called by ecu.test in chronologically ascending order, one time per timestamp at which one of the signals to which the function is tied shows a measured value. If several signals have a measured value for a timestamp, the function is called just one time all the same. All signals having a measured value for the timestamp are passed to the function in the parameter event.

On being called by ecu.test the functions just mentioned receive four parameters:

event:

Provides access to the current trace event. Here the timestamp (event.GetTime()) and the current signal values can be queried (event.GetValue("SignalName")) For a description of the interface of the object passed refer to the Trace Analysis API documentation.

hold:

ecu.test passes on an object containing, as a kind of hold register, the last known value of all signals to which the function is tied. As with the event object, signal values can be queried here by hold.GetValue("SignalName"). For a description of the interface of the object passed see ecu.test API documentation.

dataContainer:

Provides access to ecu.test variables and the parameters. For a description of the interface of the object passed see ecu.test API documentation.

parameters:

A Python dictionary containing the parameter values indicated in the trace step for each parameter defined in the template.

report:

Allows access to the test report. The description of the interface of that object can be found in the Trace Analysis API documentation.

Info

dataContainer object as variable memory

As is customary with Python, all variables used in functions are local which means they are “empty” again on every function call. To keep intermediate results persistent across several calls ecu.test provides the object dataContainer. During an analysis run ecu.test passes the same dataContainer object to all functions of a trace step. That can be used for setting up a persistent variable, e.g. in the Init function via dataContainer.intermediateResult = 0. That variable is later available for reading and writing access in the Next function as well as the Finalize function.

Example MinimumMaximum

The trace step template “MinimumMaximum” of the scope of supply illustrates the principal functioning of Python-based trace step templates:

../../../../../_images/TraceStepTemplates_MinMaxExample.png

MinimumMaximum trace step template with Next method opened for editing

A new signal is created via button (1). An expressive name should be chosen (2) (in the example “Signal”). The signal abstracts the name in the recording from the one used in the trace step template. So the same template can be used without adaptation for evaluating several signals. A new function is created via (3) which in (4) is assigned a new name. Button (5) serves to select the signals which lead to calling the function when they occur in the recording.

In the example the function Next is called each time the signal occurs. The current signal value is assigned to the variable``value`` (value = event.GetValue("Signal")).

The two variables dataContainer.min and dataContainer.max are initialized in the Init function:

def Init(dataContainer, parameters, report):
    dataContainer.min = ''   # min(x, '') yields x
    dataContainer.max = None # max(x, None) yields x

Finally the result is put out by the function Finalize:

def Finalize(dataContainer, parameters, report):
    report.SetResultText("Min: %s\nMax: %s" \
           % (dataContainer.min, dataContainer.max))

The flow is as follows:

Let us suppose the signal has the values 2, 1, -5, 6, 0. On the first occurrence the function Next is called. The variable value carries 2. The function min of datacontainer.min ("")and 2 provides 2. So in datacontainer.min there is 2. The function max of datacontainer.max (None)and 2 also provides 2. So after the first function call there is 2 in datacontainer.min and datacontainer.max. On the second function call min of 2 and 1 and max of 2 and 1 is created. So in datacontainer.min there is 1 and in datacontainer.max there is 2. The next values are handled in the same way so that in the end datacontainer.min contains -5 and datacontainer.max contains 6 which are written into the test report in the function Finalize.

Adapting default templates using the example CalculateMinMax

Default templates cannot be modified directly. However one may edit a copy of a default template and use it like an own template.

In the tab Trace step templates you can find the template “CalculateMinMax” in the file tree of the Default templates located at StandardTraceStepTemplates/Calculate. Since default templates cannot be modified they have to be copied to “My templates” first. For this right click on the template CalculateMinMax to open the context menu and select Copy. Next make a right click somewhere in the file tree of “My templates”, for instance right click on the folder TraceStepTemplates and choose Paste from the context menu. A dialog will appear asking whether the references of packages that use the template CalculateMinMax shall be updated. Close this dialog by clicking on No. Now the copy of the template is shown in the file tree of “My templates”. This copy may be edited by performing a double click on it.

Info

If the own template has the same ID like a default template, then referencing this ID will run the own template. For instance, if a copy of CalculateMinMax is saved in the folder Calculate, the default template will be hidden by the own template.