TPT Assessment-Language - Tutorial and Reference Book - PikeTec
TPT Assessment-Language - Tutorial and Reference Book - PikeTec
TPT Assessment-Language - Tutorial and Reference Book - PikeTec
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
<strong>Tutorial</strong> <strong>and</strong> <strong>Reference</strong> <strong>Book</strong><br />
Version 3.0<br />
29. February 2008
Contents<br />
Page 2 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
1 Introduction _____________________________________________________________________________ 3<br />
1.1 Paradigm of the assessment language___________________________________________________ 4<br />
1.2 Some words about intervals <strong>and</strong> assessment variables __________________________________ 4<br />
1.2.1 Annotations of assessments _____________________________________________________________ 7<br />
2 <strong>Assessment</strong> reference manual __________________________________________________________ 9<br />
2.1 Data types ________________________________________________________________________________ 9<br />
2.2 Creation of assessment variables _______________________________________________________ 10<br />
2.3 Operations for assessment variables ____________________________________________________ 12<br />
2.4 Operations for time intervals ____________________________________________________________ 19<br />
2.5 Operations for records (file I/O operators) ______________________________________________ 22<br />
2.5.1 Reading records from file system ______________________________________________________ 23<br />
2.5.2 Writing records to the file system ______________________________________________________ 24<br />
2.5.3 Writing the default output record to the file system ___________________________________ 25<br />
2.5.4 Accessing reference data in assessment scripts ________________________________________ 26<br />
2.6 Global operations _______________________________________________________________________ 27<br />
2.7 Signal processing functions: value computations _______________________________________ 28<br />
2.8 Signal processing functions: signal computations ______________________________________ 30<br />
2.8.1 Filter operations ________________________________________________________________________ 33<br />
2.9 Temporal regular expressions ___________________________________________________________ 38<br />
2.10 Context intervals <strong>and</strong> the during operator ______________________________________________ 41<br />
2.10.1 During-Operator _______________________________________________________________________ 41<br />
2.10.2 “This” operator _________________________________________________________________________ 42<br />
2.11 Transformations of the assessment pre-processor _____________________________________ 42<br />
2.11.1 Compatibility with former versions of <strong>TPT</strong> _____________________________________________ 42<br />
2.11.2 Obsolete assessment functions in <strong>TPT</strong> 2.6 _____________________________________________ 42
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 3<br />
1 Introduction<br />
The goal of the test assessment is to determine whether system behaviours are correct or<br />
not. In order to run test assessments automatically the expected behaviour must be<br />
specified for each test case. The test assessment may be thought of as the evaluation of<br />
the test pass criteria, as in simple cases ‘pass/fail’ or ‘within given limits’.<br />
To get a better underst<strong>and</strong>ing of the test assessments of <strong>TPT</strong> it is useful to make clear the<br />
major goals of the assessment. There are two main points.<br />
1. The main goal of the test assessment is to determine if the system behaves<br />
correctly or incorrectly for the specific test case<br />
2. Besides this go/no-go health check a system typically contains information which<br />
can help us underst<strong>and</strong> what is happening in the system during test execution.<br />
This information is of particular interest when the test ‘fails’ <strong>and</strong> we wish to<br />
investigate the reasons for failure.<br />
In many practical cases the first goal of the assessment, namely the binary decision<br />
(correct/incorrect), is problematic or even impossible. There are different reasons for this.<br />
For example in embedded system design it is often impossible to access or measure all<br />
relevant signals, or the formal description of expected values may be too complex to<br />
make automated test assessments.<br />
So in reality the automated test tool can monitor the behaviour of system elements, but<br />
the analysis of the result is done manually by stakeholders or test personnel<br />
This means that in many practical cases one dismisses the fully automated test<br />
assessment that gives only a “true” or “false”. For that reason the test assessment of <strong>TPT</strong> is<br />
based on calculations of system properties rather than bottom line “true” <strong>and</strong> “false”. In<br />
the following section the basic ideas of the assessment modelling using <strong>TPT</strong> assessments<br />
are described.
Page 4 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
1.1 Paradigm of the assessment language<br />
The goal of the <strong>TPT</strong> test assessment is to calculate <strong>and</strong> extract summary information from<br />
the usually large amount of test data to determine whether a test case was successful or if<br />
an error occurred. Thus the test assessment can be seen as the challenge of abstracting a<br />
small set of adequate information about the system behaviour during the test from the<br />
very detailed <strong>and</strong> comprehensive data available.<br />
The <strong>TPT</strong> assessment language allows evaluation of the system characteristics required to<br />
assess system performance.<br />
A few examples: the duration of certain system-phases, adherence to defined signal limits,<br />
monotony properties, the maximum values of signals, etc. . Such characteristics are<br />
helpful as error indicators <strong>and</strong> they can simplify finding the cause of an error.<br />
Case 1: Observation of limits. Signals can be assigned limits <strong>and</strong> monitored for their<br />
adherence to the limit(s). Crossing a limit may not be all that is of interest; the duration,<br />
time <strong>and</strong> frequency of this non conforming behaviour can also be pertinent.<br />
Case 2: Comparison to reference signals. A signal x shall be compared to a signal xref.<br />
Again it may be important to monitor not only whether the signals differ but if the<br />
difference took place during a critical period or was particularly large, etc..<br />
Case 3: Relative timing of events. is the difference in time between the occurrence of<br />
event A (e.g. Signal x has the value 1) <strong>and</strong> the occurrence of event B shall be monitored.<br />
Case 4: <strong>Assessment</strong> periods. Analysis of the cases above may only be relevant during<br />
certain periods of the test. This means only in certain time intervals the observation of<br />
limits, the comparison to reference signals or the event timing is necessary. The<br />
assessment of a signal for example may only be defined during the initialization phase of<br />
a system.<br />
Case 5: Qualitative statements. During test assessment it shall be decided in which<br />
mode the system was operating at a certain time where mode is here something like<br />
NORMAL, OVERHEAT <strong>and</strong> OFF. Since the system mode may vary over time it is necessary<br />
to analyze the periods where a certain mode is valid.<br />
This list of examples is not exhaustive but shows that there is a variety of statements that<br />
may be relevant for the test assessment. The <strong>TPT</strong> assessment is designed to consider all<br />
such cases.<br />
1.2 Some words about intervals <strong>and</strong> assessment variables<br />
As mentioned previously, the goal of the assessment is to reduce the immense amount of<br />
data recorded during test execution to a summary of information required for evaluation<br />
of system performance.<br />
To support the specification <strong>and</strong> computation of such properties the <strong>TPT</strong> assessment uses<br />
three core concepts: time intervals, context intervals <strong>and</strong> assessment variables.<br />
time intervals are any time segments, mostly defined implicitly using the “during”<br />
operator but maybe also defined explicitly using<br />
<strong>TPT</strong>.Interval(start_time,end_time).
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 5<br />
A context interval is a time interval defined by the “during” operator in which a certain<br />
assessment is calculated. For example when a test result has been loaded the largest<br />
context interval is that for which the test result is defined. From this largest context<br />
interval smaller context intervals can be defined where certain assessments can be<br />
calculated. These context intervals can be defined explicitly in time (e.g. during<br />
<strong>TPT</strong>.Interval(10ms, 100ms):) or implicitly in time for example when a variable is<br />
larger than a certain value.<br />
An assessment variable is a variable used for this evaluation, which contains data<br />
structures relating the variable values to time intervals.<br />
The during keyword operates like ‘while(time intervals)’ of an assessment variable<br />
Let’s explain the meaning of these terms with a simple example: Assume that the system<br />
under test has an output signal called foo which can be observed <strong>and</strong> recorded during<br />
the test execution. Now we want to check whether or not the signal foo is always below a<br />
certain limit — say 100.0. The signal foo has been recorded during the test execution in<br />
the time period t=[0.0s … 10.5s). What does it mean to assess if there is an<br />
overflow?<br />
The first example to check the overflow is very simple:<br />
overflow = <strong>TPT</strong>.exists(foo(t) > 100.0);<br />
if overflow:<br />
# … do something if there is an overflow<br />
Here we evaluate whether or not there exists at least one point t in overall test case time<br />
t ∈ [0.0s, 10.5s] where signal foo exceeds the limit 100.0. The disadvantage of<br />
this computation is that overflow just carries the information true or false without<br />
any information about in which context (time) interval the overflow has been detected. We<br />
can get more information about the overflow behaviour by introducing the assessment<br />
variable concept:<br />
overflow = <strong>TPT</strong>.Boolean(); #declare the assessment variable<br />
overflow := <strong>TPT</strong>.exists(foo(t) > 100.0); #assignment to the assessment variable<br />
if overflow:<br />
# … do something if there is an overflow<br />
So what’s the difference here? overflow is now no longer a Boolean variable carrying<br />
values true or false but an assessment variable of type Boolean. <strong>Assessment</strong> variables<br />
must be declared before use. This is done in the first line of our example above. In the<br />
second line the result of the <strong>TPT</strong>.exists() operation is assigned to overflow with the<br />
following information:<br />
• the value of the variable (which is true or false depending on the result of<br />
<strong>TPT</strong>.exists()), <strong>and</strong><br />
• the context interval in which the assessment has been computed.
Page 6 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
This means that overflow carries not only the Boolean value but also the information<br />
about the interval where this information has been computed. The result can be<br />
represented as follows:<br />
<strong>Assessment</strong> variable Start Time End Time Value<br />
Overflow 0.0s 10.5s True<br />
We can even use this extra information during the subsequent calculations. As an<br />
example we can query where the computation of the overflow analysis has been started<br />
<strong>and</strong> where it has been stopped:<br />
# …<br />
if overflow:<br />
# … do something if there is an overflow<br />
from = overflow.getStartTime(); # start of the overflow analysis (== 0.0s)<br />
to = overflow.getEndTime(); # end of the overflow analysis (== 10.5s)<br />
This might still be not good enough. We know already that there is an overflow between<br />
0.0s <strong>and</strong> 10.5s but we do not know when exactly! To improve this situation we must<br />
modify the example again:<br />
overflow = <strong>TPT</strong>.Boolean();<br />
overflow := <strong>TPT</strong>.regexp([foo(t) > 100.0]);<br />
# …<br />
In this example, instead of using the operator <strong>TPT</strong>.exists() (which only can determine<br />
whether or not there is an instance when the expression was true), we use the operator<br />
<strong>TPT</strong>.regexp(). Without explaining the full power of this operator here, it is sufficient to<br />
know that it searches only for those time intervals where the expression foo(t) ><br />
100.0 is true. Depending on the behaviour of foo, this can be a single interval, multiple<br />
intervals, or not at all.<br />
Now the full power of assessment variables can be used since assessment variables can<br />
carry information about different context intervals. This is an important fact — therefore I<br />
repeat it: <strong>Assessment</strong> variables are not just variables carrying single values but data<br />
structures carrying different values according to different time intervals. For each time<br />
interval an assessment variable may or may not have a value. In our example the<br />
overflow variable has three definition intervals with three associated values (in our case<br />
all of them are true):<br />
<strong>Assessment</strong> variable Start Time End Time Value<br />
Overflow 2.2s 2.5s True<br />
Overflow 7.1s 7.2s True<br />
Overflow 7.4s 8.1s True<br />
The meaning of such assessment variables is very intuitive: In the intervals shown above<br />
the signal foo exceeds the limit 100.0. This information is much more detailed than the<br />
simple fact that there is an overflow somewhere. In addition the information carried by<br />
assessment variables can be exported to the test report:
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 7<br />
overflow = <strong>TPT</strong>.Boolean();<br />
overflow := <strong>TPT</strong>.regexp([foo(t) > 100.0]);<br />
<strong>TPT</strong>.export(overflow); # export this information to the test report<br />
Furthermore one can use the assessment variable to derive even more detail:<br />
overflow = <strong>TPT</strong>.Boolean();<br />
overflow := <strong>TPT</strong>.regexp([foo(t) > 100.0]);<br />
overflowAmount = <strong>TPT</strong>.Double(); # create an assessment var of type `double`<br />
during overflow:<br />
overflowAmount := <strong>TPT</strong>.integral(foo(t)-100); # integrate the exceedance<br />
In this example we define a second assessment variable called overflowAmount. It is<br />
defined by integrating the expression foo(t)-100. However, since the overflow is<br />
limited to 3 intervals we want to integrate the expression only in these intervals. This is<br />
done by means of the so called during-operator. It restricts the subsequent<br />
computation to the three intervals defined by the variable overflow. The result of this<br />
computation is the assessment variable overflowAmount which can be represented as<br />
follows:<br />
<strong>Assessment</strong> variable Start Time End Time Value<br />
overflowAmount 2.2s 2.5s 0.0002<br />
overflowAmount 7.1s 7.2s 0.0030<br />
overflowAmount 7.4s 8.1s 2.5662<br />
As you can see this is a very efficient way of dealing with information that is dependent<br />
on the associated context interval. In the example above the “severity” of the overflow (i.e.<br />
how much it deviates from the limit) depends on the context interval. The three different<br />
values of overflowAmount quantify the severity for a particular time interval.<br />
Summary:<br />
(1) Time intervals are time segments from a start to an end time. (2) All assessment<br />
computations are performed within a well-defined context (time) interval. The default<br />
time interval being used is the “overall time interval” of the test case (i.e. from the<br />
beginning of the test case to the end). (3) <strong>Assessment</strong> variables are able to store different<br />
values for different time intervals.<br />
1.2.1 Annotations of assessments<br />
The assessment scripts are always associated to a state of the <strong>TPT</strong> testlet. It is possible to<br />
write assessments that are valid for all the tests. Also it is possible to write assessments<br />
that are evaluated in certain states or even scenarios. Please use the assessment tab in the<br />
<strong>TPT</strong>-main window.<br />
<strong>Assessment</strong>s at a state are valid for the state itself <strong>and</strong> all sub-states. Thus assessment<br />
scripts at the top level will be executed for the complete automaton.<br />
<strong>Assessment</strong> Header:<br />
For functions of the assessment script that are more general <strong>and</strong> shall be visible for all<br />
assessments in all contexts the assessment header shall be used. Please use View/Edit<br />
Assess Header or the shortcut Ctrl-H.
Page 8 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
The assessment header will be included into the assessment-script prior to all other<br />
assessments <strong>and</strong> has no time-context.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 9<br />
2 <strong>Assessment</strong> reference manual<br />
The <strong>TPT</strong> <strong>Assessment</strong> <strong>Language</strong> is derived from the scripting language Python 1 . This means that in<br />
general <strong>TPT</strong> assessments can do everything that can be done with Python — with a few exceptions.<br />
This chapter explains the features of the <strong>TPT</strong> assessment language which are not features of st<strong>and</strong>ard<br />
Python.<br />
2.1 Data types<br />
The <strong>TPT</strong> assessment supports different data types for signals <strong>and</strong> constants. Every<br />
assessment variable has to be explicitly declared with a type. The possible types are listed<br />
below:<br />
Data type Data range<br />
Boolean true, false<br />
Int8 -128 … +127<br />
UInt8 0 ... 255<br />
Int16 -32768 … + 32767<br />
UInt16 0 … 65536<br />
Int32 -2147483648 … +2147483647<br />
UInt32 0 … 4294967296<br />
Int64 -2 63 … +(2 63 -1)<br />
Double Floating point double precision<br />
Float Floating point single precision<br />
Table 1: Available data types<br />
1<br />
We don’t give a general introduction to the Python language in this document. Python reference guides <strong>and</strong><br />
tutorials can be downloaded from www.python.org.
Page 10 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
2.2 Creation of assessment variables<br />
<strong>TPT</strong> assessment uses so called assessment variables in order to specify <strong>and</strong> process data<br />
of interest. These variables differ from the normal Python variable types. This allows<br />
h<strong>and</strong>ling of large amounts of data efficiently by optimising internal data structures <strong>and</strong><br />
makes access <strong>and</strong> interaction with the data efficient <strong>and</strong> readable.<br />
In order to use signals they must be declared as follows.<br />
d = <strong>TPT</strong>.Double(); # data range: floating point double accuracy (64 Bit)<br />
f = <strong>TPT</strong>.Float(); # data range: flaoating point (32 Bit)<br />
i = <strong>TPT</strong>.Int(); # data range: -2^31 .. 2^31-1 (= 32 Bit signed integer)<br />
b = <strong>TPT</strong>.Boolean(); # data range: “true“ <strong>and</strong> “false“<br />
Additionally for integer variables the data type can be selectively controlled. This might be<br />
useful to reduce the large amount of data in larger projects.<br />
i = <strong>TPT</strong>.Int8(); # data range: -128 .. 127<br />
i = <strong>TPT</strong>.Int16(); # Data range: -2^15 .. 2^15-1<br />
i = <strong>TPT</strong>.Int32(); # Data range: -2^31 .. 2^31-1<br />
i = <strong>TPT</strong>.Int64(); # Data range: -2^63 .. 2^63-1<br />
i = <strong>TPT</strong>.UInt8(); # Data range: 0 .. 255<br />
i = <strong>TPT</strong>.UInt16(); # Data range: 0 .. 65535<br />
i = <strong>TPT</strong>.UInt32(); # Data range: 0 .. 2^32-1<br />
If variables should be exported later on, there is a smart abbreviation of declaring a<br />
variable <strong>and</strong> tagging it for export (see <strong>TPT</strong>.export() in section 2.5 for more details) by<br />
adding an ‘X’ to the creation method such as in the following examples:<br />
f = <strong>TPT</strong>.DoubleX(); # create a double variable <strong>and</strong> tag it for export<br />
i = <strong>TPT</strong>.Int16X(); # create an int16 variable <strong>and</strong> tag it for export<br />
b = <strong>TPT</strong>.BooleanX(); # create a boolean variable <strong>and</strong> tag it for export<br />
...<br />
variable <strong>TPT</strong>.Double()<br />
<strong>TPT</strong>.Double() declares a new assessment variable of type double.<br />
dv = <strong>TPT</strong>.Double();<br />
dv := 2.1;<br />
dc = <strong>TPT</strong>.Double();<br />
dc(t) := 2.1 * sin(t);<br />
In the example above a variable dv is declared <strong>and</strong> the value 2.1 is assigned. The variable<br />
dc is declared <strong>and</strong> the sine signal 2.1*sin(t) is assigned. Both dv <strong>and</strong> dc are <strong>TPT</strong><br />
assessment variables.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 11<br />
Please note that the assignment is not been done by using a simple “=” but “:=”. The<br />
reason for using this special operator is that the assessment variable dv <strong>and</strong> dc are<br />
Python objects. Replacing the “:=” by “=”in the second statement has a completely<br />
different meaning: it will assign the value <strong>and</strong> the native Python type: the variable will no<br />
longer be a <strong>TPT</strong> assessment variable. The difference might be clearer in the following<br />
example.<br />
dv = <strong>TPT</strong>.Double();<br />
dv := 2.1;<br />
# correct! 2.1 is assigned to the object “dv“. Now we can operate<br />
# with dv, i.e. assign a comment or read the length of the interval<br />
# where the value has been assigned:<br />
#<br />
dv.setComment(“Assign a comment to explain this value for reporting“);<br />
res = dv.getLength();<br />
…<br />
Fig 1: Correct example for the variable definition<br />
dv = <strong>TPT</strong>.DoubleVariable();<br />
dv = 2.1;<br />
# WRONG !! “dv” becomes a simple integer “object“. The assessment variable<br />
# object is deleted. Using the access methods of the example above would<br />
# cause a runtime error:<br />
dv.setComment(“Assign a comment …“); # abort!!! “dv“ not an assessment var.<br />
res = dv.getLength(); # abort!!! “dv“ not an assessment var.<br />
variable <strong>TPT</strong>.Float()<br />
Fig 2: Wrong usage for the variable definition<br />
<strong>TPT</strong>.Float() declares a new assessment variable of type float.<br />
dv = <strong>TPT</strong>.Float();<br />
dv := 2123.2;<br />
dc = <strong>TPT</strong>.Float();<br />
dc(t) := 223 * t;<br />
Function is analogous to <strong>TPT</strong>.Double().<br />
variable <strong>TPT</strong>.Int()<br />
<strong>TPT</strong>.Int() declares a new assessment variable of type integer.<br />
dv = <strong>TPT</strong>.Int();<br />
dv := 2123;<br />
dc = <strong>TPT</strong>.Int();<br />
dc(t) := int(223 * t);
Page 12 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
Function is analogous to <strong>TPT</strong>.Double().<br />
variable <strong>TPT</strong>.Boolean()<br />
<strong>TPT</strong>.Boolean() declares a new assessment variable of type Boolean.<br />
dv = <strong>TPT</strong>.Boolean();<br />
dv := true;<br />
dc = <strong>TPT</strong>.Boolean();<br />
dc(t) := (t > 1) ? true : false;<br />
Function is analogous to <strong>TPT</strong>.Double().<br />
variable <strong>TPT</strong>.Int8(), .Int16(), .Int32(), .Int64(), .UInt8(), .UInt16(), UInt32()<br />
For the declaration of the specific integer variables the following functions can be used.<br />
<strong>TPT</strong>.Int8(), <strong>TPT</strong>.Int16(), <strong>TPT</strong>.Int32(), <strong>TPT</strong>.Int64(), <strong>TPT</strong>.UInt8(),<br />
<strong>TPT</strong>.UInt16(), <strong>and</strong> <strong>TPT</strong>.UInt32().<br />
dv = <strong>TPT</strong>.Int8();<br />
dv := 12;<br />
dc = <strong>TPT</strong>.Int8();<br />
dc(t) := int(t*256); # not allowed if t >= 1.0s<br />
Function is analogous to <strong>TPT</strong>.Double().<br />
2.3 Operations for assessment variables<br />
Various methods exist to modify or read information of the variables.<br />
string variable.getName()<br />
This method returns the logical name of the variable as it will be used in the test report.<br />
i = <strong>TPT</strong>.Int();<br />
res = i.getName(); # returns “i“<br />
int variable.getSize()<br />
This operator returns the overall number of (time) intervals in which the variable is<br />
defined. Thus, the number returned is independent of the current context interval. It may<br />
even be used without any context interval defined.<br />
i = <strong>TPT</strong>.Int();<br />
res = i.getSize(); # for newly created variables: res == 0
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 13<br />
float variable.getStartTime()<br />
Returns the earliest point in time where the assessment variable is defined relative to the<br />
start time of the current context interval. The definition of a variable is independent of a<br />
context interval but variable.getStartTime() returns the earliest “local” time where<br />
the variable is defined <strong>and</strong> is independent of whether or not this point in time is<br />
contained in the current context interval. This time might be outside the context interval<br />
within which variable.getStartTime() is evaluated. If, for example, the variable is<br />
defined before the context interval a negative time value is returned.<br />
Example: variable ‘i’ is defined in intervals [3,15] <strong>and</strong> [21,30], the current context is<br />
[2,4]. i.getStartTime(); is 3-2=1. If the context interval is [20,400],<br />
i.getStartTime(); is 3-20=-17.<br />
Special case: For a new (<strong>and</strong> still empty) assessment variable (created with <strong>TPT</strong>.Int(),<br />
for example), the global start point is 0.0 by definition. If the context interval is<br />
[20,400], this method returns -20.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i.getStartTime();<br />
float variable.getEndTime()<br />
Returns the time where the variable is no longer defined relative to the start of the<br />
context interval.<br />
The result is returned in local time. It does not matter if the variable occurs outwith the<br />
current context interval or not.<br />
Example: The variable is defined in intervals [3,15] <strong>and</strong> [21,30], whereas the current<br />
context is [2,4]. The resulting time value is 30-2=28. If the context interval is<br />
[20,400], the resulting time value is 30-20=10.<br />
Special case: For a new (<strong>and</strong> still empty) assessment variable (e.g. created with <strong>TPT</strong>.Int),<br />
the global end point is 0.0 by definition. If the context interval is [20,400], this<br />
method returns -20.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i.getEndTime();<br />
float variable.getLength()<br />
Returns the difference between the start of the first instance of the variable <strong>and</strong> the end<br />
of its last instance:<br />
getLength() = getEndTime() – getStartTime().<br />
Info: This is not the same as the sum of all periods of definition. Periods of no definition<br />
are not included in this calculation.
Page 14 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i.getLength();<br />
boolean variable.isDefined(float time)<br />
Checks whether or not values of a signal can be accessed at the given local time time.<br />
This means that c.isDefined(2.0) returns true if the value of c at local time 2.0<br />
(which is 2 seconds after the start time of the current context interval) exists.<br />
interval variable[int index]-Operator<br />
As mentioned in section 1.2 assessment variables may consist of multiple definition<br />
intervals. The different intervals are indexed using variable[ n-1] where n is the nth<br />
definition interval. Hence the first interval can be accessed with index 0, the last one with<br />
index getSize()-1. Using indices outside this range will raise a runtime error.<br />
(“Variable xyz has no definition interval with index …“). Accessing the<br />
definition intervals using the []-operator is independent from the current context interval.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
iv = i[0];<br />
# iv is the globally first interval of the assessment variable<br />
number variable(float time)-Operator: Accessing values at a particular time<br />
Snapshot values of a signal can be accessed using the ()-operator. Accessing single<br />
values always uses local time. This means that c(0.0) returns the value of c at local time<br />
0.0 (which is the start time of the current context interval <strong>and</strong> not the global time 0.0.<br />
The assessment variable must exist at local time t , otherwise a runtime error will be<br />
raised.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = 2 * i(12.0); # reads the value of i at t = 12.0 (local time)<br />
number variable: Autocast for accessing values of a variable<br />
If an assessment variable is part of a numerical calculation without any special operators,<br />
the “current value” of the variable will be used.<br />
If the variable is accessed in context of a time dependent expression (i.e. an expression<br />
where t is bound to the current point in time) the value of the assessment variable at t<br />
will be read. In other words, instead of var(t) one can simply write var with the same<br />
meaning.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 15<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = <strong>TPT</strong>.always(i > 2); # both lines are identical<br />
res = <strong>TPT</strong>.always(i(t) > 2); # in semantics.<br />
If the variable is accessed outwith a time dependent expression (i.e. t is not allowed in<br />
this expression), the value of the variable within the current context interval will be<br />
returned if it is unique, otherwise a runtime error will be raised.<br />
The unique value will be determined as follows: From all definition intervals of the<br />
assessment variable only those intervals are considered that intersect the current context<br />
interval. If the variable has the same (constant) value within all remaining intervals then<br />
this is the resulting unique value. A runtime error will be raised under one of the following<br />
conditions:<br />
• If there is no definition interval of the assessment variable intersecting the current<br />
context interval (Error: “Variable xyz is undefined in context<br />
interval …”)<br />
• If there is at least one definition interval of the assessment variable intersecting<br />
the context interval that is not constant (Error: “Variable xyz is not a<br />
constant in definition interval …”)<br />
• If there are at least two different definition intervals intersecting the current<br />
context interval with constant, but different values (Error: “Variable xyz is<br />
defined in multiple definition intervals with different<br />
constants A <strong>and</strong> B. Context interval is …”)<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = 2 * i; # reads the constant value of i from current context interval<br />
If it is not possible to use the auto-cast convention above in some expression context, the<br />
same semantics can be expressed using syntax var() instead of var.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i; # “res“ refers to the same object such as “i“ (no Autocast)<br />
res = i(); # the constant value of i in current context interv. will be read<br />
number variable.getLeftValue()<br />
This function returns the first value of a variable in the current context interval. The<br />
function may be applied only if there is at least one definition interval of the assessment<br />
variable in the current context interval, otherwise a runtime error will be raised<br />
(“Variable xyz is undefined in context interval …”).<br />
Example: The variable is defined in intervals [3,15] <strong>and</strong> [21,30], whereas the context is<br />
[5,25]. The result is the value of the assessment variable at global time 5.
Page 16 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i.getLeftValue();<br />
number variable.getRightValue()<br />
This function returns the last value of a variable in the current context interval. The<br />
function may be applied only if there is at least one definition interval of the assessment<br />
variable in the context interval, otherwise a runtime error will be raised (“Variable xyz<br />
is undefined in context interval …”).<br />
Example: The variable is defined in intervals [3,15] <strong>and</strong> [21,23], whereas the context is<br />
[5,25]. The result is the value of the assessment variable at global time 23.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i.getRightValue();<br />
variable.setVerdict(int result)<br />
With this function every definition interval of an assessment variable can be tagged with a<br />
verdict using one of the following constants:<br />
• variable.setVerdict(<strong>TPT</strong>.SUCCESS): The signal indicates that the system<br />
behaviour was as expected .<br />
• variable.setVerdict(<strong>TPT</strong>.FAILED): The signal indicates that the system<br />
behaviour shows an error .<br />
• variable.setVerdict(<strong>TPT</strong>.DONT_KNOW): The signal indicates that it cannot<br />
be decided automatically whether or not the system behaviour was as expected.<br />
If setVerdict() has not been called for a variable, the default verdict is<br />
<strong>TPT</strong>.DONT_KNOW. However, <strong>TPT</strong>.Boolean() variables are an exception to this rule. If<br />
these variables are constant within a definition interval, the verdict is automatically set to<br />
<strong>TPT</strong>.SUCCESS if the constant value is TRUE, similarly the verdict is <strong>TPT</strong>.FAILED if the<br />
variable is constantly FALSE. In either case the default verdict can be overwritten by the<br />
user using the setVerdict() function.<br />
A runtime error will be raised by this function under one of the following conditions:<br />
• If there is no definition interval of the assessment variable intersecting the current<br />
context interval (Error: “Variable xyz is undefined in context<br />
interval …”)<br />
• If there is more than one definition interval intersecting the context interval (Error:<br />
“Variable xyz is defined in more than one interval<br />
intersecting context interval …”)
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 17<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
i(t) := int (2 * t);<br />
i.setResult(<strong>TPT</strong>.SUCCESS); # i shows a correct system behaviour -> SUCCESS<br />
variable.setComment(string comment)<br />
A comment can be added to every definition interval of an assessment variable using the<br />
function setComment(). Before calling this function, be sure that there is exactly one<br />
definition interval of the assessment variable in the current context interval. The comment<br />
will be assigned to the definition interval <strong>and</strong> added to the test .<br />
A runtime error will be raised by this function under one of the following conditions:<br />
• If there is no definition interval of the assessment variable intersecting the current<br />
context interval (Error: “Variable xyz is undefined in context<br />
interval …”)<br />
• If there is more than one definition interval intersecting the context interval (Error:<br />
“Variable xyz is defined in more than one interval<br />
intersecting context interval …”)<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
if cond:<br />
i(t) := sin(t);<br />
i.setComment(“i is a sine “);<br />
else:<br />
i(t) := cos(t);<br />
i.setComment(“i is a cosine “);<br />
variable.setInterpolation(int mode)<br />
The assessment engine supports two different interpolation modes for every assessment<br />
variable var: <strong>TPT</strong>.LASTVALUE means that between two subsequent samples the signal<br />
is constant at the left sample value (excluding the right sample point). It constitutes a step<br />
function. On the other h<strong>and</strong>, <strong>TPT</strong>.LINEAR interpolates the signal between two<br />
subsequent samples.<br />
Note that, linear interpolation is allowed even for integer variables. However, the<br />
interpolated values are subject to quantization error using the integer resolution.<br />
Changing the interpolation mode for Boolean signals is allowed but has no effect.
Page 18 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
x = <strong>TPT</strong>.Double();<br />
…<br />
x(t) := sin(t);<br />
…<br />
# the interpolation mode can be changed before or even after signal definition<br />
x.setInterpolation(<strong>TPT</strong>.LINEAR);<br />
variable := number (definition of a constant)<br />
A value can be assigned to an assessment variable in a context interval using the syntax<br />
var := expr. The variable will then be constant in this context interval. However, if the<br />
variable was already defined in one or more definition interval(s) intersecting, but not<br />
identical to the current context interval, a runtime exception will be raised (“Variable<br />
xyz cannot be defined with overlapping definition intervals…“). In<br />
other words: A runtime error will occur if defining the variable would change existing<br />
definition intervals <strong>and</strong> not just their values.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
i := 1234; # assigns a constant value to “i” in current context interval<br />
variable(t) := timed-number (definition of a signal)<br />
Using the notation var(t) := timed-number a continuous signal can be assigned to<br />
an assessment variable in the current context interval. The variable will have an individual<br />
value at every sample point in the context interval. For that purpose the reserved variable<br />
t can be used within the expression timed-number on the right-h<strong>and</strong>-side to represent<br />
the “current time”. The time variable t represents the local time, i.e. it starts at t=0.0 <strong>and</strong><br />
ends at t=this.getLength()-<strong>TPT</strong>.getStepSize(). If the variable was previously<br />
defined in the context interval the old value will be overwritten. However, if the variable<br />
was previously defined in one or more definition interval(s) intersecting, but not identical<br />
to the current context interval, a runtime exception will be raised (“Variable xyz<br />
cannot be defined with overlapping definition intervals…“). In other<br />
words: A runtime error will occur if defining the variable would change existing definition<br />
intervals <strong>and</strong> not just their values.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
i(t) := int(12 * t);<br />
variable.isConstant()<br />
This operator returns true if the signal is constant during the current context interval..
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 19<br />
…<br />
i(t) := 2;<br />
j(t) := t;<br />
k := 2;<br />
i.isConstant(); # true<br />
j.isConstant(); # false<br />
k.isConstant(); # true<br />
sum = i + k; # accessing constant values allowed here<br />
j1 = j(0.0s); # since j is not a constant we must access ...<br />
j2 = j(0.1s); # ... values at individual points in time ...<br />
max = <strong>TPT</strong>.average(j(t)); # ... only<br />
2.4 Operations for time intervals<br />
There are operations to read or modify characteristics of time intervals.<br />
float interval.getStartTime()<br />
Returns the first point in time where the interval is defined. The time value is returned in<br />
local time <strong>and</strong> is independent of whether or not this point in time is contained in the<br />
current context interval.<br />
Example: The interval is [3,15] <strong>and</strong> the current context is [2,4]. The resulting time<br />
value is 3-2=1. If the context interval is [20,400], the resulting time value is 3-20=-17.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i[1].getStartTime(); # start time of the 2nd interval of “i”<br />
float interval.getEndTime()<br />
Returns the point in time where the interval is no longer defined.<br />
The result is in local time <strong>and</strong> is independent of whether or not this point in time t is<br />
contained in the current context interval.<br />
Example: The interval is defined in interval [21,30] <strong>and</strong> the current context is [2,4].<br />
The resulting time value is 30-2=28. If the context interval is [20,400], the resulting<br />
time value is 30-20=10.
Page 20 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i[1].getEndTime(); # end time of the 2nd interval of “i”<br />
float interval.getRightLimit()<br />
This method returns the greatest sample point belonging to the interval. (Note, that<br />
intervals in <strong>TPT</strong> are always right-open intervals with a fixed sample rate. Therefore<br />
getRightLimit() is the same as getEndTime()-<strong>TPT</strong>.getStepSize()).<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i[0].getRightLimit(); # right limit of the 1st interval of “i”<br />
float interval.getLength()<br />
This method returns the overall length of the interval. This is exactly the difference<br />
between start <strong>and</strong> end time: getLength() = getEndTime() – getStartTime().<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
res = i[1].getLength();<br />
boolean interval.isDefined(float time)<br />
Checks whether or not the interval contains the given local time time. This means that<br />
j.isDefined(2.0) returns true if the value of j at local time 2.0 (which is 2 seconds<br />
after the start time of the current context interval) exists.<br />
number interval(float time)-Operator: Accessing values at a particular time<br />
Single values of an interval can be accessed using the ()-operator. Accessing single<br />
values always uses local time. This means that j(0.0) returns the value of j at local time<br />
0.0 (which is the start time of the current context interval <strong>and</strong> not the global time 0.0.<br />
t must be a value between j.getStartTime() <strong>and</strong> j.getEndTime(), otherwise a<br />
runtime error will be raised.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
j = i[someindex];<br />
res = 2 * j(12.0); # j must be defined at t=12.0<br />
number interval: Autocast for accessing values of an interval<br />
If an interval is part of a numerical calculation without any special operators, the “current<br />
value” of the interval will be used.<br />
If the interval is accessed in context of a time dependent expression (i.e. an expression<br />
where t is bound to the current point in time) the value of the interval at t will be read. In
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 21<br />
other words, instead of j(t) one can simply write j with the same meaning for any<br />
interval j.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
j = i[someindex];<br />
res = <strong>TPT</strong>.always(j > 2); # both lines are identical<br />
res = <strong>TPT</strong>.always(j(t) > 2); # in semantics.<br />
If the interval is accessed outside of a time dependent expression (i.e. t is not allowed in<br />
this expression), the value of the interval within the current context interval will be<br />
returned if it is constant, otherwise a runtime error will be raised.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
j = i[someindex];<br />
res = 2 * j; # reads the value of j (must be a constant)<br />
If it is not possible to use the auto-cast convention above, it may be expressed using<br />
syntax j() instead of j.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
j = i[someindex];<br />
res = j; # “res“ refers to the same object as “j“ (no Auto-cast)<br />
res = j(); # the constant value of j will be read<br />
int interval.getSamplePointSize()<br />
This method returns the total number of sample points stored to represent the signal of<br />
this interval. For a constant this method returns always “1”. For continuous signals the<br />
returned value is the same as interval.getLength()/<strong>TPT</strong>.getStepSize().<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
n = i[0].getSamplePointSize(); # no. of samples in first interval of i<br />
interval.setComment(string comment)<br />
A comment can be added to an interval using the function setComment().The comment<br />
will be assigned to the interval <strong>and</strong> added to the test report (if exported) .
Page 22 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
i = <strong>TPT</strong>.Int();<br />
…<br />
# add a comment to the 2nd definition interval of “i”<br />
i[1].setComment(“i is a sine “);<br />
interval.isConstant()<br />
This operator returns true if the signal is constant over time during this interval.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
myIV = i[1];<br />
if myIV.isConstant():<br />
# we can access the constant value directly in this case:<br />
print myIV+1;<br />
else:<br />
# we can access the continous course only at individual times:<br />
print myIV(0.0s);<br />
print myIV(1.0s);<br />
print myIV(2.0s);<br />
bool interval.intersects(interval other)<br />
This function checks whether two intervals overlap each other.<br />
i1 = <strong>TPT</strong>.Int();<br />
i2 = <strong>TPT</strong>.Int();<br />
…<br />
if i1[0].intersect(i2[3]):<br />
# 1st interval of i1 intersects 4th interval of i2 !<br />
…<br />
interval <strong>TPT</strong>.Interval(float start, float end)<br />
This method creates a new interval that ranges from time start (inclusive) to end<br />
(exclusive). Both parameters must be specified in local time. Such intervals are commonly<br />
used in combination with the during-operator.<br />
i = <strong>TPT</strong>.Interval(2,5.7); # creates a new interval btw. 2.0s <strong>and</strong> 5.7s<br />
2.5 Operations for records (file I/O operators)<br />
For the <strong>TPT</strong> assessment it is necessary to access intermediate <strong>and</strong> results files.<br />
string <strong>TPT</strong>.workingDirectory()<br />
This function returns the “working directory” of the assessment script. If you are running<br />
the assessment script from <strong>TPT</strong> for a particular test case the working directory is always
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 23<br />
the directory where the data log files are located (assembled during the test execution). If<br />
the assessment engine has been started as a st<strong>and</strong>alone process the current working<br />
directory is the directory where the engine has been started.<br />
workingdir = <strong>TPT</strong>.workingDirector();<br />
# now we can locate a file within the workingDirectory as follows:<br />
datafilename = <strong>TPT</strong>.workingDirectory() + “/myfile.dat”;<br />
…<br />
2.5.1 Reading records from file system<br />
record <strong>TPT</strong>.readRecord(string filename, double jittertolerance)<br />
This function opens a file with the given filename for reading <strong>and</strong> reads all relevant signal<br />
information into the assessment engine. The individual signals can be accessed using the<br />
Record object returned by this function (see the access functions described below).<br />
<strong>TPT</strong> supports the following signal file formats:<br />
• <strong>TPT</strong>BIN, which is a specialized proprietary file format of <strong>TPT</strong> to store signals in a<br />
compact format <strong>and</strong> that supports all information necessary during test<br />
execution, test assessment <strong>and</strong> report generation.<br />
• MAT, which is the Matlab binary file format for storing signal data<br />
• CSV (comma-separated values), which is a simple ASCII table-like file format<br />
myrecord = <strong>TPT</strong>.readRecord(“myfile.tptbin”);<br />
a = myrecord.getVariable(“a”); # obtain var “a” from file content<br />
…<br />
len = a.getLength(); # use the variable as descibed in section 2.3<br />
You can use absolute or relative pathnames. If the filename is relative <strong>and</strong> if you are<br />
running the script form <strong>TPT</strong> for a particular test case the working directory is<br />
automatically added.<br />
The optional parameter jittertolerance indicates the maximum tolerance the time<br />
jittering of a signal may have in order to be interpreted as sampled with constant<br />
sampling time. For example a given signal has a sampling time that is not really constant.<br />
The sampling time varies between 0.9 <strong>and</strong> 1.1 seconds but it is known that the sampling<br />
time is constant 1s. The reason for this phenomenon is may be an asynchronous data<br />
transfer. Setting the jitter-tolerance to 0.1 would cause the signal being interpreted with a<br />
constant sampling time of 1s.<br />
variable record.getVariable(string variablename)<br />
An assessment variable can be retrieved from a record by its name using the<br />
getVariable() method.
Page 24 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
myrecord = <strong>TPT</strong>.readRecord(“myfile.tptbin”);<br />
a = myrecord.getVariable(“a”); # obtain var “a” from file content<br />
b = myrecord.getVariable(“b”); # obtain var “b” from file content<br />
…<br />
It is not necessary to declare variables a <strong>and</strong> b using <strong>TPT</strong>.Double(), <strong>TPT</strong>.Int() etc.<br />
The declaration is done implicitly when importing the variable.<br />
interval record.getCompleteInterval()<br />
This method returns the complete interval for a given record, which is the smallest interval<br />
that spans all definition intervals of all variables within this record. If the record is empty<br />
(no variables contained) or if all variables of this record are empty (newly created without<br />
a definition) the default interval returned by this method is [0,<strong>TPT</strong>.getStepSize()].<br />
myrecord = <strong>TPT</strong>.readRecord(“myfile.tptbin”);<br />
a = myrecord.getCompleteInterval();<br />
…<br />
float record.getStepSize()<br />
This method returns the greatest common divisor (GCD) of all the step sizes (sampling<br />
rates) of all variables within this record. If there is no variable in the record at all, the step<br />
size returned by this method is 1.0, by definition.<br />
myrecord = <strong>TPT</strong>.readRecord(“myfile.tptbin”);<br />
samplingRate = myrecord.getStepSize();<br />
…<br />
2.5.2 Writing records to the file system<br />
record <strong>TPT</strong>. Record()<br />
This method generates a new empty test record into which variables can be exported.<br />
foo = <strong>TPT</strong>.Int();<br />
bar = <strong>TPT</strong>.Float();<br />
…<br />
rec = <strong>TPT</strong>.Record();<br />
rec.add(foo); # export variable with name “foo“<br />
record.add(variable var)<br />
Adds an assessment variable to a record. If the record is written to the file system later on,<br />
this variable will be stored in the exported file together with all other exported variables.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 25<br />
foo = <strong>TPT</strong>.Int();<br />
bar = <strong>TPT</strong>.Float();<br />
…<br />
rec = <strong>TPT</strong>.Record();<br />
rec.add(foo); # export variable with name “foo“<br />
record.add(variable var, string variablename)<br />
In some cases it might be necessary to change the name of a signal before exporting it to<br />
a file. This is done by appending the variable’s new name. However, be careful using this<br />
function because it renames the variable permanently.<br />
foo = <strong>TPT</strong>.Int();<br />
bar = <strong>TPT</strong>.Float();<br />
…<br />
rec = <strong>TPT</strong>.Record();<br />
rec.add(foo); # export variable with name “foo“<br />
rec.add(bar,”mybar”); # export “bar” with name “mybar”.<br />
name = bar.getName(); # read variable’s name<br />
# name == “mybar” !!<br />
record.writeRecord(string filename)<br />
This method exports a record to the file system.<br />
foo = <strong>TPT</strong>.Int();<br />
bar = <strong>TPT</strong>.Float();<br />
…<br />
rec = <strong>TPT</strong>.Record();<br />
rec.add(foo);<br />
rec.add(bar);<br />
rec.writeRecord(“foobar.tptbin“); # writes the signasl into a data file<br />
You can use absolute or relative pathnames. If the filename is relative <strong>and</strong> if you are<br />
running the script form <strong>TPT</strong> for a particular test case the working directory is<br />
automatically added.<br />
2.5.3 Writing the default output record to the file system<br />
Signals that are to appear in the reports must be exported while running the assessment.<br />
Normally the <strong>TPT</strong> assessment uses a central export file for all of the export signals. This<br />
record has some special access methods that are just shortcuts for the methods described<br />
above.<br />
record <strong>TPT</strong>.getExportRecord()<br />
This method returns the central export record. In general, it is not necessary to retrieve<br />
this record explicitly but to use the shorth<strong>and</strong> methods below.
Page 26 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
<strong>TPT</strong>.export(variable var)<br />
Using <strong>TPT</strong>.export(var) marks the variable var for export into the default data file<br />
(usually testcase.tresult.tptbin).<br />
<strong>TPT</strong>.export(var) is shorth<strong>and</strong> for <strong>TPT</strong>.writeExportRecord().add(var).<br />
foo = <strong>TPT</strong>.Int();<br />
…<br />
<strong>TPT</strong>.export(foo); # same as <strong>TPT</strong>.getExportRecord().add(foo)<br />
<strong>TPT</strong>.export(variable var, string varname)<br />
Using <strong>TPT</strong>.export(var,name) marks the variable var for export into the default data<br />
file (usually testcase.tresult.tptbin). In this case one can use this function to<br />
rename the assessment variable before exporting it. However, be careful using this<br />
function because it renames the variable permanently.<br />
<strong>TPT</strong>.export(var, name) is shorth<strong>and</strong> for <strong>TPT</strong>.writeExportRecord().add(var,<br />
name).<br />
foo = <strong>TPT</strong>.Int();<br />
bar = <strong>TPT</strong>.Float();<br />
…<br />
<strong>TPT</strong>.export(foo); # same as <strong>TPT</strong>.getExportRecord().add(foo)<br />
<strong>TPT</strong>.export(bar, “mybar“);# same as <strong>TPT</strong>.getExportRecord().add(foo,”mybar“)<br />
<strong>TPT</strong>.writeExportRecord(string filename)<br />
This method exports all variables added to the central record to the file system (usually to<br />
the file named testcase.tresult.tptbin).<br />
Using <strong>TPT</strong>.writeExportRecord(filename) is shorth<strong>and</strong> for calling<br />
<strong>TPT</strong>.getExportRecord().writeRecord(filename).<br />
foo = <strong>TPT</strong>.Int();<br />
bar = <strong>TPT</strong>.Float();<br />
…<br />
<strong>TPT</strong>.export(foo); # same as <strong>TPT</strong>.getExportRecord().add(foo)<br />
<strong>TPT</strong>.export(bar, “mybar“);# same as <strong>TPT</strong>.getExportRecord().add(foo,”mybar“)<br />
…<br />
<strong>TPT</strong>.writeExportRecord(“testcase.tresult.tptbin”); # write now<br />
# same effect:<br />
<strong>TPT</strong>.getExportRecord().writeRecord(“testcase.tresult.tptbin”);<br />
If the assessment script has been generated by <strong>TPT</strong> this comm<strong>and</strong> will be inserted<br />
automatically into the script.<br />
2.5.4 Accessing reference data in assessment scripts<br />
If a reference base directory has been specified in the execution configuration of <strong>TPT</strong> the<br />
reference signals are accessible using the operations described in the section below.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 27<br />
record <strong>TPT</strong>.get<strong>Reference</strong>Data()<br />
This method returns a record that contains all the signals from reference data. You can<br />
use this to read reference signals in the same way as reading measured signals:<br />
…<br />
ref = <strong>TPT</strong>.get<strong>Reference</strong>Data();<br />
a_ref = ref.getVariable(“a”); # obtain var “a” from reference file content<br />
b_ref = ref.getVariable(“b”); # obtain var “b” from reference file content<br />
…<br />
string <strong>TPT</strong>.get<strong>Reference</strong>DataFile()<br />
This method delivers the name of the file that contains the reference data for this test<br />
case. If no reference base directory has been specified in the execution configuration this<br />
method returns an empty string.<br />
2.6 Global operations<br />
<strong>TPT</strong>.setStepSize(float sampleSize)<br />
This function sets the global step size (sampling rate) used in all computations of the <strong>TPT</strong><br />
assessment engine. The default step size is 1.0s. As a rule, the step size should be set only<br />
once at the beginning of the assessment computation. Even if updating the step size<br />
between some calculations is possible, the semantics are quite complicated <strong>and</strong> may<br />
cause a behaviour which is difficult to predict.<br />
<strong>TPT</strong>.getStepSize()<br />
This function returns the global step size (sample rate) used in all computations of the<br />
<strong>TPT</strong> assessment engine. This has the same meaning as the ‘@‘-operator (see below).<br />
@-Operator<br />
This operator returns the global step size (sample rate) used in all computations of the<br />
<strong>TPT</strong> assessment engine. This has the same meaning as the <strong>TPT</strong>.getStepSize()operation<br />
(see above).<br />
float <strong>TPT</strong>.toGlobal(float time)<br />
This operator returns the global time that belongs to the given local time ‘time’.<br />
during <strong>TPT</strong>.Interval(2,4):<br />
<strong>TPT</strong>.toGlobal(0s); # delivers 2s<br />
void <strong>TPT</strong>.setTestResult(int result)<br />
This function sets the global test result for the test case to <strong>TPT</strong>.FAILED, <strong>TPT</strong>.SUCCESS<br />
or <strong>TPT</strong>.DONT_KNOW (<strong>TPT</strong>.setTestResult(<strong>TPT</strong>.FAILED)), (<strong>TPT</strong>.setTestResult<br />
(<strong>TPT</strong>.SUCCESS) or (<strong>TPT</strong>.setTestResult(<strong>TPT</strong>.DONT_KNOW))). This will be exported
Page 28 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
as an Integer variable “<strong>TPT</strong>_TestResult“. When <strong>TPT</strong>.setTestResult() is not used<br />
in a test case it won’t be exported.<br />
# Test was successful<br />
<strong>TPT</strong>.setTestResult(<strong>TPT</strong>.SUCCESS);<br />
void <strong>TPT</strong>.setTestComment(string comment)<br />
This function sets the global comment that will be assigned to the test case (more<br />
precisely: to the implicitly defined variable <strong>TPT</strong>_TestResult that will be exported). This<br />
comment will be shown in the overview report generated as a summary over all test cases<br />
as well as in the details reports for individual test cases.<br />
# Test had a particual shift time problem<br />
<strong>TPT</strong>.setTestResult(<strong>TPT</strong>.FAILED);<br />
<strong>TPT</strong>.setTestComment(”shift time too long”);<br />
Lazy conditional expression: cond ? thenExpr : elseExpr<br />
To use conditional expressions there is a “cond ? thenExpr : elseExpr“-operator<br />
as known from languages such as C, C++ or Java.<br />
# compare signals a <strong>and</strong> b, but shift b 2s to the right. Since this comparision<br />
# is not allowed if t < 2 we define the expression to be true (1) if t < 2<br />
<strong>TPT</strong>.always(t < 2 ? 1: a(t) == b(t-2));<br />
2.7 Signal processing functions: value computations<br />
boolean <strong>TPT</strong>.always(timed-boolean expr)<br />
This operation checks if the expression expr of type boolean is true for all points in<br />
time of the current context interval. If the expression is false during at least one sample<br />
period the result is false.<br />
res = <strong>TPT</strong>.always(sin(t) < 2);<br />
# res == 1<br />
double <strong>TPT</strong>.average(timed-float expr)<br />
This method returns the mean average value of the numeric expression over all time steps<br />
within the current context interval.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 29<br />
res = <strong>TPT</strong>.average(2 * t);<br />
# res == this.getLength()<br />
boolean <strong>TPT</strong>.check( boolean cond1, float val1, string text1,<br />
boolean cond2, float val2, string text2,<br />
...,<br />
float valOtherwise, string textOtherwise)<br />
This operation checks if the expression cond1 of type boolean is true <strong>and</strong> delivers the<br />
value val1 associated with the comment text1 in this case. Otherwise the expression<br />
cond2 will be checked. If true the value val2 associated with the comment text2 will be<br />
returned, <strong>and</strong> so on. If none of the conditions cond1 to condN are fulfilled the function<br />
returns valOtherwise associated with comment textOtherwise.<br />
a = <strong>TPT</strong>.Double();<br />
a := t < 3 ? t : (t-3);<br />
res = <strong>TPT</strong>.Int8();<br />
res := <strong>TPT</strong>.check(<br />
a.getLeftValue() == A_CONST_X, 1, “a is initially X”,<br />
a.getLeftValue() == A_CONST_Y, 2, “a is initially Y”,<br />
-1, “neither X nor Y”);<br />
boolean <strong>TPT</strong>.checkAlways(timed-boolean expr, string successText, string<br />
errorText)<br />
This operation checks if the time dependent expression expr of type boolean is true<br />
for all points in time of the current context interval. If the expression is always true the<br />
result is true in the current context interval <strong>and</strong> the given successText is automatically<br />
used as the comment. Otherwise (if the expression is false at least for one sample) the<br />
result is false in all sub-intervals of the current context interval where the expr failed.<br />
a = <strong>TPT</strong>.Double();<br />
a(t) := t < 3 ? t : (t-3);<br />
res = <strong>TPT</strong>.Boolean();<br />
res := <strong>TPT</strong>.checkAlways(a(t) >= 2, “a is in range” ,”a exceeds limit”);<br />
# res is true in ranges [2..3] <strong>and</strong> [5..end]<br />
boolean <strong>TPT</strong>.exists(timed-boolean expr)<br />
This operation checks if the time dependent expression expr of type boolean is true<br />
during at least one sample period of the current context interval. If the expression is<br />
false for there is no time t with expr(t)==true.
Page 30 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
res = <strong>TPT</strong>.exists(t > 2);<br />
# res == 1 if the context interval is longer than 2s<br />
float <strong>TPT</strong>.max(timed-float expr)<br />
This method returns the maximum of all values expr(t) within the current context<br />
interval.<br />
res = <strong>TPT</strong>.max(sin(t));<br />
# res == 1 if context interval is longer than PI/2<br />
float <strong>TPT</strong>.min(timed-float expr)<br />
This method returns the minimum of all values expr(t) within the current context<br />
interval.<br />
res = <strong>TPT</strong>.min(sin(t));<br />
# res == -1 if context interval is longer than PI*3/2<br />
boolean <strong>TPT</strong>.never(timed-boolean expr)<br />
This operation checks if the expression expr of type boolean is false during all of the<br />
current context interval. If the expression is true during at least one sample period the<br />
result is false.<br />
res = <strong>TPT</strong>.never(sin(t) < 2);<br />
# res == 0<br />
2.8 Signal processing functions: signal computations<br />
timed-float <strong>TPT</strong>.boundControl(timed-float expr, float min, float max)<br />
The operation checks whether or not the course of expr is out of the limits [min, max]<br />
within the current context interval. The result is for a given time t is defined as follows:<br />
• the negative value expr(t)-min if expr(t) is below bounds (expr(t) max),<br />
<strong>and</strong><br />
• the value 0.0, if min ≤ expr(t) ≤ max<br />
Note that boundControl() can be considered as a special form of the hose()<br />
function. The expression boundControl(expr, min, max) has the same meaning as<br />
the equivalent term hose(expr, (max+min)/2, 0, (max-min)/2). However, the<br />
implementation is more efficient.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 31<br />
res = <strong>TPT</strong>.Double();<br />
# defines res in a way to check for being off the limits of 0.5 or -0.5<br />
res(t) := <strong>TPT</strong>.boundControl(sin(t), -0.5, 0.5);<br />
timed-float <strong>TPT</strong>.deviation(timed-float expr1, timed-float expr2, float x)<br />
This operator calculates the deviation of expr1 <strong>and</strong> expr2 <strong>and</strong> returns the difference as<br />
a signal. The parameter ± x specifies the time tolerance, i.e. for a given time t the value<br />
expr1(t) is compared with all values expr2(t ± x). The smallest absolute difference<br />
will be returned as the deviation at t.<br />
Note that deviation() can be considered as a special case of hose(). The expression<br />
deviation(expr1, expr2, x) is equivalent to |hose(expr1, expr2, x, 0)|.<br />
However, the implementation is more efficient.<br />
foo = <strong>TPT</strong>.Double();<br />
bar = <strong>TPT</strong>.Double();<br />
res = <strong>TPT</strong>.Double();<br />
foo(t) := …<br />
bar(t) := …<br />
# tolerate +/-1 seconds when comparing foo <strong>and</strong> 2*bar(t/2)<br />
res(t) := <strong>TPT</strong>.deviation(foo(t), 2*bar(t/2), 1.0s);<br />
timed-float <strong>TPT</strong>.dt(timed-float expr)<br />
This operator calculates the first derivative or more precisely, the difference quotient over<br />
time.<br />
foo = <strong>TPT</strong>.Double();<br />
res = <strong>TPT</strong>.Double();<br />
foo(t) := sin(t);<br />
res(t) := <strong>TPT</strong>.dt(2* foo(t/2)); # first derivative 2*foo(t/2)<br />
timed-float <strong>TPT</strong>.dt2(timed-float expr)<br />
Analogous to <strong>TPT</strong>.dt() this function returns the second derivative (difference quotient)<br />
over time.<br />
res = <strong>TPT</strong>.Double();<br />
res(t) := <strong>TPT</strong>.dt2(2*t*t); # 2nd derivative is constant 4<br />
timed-float <strong>TPT</strong>.hose(timed-float expr, timed-float ref, float xtol, float ytol)<br />
This method generates bounds around the signal ref(t) <strong>and</strong> checks if the signal expr<br />
is encapsulated within these bounds. The hose consists of all the rectanles with the size<br />
xtol <strong>and</strong> ytol around every sample point of the reference signal ref. The result for a<br />
time t is the smallest delta between the signal expr(t) <strong>and</strong> the hose around ref. When<br />
the signal expr(t) is covered by the hose, the result is 0.0, otherwise the smallest<br />
(signed) delta between expr(t) <strong>and</strong> the reference hose ref will be returned.
Page 32 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
Figure 3 shows an example of the hose function. The red signal is expr(t) <strong>and</strong> the blue<br />
signal with dots is the reference signal ref(t). The hose function is build from<br />
rectangles depicted in grey. The hose function returns 0.0 when the original signal<br />
expr(t) is inside the grey boxes <strong>and</strong> is the difference between the border of the boxes<br />
<strong>and</strong> the original signal when the signal is outside of the grey boxes (cf. red dotted line<br />
unequal zero for t > te).<br />
For sampled systems xtol must be at least the step size to be relevant.<br />
y<br />
ytol xtol original signal<br />
reference signal<br />
hose<br />
return valuesof the hose function<br />
t e<br />
Figure 3: Hose function<br />
# hose function example<br />
foo = <strong>TPT</strong>.Double();# reference signal<br />
bar = <strong>TPT</strong>.Double();# original signal<br />
res = <strong>TPT</strong>.Double();<br />
foo(t) := …<br />
bar(t) := …<br />
# x-tol: 0.01<br />
# y-tol: 5.0<br />
res(t) := <strong>TPT</strong>.hose(bar(t), foo(t), 0.01, 5.0);<br />
timed-float <strong>TPT</strong>.integrate(timedFloat expr, int type)<br />
This method integrates the signal expr over time in the current context interval. As<br />
numeric integration type the following options are available:<br />
• <strong>TPT</strong>.EULER_FORWARD (default, if type is omitted)<br />
• <strong>TPT</strong>.EULER_BACKWARD<br />
• <strong>TPT</strong>.TUSTIN (bilinear)<br />
t
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 33<br />
timed-boolean <strong>TPT</strong>.monotony(timed-float expr, int type)<br />
Analyses the monotony of a signal in a time interval <strong>and</strong> returns true for every time t<br />
where expr has the desired monotonic behaviour. The type parameter controls which<br />
monotonic characteristics are to be observed:<br />
• <strong>TPT</strong>.INCREASING<br />
• <strong>TPT</strong>.DECREASING<br />
• <strong>TPT</strong>.STRICTLY_INCREASING<br />
• <strong>TPT</strong>.STRICTLY_DECREASING<br />
res = <strong>TPT</strong>.Boolean();<br />
2.8.1 Filter operations<br />
res(t) := <strong>TPT</strong>.monotony(t * t * f(t), <strong>TPT</strong>.INCREASING);<br />
A filter has the ability to remove certain frequency-elements from a signal. For example a<br />
low pass filter removes frequency elements above a cut off frequency fc. The higher<br />
frequencies will be removed without affecting other (lower) frequency elements. If this is<br />
done using an ideal low pass filter, the transfer function of such a filter might be
Page 34 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong>
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 35<br />
IIR-Filter design<br />
One method for IIR-filter design is the transformation of analogous filter prototypes. A<br />
classic or perfect filter design is achieved through discrete filters. This is usually be done<br />
using a low pass filter model <strong>and</strong> sampling of the signal to a series of discrete elements.<br />
Well known methods of this are Butterworth or Chebycheff filters. All filter specifications<br />
are given in the frequency domain (cut-off frequency etc.) <strong>and</strong> supplemented by the filter<br />
order.<br />
Other methods exist which have not been implemented yet.<br />
IIR-filter usually have the advantage of fulfilling the frequency-domain specifications with<br />
a small filter order N. The disadvantage of a nonlinear phase response can be negotiated<br />
by bi-directional filtering. Time domain requirements like impulse response requirements<br />
can be fulfilled by the direct methods. A specification in time <strong>and</strong> frequency domain is<br />
usually not easy.<br />
FIR-filter design<br />
In contrast to IIR-filter design FIR-filter design is thoroughly limited to discrete<br />
implementations. Thus the design methods for FIR-filter are based on the direct<br />
approximation of the specified frequency response of the discrete system. The simplest<br />
design method is called the windowing method. The order <strong>and</strong> amplitude response of the<br />
filter is stated in the frequency domain. From this transfer function the ideal impulse<br />
response is calculated. This impulse response is usually infinite <strong>and</strong> not causal <strong>and</strong> thus<br />
cannot be modelled. In order to realise the filter only a section of the ideal impulse<br />
response is considered. The section is built by using a window function. Within <strong>TPT</strong><br />
different windowing functions are provided (RECTANGULAR, HANNING, HAMMING,<br />
BLACKMAN). The filter coefficients correspond to the coefficients of the window function.<br />
The signal will be multiplied in the time domain. Thus the impulse response of the filter is<br />
equal to the values of the filter function. The multiplication in the time domain leads to a<br />
convolution of the signal with the window function in the frequency domain.<br />
In this sense the rectangular window is optimal in the time domain but due to the<br />
convolution it leads to ripples in the frequency domain. This means the gain of all<br />
frequency fractions in the pass-b<strong>and</strong> is not equal. By using different window-functions<br />
this can be improved to the expense of the time domain behaviour. For example the<br />
Hamming-window is a good compromise between time <strong>and</strong> frequency domains.<br />
1<br />
0.9<br />
0.8<br />
0.7<br />
0.6<br />
0.5<br />
0.4<br />
0.3<br />
0.2<br />
0.1<br />
Rectangular<br />
Blackman<br />
Hamming<br />
Hanning<br />
0<br />
-25 -20 -15 -10 -5 0 5 10 15 20 25<br />
The impact of choice of window width is that the larger the window, the ripples in time<br />
domain are more pronounced (Gibbs phenomenon). Also the steepness between pass<br />
<strong>and</strong> blocking b<strong>and</strong> of the filter increases with the window width or order respectively.<br />
With increasing filter order the frequencies are better separated but the distortion also<br />
increases. The balance between distortion <strong>and</strong> frequency-separation must be found.
Page 36 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
The right filter design method<br />
In the context of filtering the requirements from chapter 2.8.1must be considered.<br />
A good frequency separation can be achieved with an IIR-filter. Butterworth or Chebycheff<br />
approximations result in a ripple free pass b<strong>and</strong>. Also the non-linear phase response can<br />
be controlled by bi-directional filtering. The major disadvantage of frequency-domain IIR<br />
filter is the poorly controlled time domain behaviour. FIR-filters achieve a better frequency<br />
selection by increasing the order M. The time domain requirements behave similarly to<br />
IIR-filters. Filter coefficients <strong>and</strong> impulse response can be adapted to meet cut-off <strong>and</strong><br />
overshoot requirements. Manipulation of bidirectional filtering or the linear phase can<br />
achieve delay-free filtering.<br />
All FIR-methods result in ripple of the pass-b<strong>and</strong> gain. By normalization of filter<br />
coefficients for any FIR-filter a gain of 0db at a frequency of zero Hz can be achieved.<br />
Thus the filter design using windowing method combines zero phase, frequency<br />
separation <strong>and</strong> overshoot.<br />
timed-float <strong>TPT</strong>.filterFIR(timed-float expr, int order, int type, int windowtype,<br />
float passb<strong>and</strong>Min, float passb<strong>and</strong>Max)<br />
Applies a FIR-filter to the signal expr <strong>and</strong> returns the filtered signal. The filter order <strong>and</strong><br />
the window function is specified. The filter coefficients are identical to the ideal windowed<br />
impulse response. FIR filters have the disadvantage of fulfilling frequency requirements<br />
with a high filter order. The implemented methods design filter with a linear phase<br />
response. From this the major advantage compared to IIR filter arise, the constant time<br />
delay d = M/2 which can be utilized for delay compensation off-line.<br />
Another advantage is the simple relation between filter coefficients <strong>and</strong> impulse response.<br />
The time domain behaviour can be seen easily at the filter coefficients:<br />
The parameters are defined as follows:<br />
expr Signal<br />
order Order M of the filter<br />
type Filter type:<br />
• <strong>TPT</strong>.LOWPASS<br />
• <strong>TPT</strong>.HIGHPASS<br />
• <strong>TPT</strong>.BANDPASS<br />
windowtype window type for filter:<br />
• <strong>TPT</strong>.RECTANGULAR<br />
• <strong>TPT</strong>.HANNING<br />
• <strong>TPT</strong>.HAMMING<br />
• <strong>TPT</strong>.BLACKMAN<br />
passb<strong>and</strong>Min lower pass b<strong>and</strong> frequency [Hz]<br />
passb<strong>and</strong>Max maximum pass b<strong>and</strong> frequency [Hz]
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 37<br />
# Low pass FIR filter of order 100 <strong>and</strong> a cutoff frequency of 5 Hertz.<br />
# The filter coefficient or window type is Hanning<br />
acc_flt(t) := <strong>TPT</strong>.filterFIR(acc(t), 100, <strong>TPT</strong>.LOWPASS, <strong>TPT</strong>.HANNING, 0.0, 5.0);<br />
timed-float <strong>TPT</strong>.filterIIR(timed-float expr, int order, int type, int prototype, float<br />
passb<strong>and</strong>Min, float passb<strong>and</strong>Max)<br />
Similar to FIR filter this function filters the signal expr using the specified IIR-filter <strong>and</strong><br />
returns the filtered signal.<br />
A classically designed analogue filter is transformed into the discrete filter via frequency<br />
transformation of the low-pass prototype <strong>and</strong> discretization. The methods are called<br />
similar to the analogous design methods Butterworth <strong>and</strong> Chebycheff (type one with<br />
ripples of 1db). The filter specification is given in frequency domain extended with filter<br />
order.<br />
IIR-Filter have the advantage to fulfill frequency requirements with a small filter order N.<br />
The disadvantage of the nonlinear phase response can be negotiated with bi-directional<br />
filtering. The time domain requirements (e.g. overshoot) could be fulfilled with direct<br />
methods (not implemented). Specification in time <strong>and</strong> frequency domain is not possible<br />
offh<strong>and</strong>.<br />
The parameters are defined as follows:<br />
expr Signal<br />
order order<br />
type filter type:<br />
<strong>TPT</strong>.LOWPASS<br />
<strong>TPT</strong>.HIGHPASS<br />
<strong>TPT</strong>.BANDPASS<br />
prototype prototype of the filter<br />
<strong>TPT</strong>.BUTTERWORTH<br />
<strong>TPT</strong>.CHEBYSHEV<br />
passb<strong>and</strong>Min lower pass b<strong>and</strong> frequency [Hz]<br />
passb<strong>and</strong>Max maximum pass b<strong>and</strong> frequency [Hz]<br />
# Second order lowpass Butterworth filter with a cut off frequency of 5 Hertz<br />
acc_flt(t) := <strong>TPT</strong>.filterIIR(acc(t), 2, <strong>TPT</strong>.LOWPASS, <strong>TPT</strong>.BUTTERWORTH, 0.0, 5.0);<br />
timed-float <strong>TPT</strong>.filterMA(timed-float expr, int order, int type)<br />
Filters the signal expr using a moving average filter <strong>and</strong> returns the mean value or the<br />
st<strong>and</strong>ard deviation of the last time steps using order. This filter is a special kind of an FIR<br />
filter having the same filter coefficients for all time steps.<br />
The parameters are defined as follows:<br />
expr Signal<br />
order order of the filter<br />
type one of the following:<br />
<strong>TPT</strong>.SIGNAL (filtered signal)<br />
<strong>TPT</strong>.SIGMA (st<strong>and</strong>ard deviation)
Page 38 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
# Moving average of the last 100 time samples<br />
acc_flt(t) := <strong>TPT</strong>.filterMA(acc(t), 100, <strong>TPT</strong>.SIGNAL);<br />
timed-boolean <strong>TPT</strong>.stepDetection(timed-float expr, int order, float scale)<br />
Step detection analyses signals in order to find significant steps in the signal. This<br />
function works also for noisy signals.<br />
The step detection uses the so called “double sigma method”. A step in a signal is<br />
detected when two consecutive samples of the signal have a minimum difference to a<br />
moving average of the signal that is larger as scale times the st<strong>and</strong>ard deviation of the<br />
moving average with order “order”.<br />
The parameters are defined as follows:<br />
expr Signal<br />
order order of the moving average filter<br />
scale scales the st<strong>and</strong>ard deviation sigma.<br />
# step detection in the acceleration pedal value<br />
# the moving average must be exceeded with at minimum 1.7 * Sigma<br />
# the moving average uses the 50 last time steps<br />
x = <strong>TPT</strong>.BooleanX();<br />
x(t) := <strong>TPT</strong>.stepDetection(accleleration_pedal(t), 50, 1.7);<br />
2.9 Temporal regular expressions<br />
<strong>TPT</strong>.regexp(regexp re)<br />
This function defines a regular expression in <strong>TPT</strong>. A regular expression on the basis of the<br />
following operators can be defined in the braces. The function <strong>TPT</strong>.regexp() gives<br />
each interval where the expression is true.<br />
# search each interval where c is first 3 <strong>and</strong> then 4<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([c(t) == 3] [c(t) == 4]);<br />
[timedExpr e]<br />
[timedExpr e]{float min}<br />
[timedExpr e]{float min, float max}<br />
This element is the basis of regular expressions. In the simplest case a time dependent<br />
logical expression is specified in brackets.<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([(t >= 1 <strong>and</strong> t < 2) or (t >= 4 <strong>and</strong> t < 7)]);<br />
# iv is defined in the interval [1,2) <strong>and</strong> [4,7)<br />
Optionally the minimum time of the matching intervals can be specified in curly braces. If<br />
the operation e is true in a given interval but is only true for a time shorter than min, it<br />
does not match.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 39<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([(t >= 1 <strong>and</strong> t < 2) or (t >= 4 <strong>and</strong> t < 7)]{2});<br />
# iv is defined only in the interval [4,7) because [1,2) is shorter than 2<br />
Also a minimum <strong>and</strong> maximum time can be specified in curly braces. Only intervals of a<br />
minimum length will match. If the interval is longer than the maximum specified it will be<br />
set at the maximum.<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([(t >= 1 <strong>and</strong> t < 2) or (t >= 4 <strong>and</strong> t < 7)]{2,2});<br />
# iv is defined in the interval [4,6) it is cut to length 2<br />
regexp1 regexp2<br />
As many regular expressions as desired can be written one after another without an<br />
explicit operator. The expressions will be evaluated in order left to right.<br />
# search each interval where c is first 3 <strong>and</strong> then 4<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([c(t) == 3] [c(t) == 4]);<br />
regexp?<br />
The suffix “?” helps to define expression that match conditionally. This means that the<br />
expression matches also to a void interval.<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([c(t) == 3] [c(t) == 5]? [c(t) == 4]); # 333444 or 33355444<br />
regexp+<br />
The suffix “ + “ helps to define expressions that match at least once but also very often (1<br />
to n-times).<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp(([c(t) == 3][c(t) == 2])+); # 3333222333222333222………<br />
regexp*<br />
The suffix “ * “ helps to define expressions that match arbitrarily often (0- to n-times).<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp(([c(t) == 3][c(t) == 2])*); # 3333222333222333222………<br />
(regexp)<br />
Expressions can be parenthesized generating blocks using braces ‚(’ <strong>and</strong> ‚)’.
Page 40 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp(([c(t) == 3][c(t) == 4])+); # 333444333444333444………<br />
name := regexp<br />
Expressions in parentheses can be explicitly named in order to access the matched<br />
expression later on.<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp(([c(t) == 3] cEquals4 := [c(t) == 4])+); #<br />
333444333444333444………<br />
In this example cEquals4 is defined as a void variable. After the calculation the part<br />
intervals that match c(t)==4 are taken.<br />
regexp1 | regexp2<br />
This operator is used to match either the left or the right expression.<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp(([c(t) == 3][c(t) == 4])|[c(t) == 5]); # 333444 oder 555555<br />
The example matches to intervals where c is first 3 <strong>and</strong> then 4 or constant 5.<br />
^regexp<br />
The prefix “^“ of a regular expression says that this expression must start at the very<br />
beginning of the actual time interval.<br />
iv1 = <strong>TPT</strong>.Boolean();<br />
iv1 := <strong>TPT</strong>.regexp([t >= 1]); # matches to the interval [1, tende)<br />
iv2 = <strong>TPT</strong>.Boolean();<br />
iv2 := <strong>TPT</strong>.regexp(^[t >= 1]); # doesn’t match since t >= 1 is not true at t=0<br />
regexp$<br />
The suffix “$“ says that the expression must match until the very end of a time interval.<br />
iv = <strong>TPT</strong>.Boolean();<br />
iv := <strong>TPT</strong>.regexp([c(t) == 3]$);<br />
This expression matches only to intervals where in the actual context c(t) == 3 is true<br />
until the end of the interval.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 41<br />
2.10 Context intervals <strong>and</strong> the during operator<br />
2.10.1 During-Operator<br />
The during-operator gets a time interval as a parameter <strong>and</strong> is used in the same way as<br />
a Python keyword like (if, for etc.). An intersection of the actual assessment <strong>and</strong> the<br />
specified time interval is build. For each interval in the given intersection, the code of the<br />
during-block is executed.<br />
In other words the during-operator defines a interval of time where operations are<br />
evaluated similar to “while(time interval)”. This interval is the context interval. The<br />
definition of the time interval where the statements inside “during” can be done explicitly<br />
or implicitly. Within the during-statement the time is defined locally <strong>and</strong> starts with zero.<br />
Example explicit definition:<br />
# define the variable x<br />
x = <strong>TPT</strong>.Double();<br />
during <strong>TPT</strong>.Interval(10ms, 100ms):<br />
# the actual context interval is limited to [10ms … 100ms)<br />
x(t) := sin(t*50)+1.0;<br />
# the function x(t) is evaluated for “local” times 0..90ms<br />
Example implicit definition:<br />
foo = <strong>TPT</strong>.Double ();<br />
overflow = <strong>TPT</strong>.Boolean();<br />
foo := …<br />
overflow := <strong>TPT</strong>.regexp([foo(t) > 100.0]);<br />
overflowAmount = <strong>TPT</strong>.Double(); # create an assessment var of type `double`<br />
during overflow:<br />
overflowAmount := <strong>TPT</strong>.integral(foo(t)-100); # integrate the exceedance<br />
Example nested during:foo = <strong>TPT</strong>.Double ();<br />
bar = <strong>TPT</strong>.Boolean();<br />
foo := …<br />
bar := …<br />
# assume, foo is defined in the interval [1, 17) <strong>and</strong> bar<br />
# is defined in the intervals [2,5) <strong>and</strong> [6,19)<br />
during foo:<br />
# the actual context interval is limited to [1,17). This block is executed<br />
# once<br />
[…]<br />
# nested during:<br />
during bar:<br />
# the actual context interval is limited to [2,5) resp [6,17). This<br />
# is executed twice<br />
[…]
Page 42 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
2.10.2 “This” operator<br />
Within a context interval defined by “during” some operations on the interval itself can be<br />
executed. The pre-defined “interval variable” is named “This”. The executable operations<br />
are all operations that can be used for intervals (cf. Section 2.4). Useful are only some of<br />
these operations namely:<br />
• This.getEndTime() returns the last time value of the context interval.<br />
• This.getLength() returns the length of the context interval <strong>and</strong> is<br />
semantically the same as This.getEndTime().<br />
• This.getRightLimit() returns the largest sampling-point of the interval.<br />
2.11 Transformations of the assessment pre-processor<br />
The pre-processor transforms all elements <strong>and</strong> statements of the assessment script that<br />
are not st<strong>and</strong>ard-python into st<strong>and</strong>ard python. It is generally possible to write assessment<br />
script in st<strong>and</strong>ard-Python but this code is much more complicated to underst<strong>and</strong><br />
2.11.1 Compatibility with former versions of <strong>TPT</strong><br />
Since the language for test assessment has been consolidated <strong>and</strong> slightly redesigned to<br />
be easier to use, there are some important compatibility issues to know when upgrading<br />
from older <strong>TPT</strong> versions.<br />
A lot of additional features of the new <strong>Assessment</strong> language do not affect the behaviour<br />
of assessment scripts written with older versions (up to 2.4) of <strong>TPT</strong>. These features are<br />
described in the previous sections.<br />
In the following only those features are listed that must be considered when upgrading<br />
from <strong>TPT</strong> version 2.2 - 2.4 to version 2.6 or above. These features can be summarized as<br />
follows:<br />
• The distinction between assessment channels <strong>and</strong> assessment variables has been<br />
omitted<br />
• Meaning of time variable “t” has been consolidated<br />
The time „t“ within regular expressions is in <strong>TPT</strong> 2.6 the local time within the<br />
context-intervals.<br />
2.11.2 Obsolete assessment functions in <strong>TPT</strong> 2.6<br />
The following functions of the former assessment-versions should not be used anymore.<br />
variable.getStepSize()<br />
This function should not be used anymore. Please use <strong>TPT</strong>.getStepSize() ad. It<br />
returns the step-size independent of the variable.<br />
res = <strong>TPT</strong>.getStepSize(); # Abfrage der Schrittweite<br />
variable.left()<br />
This function should not be used anymore. Please use variable.getLeft() instead.
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 43<br />
res = <strong>TPT</strong>.getLeft();<br />
variable.right()<br />
This function should not be used anymore. Please use variable.getRight() instead.<br />
res = <strong>TPT</strong>.getRight();<br />
number variable.getLeft ()<br />
renamed to getLeftValue()<br />
number variable.getRight ()<br />
renamed to getRightValue()<br />
## - Comment<br />
This function should not be used anymore. Please use variable.setComment()<br />
instead.<br />
i = <strong>TPT</strong>.Int();<br />
…<br />
if cond:<br />
i(t) := sin(t);<br />
i.setComment(“i ist ein Sinuskanal“);<br />
else:<br />
i(t) := cos(t);<br />
i.setComment(“i ist ein Kosinuskanal“);<br />
variable.result<br />
Please use variable.setResult() instead.<br />
interval.getSize()<br />
This function doesn’t exist anymore please use interval.getSamplePointSize()<br />
instead.<br />
<strong>TPT</strong>.DoubleVariable([string varname])<br />
dv = <strong>TPT</strong>.DoubleVariable() is identical to dv = <strong>TPT</strong>.Double(„dv“).<br />
<strong>TPT</strong>.FloatVariable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int8Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()
Page 44 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
<strong>TPT</strong>.UInt8Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int16Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.UInt16Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int32Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.UInt32Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int64Variable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.BooleanVariable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.StringVariable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.VoidVariable([string varname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.DoubleChannel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.FloatChannel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int8Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.UInt8Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()
<strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong> Page 45<br />
<strong>TPT</strong>.Int16Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.UInt16Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int32Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.UInt32Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.Int64Channel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
<strong>TPT</strong>.BooleanChannel([string channelname])<br />
Cf. <strong>TPT</strong>.DoubleVariable()<br />
Channel.setName(string exportName)<br />
Please declare the Name with the declaration.<br />
variable record.getChannel(string variablename)<br />
Obsolete function. Use record.getVariable(string variablename) instead.<br />
record.getOverallTimeScope()<br />
Obsolete function. Use record.getCompleteInterval() instead.<br />
record PyTestRecord(string filename)<br />
Obsolete function. Use <strong>TPT</strong>.readRecord() instead.<br />
record <strong>TPT</strong>.TestRecord()<br />
Obsolete function. Use <strong>TPT</strong>. Record() instead.<br />
record PyTestRecord(string filenameToRead)<br />
Obsolete function. Use <strong>TPT</strong>. readRecord(filenameToRead) instead.<br />
<strong>TPT</strong>.writeExportRecord()<br />
Obsolete. Same as <strong>TPT</strong>.writeExportRecord(“testcase.tresult.tptbin”).<br />
Use this statement instead.
Page 46 <strong>TPT</strong> <strong>Assessment</strong>-<strong>Language</strong><br />
<strong>TPT</strong>.writeExportedRecord()<br />
Obsolete. Same as <strong>TPT</strong>.writeExportRecord(“testcase.tresult.tptbin”). Use<br />
this statement instead.<br />
<strong>TPT</strong>.writeExportedRecord(string filename)<br />
Obsolete. Same as <strong>TPT</strong>.writeExportRecord(filename). Use this statement<br />
instead.<br />
<strong>TPT</strong>.getExportedRecord()<br />
Obsolete (renamed). Same as <strong>TPT</strong>.getExportRecord().<br />
<strong>TPT</strong>.clearExportRecord()<br />
Obsolete.<br />
<strong>TPT</strong>.clearExportedRecord()<br />
Obsolete.