Content

Overview

Definitions

How Transformations and Calculations are Processed

Numeric Data Types in Calculations

Maximum Numeric Data Values

About Parsing and Locale

Transformation Rules

Calculation Rules

In General...

Parameter Syntax

Internal and Reference Calculations

Standard Operators

Expression Length

Internal Calculations

In General...

Simple Examples

Wildcards

Max Qualifier

Returning Text from a Calculation

Passing Other Data Types into a Calculation

Excluding Data

Referencing Data Items by an SDIDataItem Column

Column Name Reference

Parameter Limit Reference

Attribute Reference

Referencing Data Sets by an SDIData Column

Filtering

Column Name Reference

Multiple Column Expressions with Logical AND

Attribute Reference

Attributes Not Defined for a Data Set

Referencing an SDI Column

Column Name Reference

Attribute Reference

 

Reference Calculations

In General...

Explicit Reference to a Single SDI

Foreign Key Reference to a Single SDI

Reverse Foreign Key Link

SDI Relation

SDI Data Relation

Array Calculations

Sample Parent/Child Relation

Using Calculations with QC Samples (AQC)

Groovy Examples

Groovy Examples: Numeric

Groovy Examples: Other Data Types

Java Objects Passed Into Groovy Calculation Expressions

Expression Library and Expression Editor

 

Overview

Top ../images/arwup.gif (846 bytes)

Definitions

 

You can perform two mathematical operations on entered numeric data:

Operation Use
Transformations Modify data, such as round or truncate the entered value.
Calculations Perform arithmetic calculations, such as add to or subtract from the entered value.

After creating an expression to define one of these operations, you must associate the operation with a Parameter in a Parameter List.

How Transformations and Calculations are Processed

 

This is a high-level overview of how Transformations and Calculations are processed during numeric data entry:

1.

A User enters a data value:

SDIDataItem.EnteredText = String entered during Data Entry
  = 10.2676700

The system drops trailing zero significant digits, operators, and text:

SDIDataItem.EnteredValue = 10.26767

 

2.

If the Parameter List defines a Transformation Rule, the system applies it:

SDIDataItem.TransformRule = Transformation Rule defined by Parameter List
  = round( [this], 3 )
SDIDataItem.TransformValue = Result of the Transformation
  = 10.268

If the Parameter List does not define a Transformation Rule, SDIDataItem.EnteredValue = SDIDataItem.TransformValue.

If the Parameter List defines a Display Format, it is applied to SDIDataItem.TransformValue to arrive at the Display Value.

 

3.

SDIDataItem.TransformValue is used to evaluate Calculation Rules and Parameter Limits.

SDIDataItem.TransformValue is used to evaluate Specification Limits only if the Specification does not define a Transformation Rule.

 

4.

If the data are checked against a Specification, what happens next depends on whether or not the Parameter List defines a Transformation Rule:

5.
a.

If both the Specification and the Parameter List define a Transformation Rule, the Specification's Transform Rule is applied to the result of the Parameter List's Transformation (value in SDIDataItem.TransformValue).

SpecParamItems.TransformRule = Transformation Rule defined by Specification
    round( [this], 2 )
SDIDataItem.TransformValue = Result of the Transformation defined by the Parameter List
  = 10.268
SDIDataItemSpec.TransformValue = 10.27
SDIDataItemSpec.CheckedValue = 10.27
  = "Checked Value" reported in Data Entry pages

SDIDataItemSpec.TransformValue is used to evaluate Specification Limits.

5.
b.

If the Specification defines a Transformation Rule but the Parameter List does not, the Specification's Transformation Rule is applied to SDIDataItem.EnteredValue:

SpecParamItems.TransformRule = Transformation Rule defined by Specification
    round( [this], 1 )
SDIDataItem.EnteredValue = 10.26767
SDIDataItemSpec.TransformValue = 10.3
SDIDataItemSpec.CheckedValue = 10.3
  = "Checked Value" reported in Data Entry pages

SDIDataItemSpec.TransformValue is used to evaluate Specification Limits.

Numeric Data Types in Calculations

 

LabVantage has two numeric Data Types that are used in Calculations:

"Numeric with Calculation Expression" (N) refers to entered numeric data or calculated data that can be manually changed in Data Entry (editable).
"Numeric Calculation" (NC) refers to calculated data that cannot be manually changed in Data Entry (readonly).

Maximum Numeric Data Values

 

If using an Oracle DBMS, LabVantage supports numeric input up to a maximum value of 12 digits and does not return more than 13 significant digits. Attempting to return more will return zeros as placeholders beyond the 13 digits.

If using a SQL Server DBMS, LabVantage supports numeric input up to a maximum value of 10 digits.

When executing Calculations, the LabVantage calculation engine does not preserve and honor rules of significance and precision across mathematical operations. The calculation engine simply processes the numeric value of each input.

Calculated values are stored both as text (in SDIDataItem.EnteredText) and as a number (in SDIDataItem.EnteredValue). SDIDataItem.EnteredValue holds the calculated value to the maximum precision supported by LabVantage. The Display Value is applied to the calculated value to alter presentation of the result. For example, if a Calculation is evaluated at 0.3333333333, the Display Value could be set to show this as 0.33.

About Parsing and Locale

 

LabVantage numeric parsing routines ignore the thousands separator on input. This can result in unexpected consequences when executing Actions through the ToDo List, such as when executing an Action as a Task (see Action Processing and ToDoList Maintenance).

Tasks are executed as the (system) user, which uses the same Locale as the Application Server. If you execute an EnterDataItem Task with an EnteredText value of 38.20 and the Application Server is running in Danish Locale, the Application Server will correctly interpret the 38.20 as Danish numerical format. However, since LabVantage ignores the thousands separator, the user will see 3820, regardless of the user's Locale.

 

Transformation Rules

Top ../images/arwup.gif (846 bytes)

Transformation Rules modify data, such as round or truncate the entered value. See How Transformations and Calculations are Processed above.

When creating Transformation Rules, the variable [this] represents the Entered Value.  For example, this Transformation Rule rounds the Entered Value of 2.179 to one significant digit:

Transformation Rule Entered Value Transform Value
round ([this], 1) 2.179 2.2

Create Transformation Rules in the Expression Editor.

 

Calculation Rules

Top ../images/arwup.gif (846 bytes)

In General...

 

Calculation Rules are expressions that perform basic arithmetic calculations, such as add to or subtract from an entered value.

LabVantage supports expressions written in these languages:

LabVantage (LabVantage's proprietary expression language).
Groovy (maintained by the Apache Software Foundation at http://www.groovy-lang.org/).

Parameter Syntax

 

When writing Calculation expressions, you must define all information necessary to uniquely identify each Parameter used in the Calculation.   For each group of terms required to identify the Parameter down to the Replicate level:

LabVantage Syntax Groovy Syntax
Enclose the group within square brackets, e.g.,

[group]

Preface the group with a dollar sign, and enclose the group with curly braces, e.g.,

${group}

Use a pipe (|) to separate SDI qualifiers, Parameter List qualifiers, and Parameter qualifiers.
Between pipes, use a semicolon to delimit each qualifier.

Using LabVantage syntax, you can build expressions that identify data from the SDI to Replicate level. In general, the complete form of such an expression is:

[SDI|PL;PLV;Var;DS|P;PT;R;DI]

where

SDI = SDI Reference
PL = Parameter List
PLV = Parameter List Version
Var = Parameter List Variant
DS = Data Set Number (see Note below)
P = Parameter
PT = Parameter Type
R = Replicate
DI = SDIDataItem Column or Data Item Attribute
NOTE:   Two highly specialized variations on Data Set syntax are described in Referencing Data Sets by an SDIData Column.

The equivalent Groovy syntax is:

${SDI|PL;PLV;Var;DS|P;PT;R;DI}

Internally, LabVantage identifies a Groovy expression by automatically prefacing the expression with $G{ and ending it with }.

NOTE:   Variants on Data Item syntax are described in Referencing Data Items by an SDIDataItem Column.

To avoid confusion, the bulk of examples that follow use LabVantage syntax. For examples of Groovy expressions, see Groovy Examples.

Internal and Reference Calculations

LabVantage supports two types of Calculations:

Internal Calculations involve only one SDI. Accordingly, you need to specify only the qualifiers you need to identify the Parameter List and Parameter, e.g.,

[PL;PLV;Var;DS|P;PT;R;DI]

Reference Calculations involve more than one SDI. This is where you must also specify the "SDI Reference" qualifiers, e.g.,

[SDI|PL;PLV;Var;DS|P;PT;R;DI]

As shown, the syntax for writing expressions that perform Reference Calculations is an extension to the syntax used for Internal Calculations. In other words, it is best to gain familiarity with Internal Calculations before attempting Reference Calculations.

Standard Operators

 

LabVantage uses the following standard mathematical operators for expressions created using the Expression Library and Expression Editor:

Operator Operation   Operator Operation
+ Addition   ^ Exponentiation
- Subtraction   < Less Than
* Multiplication   > Greater Than
/ division   = Equal To

Expression Length

 

Expressions are stored in the Expression.Expression column. The data type of this column is CLOB. Expressions longer than 2000 characters can therefore be stored.

 

Internal Calculations

Top../images/arwup.gif (846 bytes)

In General...

 

You do not need to specify all qualifiers... only what you need to identify the desired item. You can:

Truncate the Parameter List or Parameter information...
 

or...

Omit the Parameter List qualifiers and specify only the Parameter.

Simple Examples

 

As a start, these are simple examples of valid variables using the Parameter List "PL_01" and Parameter "Cu". Note the use of the word "current"... this means the item being edited... think of it as "this". For example, if you are entering data for Sample "S-001" and the Calculation Rule specifies that Parameter "Cu" is in the "current" Parameter List, the Calculation Rule is done on S-001's Parameter List for which you are entering data... in other words, "this" Parameter List.

The Variable... Defines the value of Parameter Cu when...

[Metals;1;Cur;2|Cu;Prod;3]

Cu is in the "Metals" Parameter List, Version 1, Variant "Cur", Data Set Number 2...
  and...
You want to use Replicate 3 of Parameter Cu with Parameter Type "Prod".

[Cu]

Cu is in the current Parameter List.

The calculation uses the current Parameter List Version, Variant, and Data Set Number, plus the current Parameter Type and Replicate.

[Cu;Prod]

Cu is in the current Parameter List...
  and...
Parameter Type "Prod" is associated with Cu.

The calculation uses the current Parameter List Version, Variant, and Data Set Number, plus the current Parameter Replicate.

[Metals|Cu]

Cu is in the "Metals" Parameter List.

The calculation uses the current Parameter List Version, Variant, and Data Set Number, plus the current Parameter Type and Replicate.

[Metals;1|Cu;Prod]

Cu is in the "Metals" Parameter List, Version 1...
  and...
Parameter Type "Prod" is associated with Cu.

The calculation uses the current Parameter List Variant and Data Set Number, plus the current Parameter Replicate.

As an example of a simple Internal Calculation, consider summing the values of Parameters Fe and Ni to determine the value of Parameter Steel (both Fe and Ni are in the same Parameter List). For Steel, you would define the Calculation [Fe] + [Ni]. For Fe = 5 and Ni = 1, the value of Steel would be 6.

Wildcards

 

You can use these wildcards in place of any value:

Wildcard Meaning
* All values of an item.
# The current value of an item... in other words, "this" item.
Examples Using LabVantage Syntax

Using LabVantage syntax, wildcards must reference columns of data type "Number". For example:

This syntax... Performs the calculation using...
[ParamListId;*;VariantId;*|ParamId;ParamType;ReplicateId]All Versions and Data Set Numbers of the Parameter List.
[#;#;#|#;ParamType;#]
The current Parameter List, Version, Variant, Parameter, and Replicate...
 and...
The explicitly specified Parameter Type.
[#;3;*|#;*;9]
All Variants of Version 3 of the current Parameter List...
 and...
Replicate 9 of all Parameter Types of the current Parameter.
sum( [Al;*;*] )The sum of all Parameter Types and Replicates for Parameter Al.
Examples Using Groovy Syntax

Using Groovy syntax, wildcards can reference columns of any data type. For example:

This syntax... Performs the calculation using...
${Al;*;*}.sum() The sum of all Parameter Types and Replicates of Parameter Al.
This syntax... Returns...
return ${Al;*;*;enteredtext} The enteredtext column of the SDIDataItem table for all Parameter Types and Replicates of Parameter Al.

Note that in the Simple Examples (where information was truncated or omitted), the missing values are treated as #. For example:

[Cu] is the same as [#;#;#|Cu;#;#]

As another example of using wildcards, you can create a single expression that calculates multiple values, with each calculation based on a set of Replicates for a unique Parameter. Consider a Parameter List that defines the floor space of a room using the Parameters Length, Width, and Area.  You want to calculate the area by taking three sets of measurements, each with a different measurement instrument.  You therefore specify three Replicates for each Parameter (the Replicate column is for the purpose of clarifying the example):

SDI Parameter List Parameter Value Replicate
Room Floor_Space Length   1
Length   2
Length   3
Width   1
Width   2
Width   3
Area   1
Area   2
Area   3

You can create a single expression to calculate three values for Area.  The expression for each Area Replicate number would use the Length and Width values of the corresponding Replicate number.  For example, the Area of Replicate number 1 would calculate using the Length and Width of Replicate number 1. To create this expression, use the following syntax for the Area calculation, which assumes that Length and Width are in the current Parameter List, and the Parameter Type is Standard:

Area = [Length;Standard;#]*[Width;Standard;#]

The # symbol tells the calculation engine to use the value of each Replicate in sequence.  Of course, the engine will not calculate Area until both Length and Width values are entered.  The results:

SDI Parameter List Parameter Value Replicate
Room Floor_Space Length  20 1
Length  40 2
Length  60 3
Width  20 1
Width  40 2
Width  60 3
Area  400 1
Area  1600 2
Area  3600 3

You can also use the asterisk (*) as a wildcard character to calculate a single value based on all Replicates for a Parameter.  This is useful when executing Aggregate functions such as averaging (see Expression Library and Expression Editor below).  For example, to calculate the average of the Lengths above, the expression

AverageLength = avg([Length;Standard;*])

takes the average of 20, 40, and 60 to give a value of 40.

Max Qualifier

 

Both the Replicate and Data Set Number accept an additional operator: "max". This uses the Parameter with the (arithmetically) highest Data Set Number or the highest Replicate number. Examples:

This syntax... Performs the calculation using...
[ParamId;ParamType;max] The highest Replicate number.
[ParamListId;#;#;max|ParamId;#;max] The highest Data Set Number.

Returning Text from a Calculation

 

You can write an expression that returns text as a result of a calculation.  For example, consider a Parameter List with the Parameters Al, Fe, and Ni. The following calculation expression is applied to the Parameter Al:

if ( [Ni] < [Fe], [Ni], [Fe] )

This expression performs the calculation using numeric values of the Parameters. If the value of Ni is less than the value of Fe, the value of Al is the value of Ni; otherwise, the value of Al is the value of Fe:

Ni Fe Al
3 5 3
5 3 5

Now. look at the following expression:

if ( [Ni] < [Fe], "<" + string([Fe]), string([Ni]) )

This time, if the numeric value of Ni is less than the numeric value of Fe, the value of Al is the < character followed by the text string representing the numeric value of Fe; otherwise, the value of Al is the text string representing the numeric value of Ni:

Ni Fe Al
3 5 <5
5 3 5

Use these guidelines when returning text from a calculation (we are using our example Parameter List and applying the calculations to Al):

Use double quotes to define string literals.

Example:

if ( [Ni] < [Fe], "Good", "Bad" )

If the value of Ni is less than the value of Fe, the value of Al is the text string Good; otherwise, the value of Al is the text string Bad.

Use string([p]) to return the text defined by a Parameter (where p is the Parameter variable). Use the + symbol to append strings.

Example:

if ( [Ni] < [Fe], "<" + string([Fe]), "Re-enter" )

If the value of Ni is less than the value of Fe, the value of Al is the < character appended to the text string representing the numeric value of Fe; otherwise, the value of Al is the text string Reenter

Never reference a Parameter to itself. In other words, if you calculation is applied to Al, do not reference Al in the calculation.

For example, the following calculation applied to Al will fail:

if ( [Al] < [Fe], [Al], [Fe] )

This is a circular reference. It will loop for about 30 seconds, then crash the session.

Passing Other Data Types into a Calculation

 

If you write your expression in Groovy, you can pass these values into a calculation (see Groovy Examples: Other Data Types):

NOTE:   For "Text" Data Type, the Empty Text Parameter Mode property in the Data Entry Policy determines whether a null or an empty string is returned if no value is entered for a Parameter.
Data Type Description
String Can be a Reference Type, Validated Reference Type, Text, or SDI (as defined by the Data detail of the Parameter List Maintenance page).

This value is taken from the TransformText column of the SDIDataItem table.

Date This value is taken from the TransformDt column of the SDIDataItem table.

Excluding Data

 

You can exclude certain Data Items from Calculations by either of these methods:

Call the SetCalcExclude Action.
Mark the Data Items as "Outliers" in the GWT Data Entry Page Toolbar.

Referencing Data Items by an SDIDataItem Column

 
Column Name Reference

Calculations can reference columns in the SDIDataItem table. How this works depends on whether the Calculation expression is written in LabVantage syntax or Groovy syntax:

LabVantage Syntax

Using LabVantage syntax, Calculations can reference any single column in the SDIDataItem table. Using the form [P;PT;R;DI], specify the SDIDataItem column for DI. Note that if you use LabVantage syntax, you can specify only one SDIDataItem column, and it must be of data type "Number". As an example, assume these relationships in SDIDataItem:

SDIDataItem
SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Param
Id
Param
Type
Replicate
Id
Peak
Offset
SampleS-001Metals111AgStandard1300
SampleS-001Metals111AgStandard2600

In this case, you could reference a PeakOffset column using either of these expressions:

[Ag;Standard;1;peakoffset]

This would return 300.

[Ag;Standard;2;peakoffset]

This would return 600.
Groovy Syntax

Groovy lets you return a map that is essentially a copy of the entire SDIDataItem record. Any column containing any data type can then be referenced by specifying (all) for the SDIDataItem column, then using the .columnid syntax as follows:

${Calcium;#;#;(all)}.columnid

where columnid is the SDIDataItem column you want to return.

For example, this returns half the entered value if it is entered with a "less than" operator:

def di = ${Calcium;#;#;(all)};
return di.enteredoperator == '<' ? di.transformvalue / 2 : di.transformvalue

NOTE:   When entered data are prefixed with the < > or = operator (such as <7), the operator is stored in the SDIDataItem.EnteredOperator column.
Parameter Limit Reference

A Data Item's Parameter Limit can be referenced using the following variables:

Variable Parameter Limit Reference
ParamLimit_1

ParamLimit_2

"Value 1" and "Value 2" (respectively) of the Parameter Limit defined by the Parameter List (see Limits and Specifying Parameter Limit Values).
ParamLimit_Status Parameter Limit Type to be evaluated. The evaluation is persisted in the SDIDataItemLimits.StatusFlag column, which indicates whether or not the Parameter Limit has been met (Y, N, or Undefined).

Examples.

The expression below refers to the Calcium;Standard;1 Parameter with a "Value 1" having an "Absurd" Parameter Limit Type:

[Calcium;Standard;1;ParamLimit_1:Absurd]

NOTE:   If the underscore is not included in the expression (such as [Calcium;Standard;1;ParamLimit:Absurd], "Value 1" is used.

The Calculation below sums the number of Replicates that have met the "Absurd" Parameter Limit Type for Calcium;Standard;*:

sum([Calcium;Standard;*;ParamLimit_Status:Absurd])

Attribute Reference

As shown in Column Name Reference above, when a single ColumnId is specified, the Calculation engine determines if an SDIDataItem column of the specified name exists. If so, the column value is used. If not, it looks for a Data Item Attribute having the specified name.

Multiple instances of a Data Item Attribute can be evaluated only when the Attribute's Data Type is "Numeric", and the expression returns a single Data Item.

Example. This expression can be evaluated ("oxidation" is a Data Item Attribute):

sum([Ag;Standard;1;oxidation])

This returns a single Data Item, so the expression can be evaluated.

Multiple instances of a Data Item Attribute cannot be evaluated if the expression returns multiple Data Items.

Example. This expression could be a problem:

sum([Ag;Standard;*;oxidation])

This expression specifies all Replicates of Ag;Standard. If multiple Replicates are found with multiple instances of a Data Item Attribute, an error is returned (and displayed in the Calculation Report).

Referencing Data Sets by an SDIData Column

 
Filtering

Calculations can reference a Data Set with respect to any single column in the SDIData table, such as the SourceWorkitemId or InstrumentId columns. In a Calculation, you can filter by these (or any) SDIData column.

To provide such filtering using the form [PL;PLV;Var;DS|P;PT;R;DI], specify the SDIData column for DS. Note that you can specify only one SDIData column.

Example 1. Assume these relationships in SDIData:

SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Source
WorkitemId
Source
Workitem
Instance
Sample S-001 Metals 1 1 1 OxyTest 1
Sample S-001 Metals 1 1 2 ControlTest 1

This expression calculates the sum of all of the "Metals" Parameters in the ControlTest Workitem:

sum([Metals;*;*;workitem=ControlTest|*]

Example 2. Assume these relationships in SDIData:

SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Source
WorkitemId
Source
Workitem
Instance
Sample S-001 Metals 1 1 1 OxyTest 1
Sample S-001 Metals 1 1 2 ControlTest 1
Sample S-001 Weight 1 1 1 OxyTest 1
Sample S-001 Weight 1 1 2 ControlTest 1

A calculation in the "Metals" Parameter List that requires the "Weight" from the same Workitem, such that the OxyTest Metals uses the OxyTest Weight, and the ControlTest Metals uses the ControlTest Weight, would be written as:

. . . + [Weight;*;*;sourceworkitemid=#|weight] + . . .

Special Handling for Workitems

Sometimes both the SourceWorkitemId column and the SourceWorkitemInstance column are required in Data Set filtering. To handle this scenario, a special syntax is provided that automatically matches on the current SourceWorkitemInstance in addition to the specified SourceWorkitemId:

[. . . ;workitem=xxx| . . .]

where xxx is either a specific WorkitemId or the # wildcard:

workitem=<workitemid>

where <workitemid> is the identifier of the Workitem

This matches on SourceWorkitemId=<workitemid> and the current SourceWorkitemInstance.

Example:

Al;Std;1=[Metals;*;*;workitem=MyWorkitem|Al;Std;1]

You can use this to do calculations on Data Sets within the same Workitem Instance, as the system adds an implicit "sourceworkiteminstance=#" to this.

workitem=#

This matches on both the current SourceWorkitemId and the current SourceWorkitemInstance.

Example:

Al;Std;1=[Metals;*;*;workitem=#|Al;Std;1]

NOTE:   Actions have these effects on SDIData.SourceWorkitemId and SDIData.SourceWorkitemInstance:
AddSDIWorkitem and ApplySDIWorkitem populate the columns.
CopyDataSet preserves the column values.
AddSDI clears the column values when copying an SDI.

Example 3. Assume these relationships in SDIData:

SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Source
WorkitemId
Source
Workitem
Instance
Sample S-001 Metals 1 1 1 OxyTest 1
Sample S-001 Metals 1 1 2 ControlTest 1

In this example, the Calculation for Al in the OxyTest Workitem uses the value of Al for Data Set 2 in the ControlTest Workitem.

OxyTest;1   ControlTest;1

Metals;1;1;1

 

Metals;1;1;2

Al;Std;1=[Metals;1;1;dataset=2|Al;Std;1]

Al;Std;1

NOTE:   The dataset column is a Parameter List key. This means that you can specify Metals;1;1;2 instead of Metals;1;1;dataset=2.

Example 4. Assume these relationships in SDIData:

SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Source
WorkitemId
Source
Workitem
Instance
Instrument
Id
Sample S-001 Metals 1 1 1 OxyTest 1 Calor-A
Sample S-001 Metals 1 1 3 ControlTest 1 Calor-A

In this example, the Calculation for Al in the OxyTest Workitem uses the value of Al in the ControlTest Workitem by specifying a matching InstrumentId. Here, the hash (#) wildcard has the effect of using the same InstrumentId as that being calculated.

OxyTest;1   ControlTest;1

Metals;1;1;1

 

Metals;1;1;3

Al;Std;1=[Metals;1;1;instrumentid=#|Al;Std;1]

Al;Std;1

Example 5. Assume these relationships in SDIData:

SDIData
SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Instrument
Id
Sample S-001 Metals 1 1 1 Calor-A
Sample S-001 Metals 1 1 2 Calor-B

In this case, you could reference the Data Set by Instrument Id, e.g.,

Metals;1;1;1

 

Metals;1;1;2

Al;Std;1=[Metals;1;1;instrumentid=Calor-A|Al;Std;1]

Al;Std;1

Column Name Reference

Calculations can also reference any single column in the SDIData table. Using the form [PL;PLV;Var;DS|DSCol], specify the SDIData column for DSCol. Note that you can specify only one SDIData column.

Example. Assume these relationships in SDIData:

SDIData
SDCId KeyId1 Param
List
ParamList
VersionId
Variant
Id
Dataset Instrument
Id
Sample S-001 Metals 1 1 1 Calor-A
Sample S-001 Metals 1 1 2 Calor-B

In this case, you could reference an InstrumentId column using either of these expressions:

[Metals;1;1;1|instrumentid]

This would return Calor-A.

[Metals;1;1;2|instrumentid]

This would return Calor-B.
Multiple Column Expressions with Logical AND

Multiple SDIData columns can be used in an expression with a logical AND operator. This offers extended filtering capability.

Example. The expression below filters all of the Data Sets with activeflag=Y and modifiableflag=N and s_cancellableflag=N.

sum([Metals;1;1;activeflag=Y && modifiableflag=N && s_cancellableflag=N|Ag;*;*])

Attribute Reference

As shown in Column Name Reference above, when a single ColumnId is specified after the pipe (|), the Calculation engine determines if an SDIData column of the specified name exists. If so, the column value is used. If not, it looks for a Data Set Attribute having the specified name.

Multiple instances of a Data Set Attribute can be evaluated only when the Attribute's Data Type is "Numeric", and the expression returns a single Data Set.

Example. This expression can be evaluated ("oxidation" is a Data Set Attribute):

sum([Metals;#;#;1|oxidation])

This returns a single Data Set, so the expression can be evaluated.

Multiple instances of a Data Set Attribute cannot be evaluated if the expression refers to multiple Data Sets, and one of the Data Sets has multiple instances of the specified Attribute.

Example. This expression could spell trouble:

sum([Metals;#;#;*|oxidation])

This expression specifies all Data Sets of Metals;#;#. If one of those Data Sets has multiple instances of the Attribute "oxidation", an error is returned (and displayed in the Calculation Report).

The Calculation is executed when a Data Item has been modified. For example, sum([Metals;#;#;*|oxidation])+ [Ag;Standard;max] executes when data are entered in the "max" Replicate of Ag;Standard in the current Data Set. However, the RedoCalculation Action executes calculations for all Data Items.

NOTE:   Calculations are not updated when you modify a Data Set Attribute during Data Entry. You must use the RedoCalculation Action to re-evaluate the expression.
Attributes Not Defined for a Data Set

If you specify a Data Set Attribute and that Attribute is not defined for the Data Set, the Calculation engine searches for a Test Attribute of the same name in the Test (SDIWorkitem) related to Data Set. If found, the Test Attribute is used. In this case, the Calculation Report shows the WorkitemId and WorkitemInstance. 

Referencing an SDI Column

 

Finally, you can reference a single column in the current SDI, such as when evaluating a Calculation on a Data Item in a Data Set for the current SDI. The current SDI is referred to as the "primary". This works for both SDI column values and SDC Attributes.

Column Name Reference

The syntax for specifying a primary SDI column value is:

[primary:columnid]

Consider that one of the the simplest expression is to refer to another Data Item in the same Data Set by simply specifying the ParamId, e.g., [Ag]. It then follows that [Ag] * [primary:samplecolumn] is a valid expression.

Attribute Reference

The syntax for specifying a primary SDI Attribute value is:

[primary:attributeid]

The Calculation engine determines if an SDI column of the specified name exists. If so, the column value is used. If not, it looks for an SDC Attribute (on the current SDI) with that name.

The Calculation is executed when a Data Item has been modified. For example, [Ag]+[primary:oxidation] executes when data are entered for the Data Item with ParamId of Ag in the current Data Set. However, the RedoCalculation Action executes calculations whether or not a Data Item has been modified.

NOTE:   Calculations are not updated when you modify a primary or dataset column value. You must use the RedoCalculation Action to re-evaluate the expression.

 

Reference Calculations

Top../images/arwup.gif (846 bytes)

In General...

 

As stated earlier, Reference Calculations are an extension of Internal Calculations. Reference Calculations are performed on the current SDI (the one for which you are entering data), but reference Parameters in another SDI. As such, an additional qualifier (which we call the "SDI Reference") is added to the Parameter List and Parameter qualifiers used to write Internal Calculations:

[SDI|PL;PLV;Var;DS|P;PT;R;DI]

The "SDI Reference" is a reference to another SDI (called the "Reference SDI") that contains the value you want to use in a calculation for the current SDI (called the "Data SDI"). The terms "Reference SDI" and "Data SDI" are used only for documentation purposes and are not defined in LabVantage. They are used only to identify SDIs in the discussions that follow.

The scenarios below apply to Reference Calculations. Note that the "SDI Reference" qualifier can have several variations for some scenarios, as shown in the examples that follow.

Scenario Syntax Variations for SDI Reference
Explicit Reference to a Single SDI
sdi:keyid1
sdi:sdcid;keyid1
sdi:sdcid;keyid1;keyid2
sdi:sdcid;keyid1;2;3

Foreign Key Reference to a Single SDI

link:columnid
link:linkid
Reverse Foreign Key Link link:sdcid;columnid
SDI Relation sdirelation:relationtype
SDI Data Relation
sdidatarelation:relationtype
relationtype
Array See Array Calculations.
Sample Parent/Child Relation See Sample Parent/Child Relation.
QC Samples (AQC) See Using Calculations with QC Samples (AQC).

The examples that follow demonstrate fundamental expressions for Reference Calculations. If you require assistance in building expressions using multiple variations on these syntaxes, try using the Expression Editor's Cross SDI Helper.

Explicit Reference to a Single SDI

 

Starting Conditions:

A "Product-X" SDI has a "Polymers" Parameter List with a "Factor" Parameter equal to "10.4".

A "Sample-001" SDI has a "Metals" Parameter List with an "Ni" Parameter. When a user enters data for Ni, a calculation must multiply it by the value of the "Factor".

This is a "forward reference"... you must go "to" another SDI to get the required value:

"Data SDI"

User is entering data for this SDI.

"Reference SDI"

Calculation references this SDI.

Sample-001

Metals

Al = 2

Ni = Al * Factor

  Product-X

Polymers

Factor = 10.4

Calculation for Ni:

Ni = [Al]*[sdi:Product;Product-X|Polymers|Factor]
  = (2) * (10.4)
  = 20.8

Note the SDI Reference qualifier is SDI:Product-X. This defines the Reference SDI... in other words, this is where the calculation goes to get the Factor.

Now suppose that someone changed the Factor, and you want to recalculate Ni... in other words, you want to do a "reverse reference". In this case, you must programmatically call the RedoCalculations Action (for example, by using the postData Entry SDC Rule). Pass in sdcid=Sample and keyid1=Sample-001:

"Data SDI"

User is entering data for this SDI.

"Reference SDI"

Calculation references this SDI.

Sample-001

Metals

Al = 2

Ni = Al * Factor

  Product-X

Polymers

Factor = 8.2

Value of Ni recalculated:

Ni = [Al]*[sdi:Product-X|Polymers|Factor]
  = (2) * (8.2)
  = 16.4
NOTE:   The RedoCalculations Action synchronizes the Status of Data Sets, Tests, and primary SDIs by calling the UpdateDatasetStatus, SyncSDIWIStatus, and SyncSDIDataSetStatus Actions (respectively).

The Status of the primary SDI is synchronized for the Sample SDC only.

Foreign Key Reference to a Single SDI

 

Starting Conditions:

A "Container-A" SDI has a "Physical" Parameter List with a "WC" Parameter equal to "10.2g". "WC" is the weight of "Container-A".

A "Sample-001" SDI has an "Alcohol" Parameter List. It contains a "WSB" Parameter (the weight of both the Sample and the Container), and a "WS" Parameter (the weight of the Sample without the Container). To determine "WS", you must get "WC" from the Container and subtract it from "WSB". This is another "forward reference".

A foreign key link exists from the ContainerId column in the Sample SDC to the Container SDC.
"Data SDI"

User is entering data for this SDI.

"Reference SDI"

Calculation references this SDI.

Sample-001

Alcohol

WSB = 15g

WS = (WSB) - (WC)

Foreign key link from
ContainerId column
in Sample SDC
to Container SDC
Container-A

Physical

WC = 10.2g

Calculation for WS:

WS = [WSB]-[link:containerid|Physical|WC]
  = (15g) - (10.2g)
  = 4.8g

Note the SDIReference qualifier is link:containerid. This defines where to get the value in the Reference SDI (the ContainerId column)... this is where the calculation goes to get the weight of the Container. To do this type of Calculation, the column you specfy (in this case, ContainerId) must be a foreign key linked column.

Alternatively, if the foreign key link is in the "LinkId" column of the "SDCLink" table, you could specify the "LinkId" value rather than the "ColumnId".

If the ColumnId or LinkId is not found for the primary SDC:

1. The Sample's SDIWorkItem Instance of the current Data Set is checked to determine if it contains the ColumnId.
2. If not found in SDIWorkItem, the Sample's current Data Set (SDIData) is checked.
3. If not found in SDIData, the Data Item (SDIDataItem) is checked.

Now suppose that someone reweighed the Container, and you want to recalculate WS... in other words, you want to do a "reverse reference". In this case, you must programmatically call the RedoCalculations Action (for example, by using the postData Entry SDC Rule). Pass in the values shown below:

"Data SDI"

User is entering data for this SDI.

"Reference SDI"

Calculation references this SDI.

Sample-001

Alcohol

WSB = 15g

WS = (WSB) - (WC)

Foreign key link from
ContainerId column
in Sample SDC
to Container SDC
Container-A

Physical

WC = 10.0g

Calculation for WS:

WS = [WSB]-[link:containerid|Physical|WC]
  = (15g) - (10g)
  = 5g

RedoCalculations properties:

PropertyId Value Meaning
reversesdcid Sample Find the Samples...
reverselinktype reversefk

...with a reverse foreign key link...

keyid1 Container-A

...to this SDI...

sdcid Container  
    ...then, do the recalculation on the Samples.
NOTE:   The RedoCalculations Action synchronizes the Status of Data Sets, Tests, and primary SDIs by calling the UpdateDatasetStatus, SyncSDIWIStatus, and SyncSDIDataSetStatus Actions (respectively).

Reverse Foreign Key Link

 

Starting Conditions:

As with the previous example, a foreign key link must exist from a ContainerId column in the Sample SDC to the Container SDC.

A "Container-A" SDI has a "Physical" Parameter List with a "WC" Parameter equal to "10g". "WC" is the weight of "Container-A".

A "Sample-001" SDI has an "Alcohol" Parameter List. It contains a "WS" Parameter (the weight of the Sample without the Container).

A "Sample-002" SDI has a "Water" Parameter List. It also contains a "WS" Parameter (the weight of the Sample without the Container).
A foreign key link must exist from the ContainerId column in the Sample SDC to the Container SDC.

Both Samples are poured into the Container.

To determine the total weight of both Samples, plus the weight of the Container, use the link:Sample SDIReference. This syntax indicates a reverse reference back to both Samples. Then use the sum function as shown:

"Data SDI"

User is entering data for this SDI.

"Reference SDI"

Calculation references this SDI.

Sample-001

Alcohol

WS = ?

Foreign key link from
ContainerId column
in Sample SDC
to Container SDC
Container-A

Physical

WC = 10g

Calculation for WS:

WS = [WC]+sum[link:Sample|containerid|Water|WS]
  = (10g) + (20g) + (15g)
  = 45g

This calculation says "Find all Samples for which you are entering data that contain a ContainerId column that is linked by foreign key to the Samples".
This returns both values, evaluating the expression for each.

As in the previous example, the column you specfy must be a foreign key linked column, and you can also specify a "LinkId".

As another example, if two child Samples are drawn from a parent Sample, calculate the total weight of the parent. This relationship (child-to-parent) is made by a foreign key link from the ParentSampleId column of the Sample SDC to the Sample SDC itself. Although this is a foreign key link within a single SDI, it is nevertheless
treated in the same manner as the previous example:

Calculation for W (weight of the parent only):

WC = Weight of each child Sample
WT = Weight of parent and children
W = Weight of parent only
  = [WT] - sum of all children
  = [WT] - sum[link:Sample|Water|WC]
 

"Sample" indicates a reverse foreign key link back to the Sample SDC.

SDI Relation

 

Rather than use foreign-key links, you could set up the "SDIRelation" table to make a many-to-many relationship.

Sample table   Container table
WB = Weight of Sample and Container
  = 15
WS = Weight of Sample only
  = [WB] - [sdirelation:holder|WC]
 
WC = Weight of Container
  = 10

 

Note that "holder" is the value of the "RelationType" column in the SDIRelation table.

This calculation says "When entering data for Samples, find Samples that have a relationship (in the SDIRelation table) to Containers of RelationType = Holder".

To find the relation from the Reference SDI (Container) back to the Data SDI (Sample), programmatically call the RedoCalculations Action (for example, by using the postData Entry SDC Rule).

RedoCalculations properties:

PropertyId Value Meaning
reversesdcid Sample Find the Samples...
reverselinktype sdirelation

...with a relation to...

keyid1 Container-A

...this SDI...

sdcid Container  
    ...then, do the recalculation on the Samples.
NOTE:   The RedoCalculations Action synchronizes the Status of Data Sets, Tests, and primary SDIs by calling the UpdateDatasetStatus, SyncSDIWIStatus, and SyncSDIDataSetStatus Actions (respectively).

Note that multiple Relation Types can also be specified as shown in the example below:

[Absorbance]+sum([sdirelation:Reagent;PriorTimepoint|BacterialTest;1;1;1|EndotoxinLevel])

Multiple SDIRelation values can be used for both sdirelation and reversesdirelation as shown in the examples below:

[sdirelation:Reagent;PriorTimepoint|Alkali Metals;1;1;1|Astatine]

[reversesdirelation:Reagent;PriorTimepoint|Alkali Metals;1;1;1|Astatine]

SDI Data Relation

 

If you want to do Calculations on different Data Sets associated with the same SDI, you could use the SDIDataRelation table to setup the relationship. This is very similar to using the SDIRelation table, except this is a many-to-many link from a Data Set in one SDI to another SDI.

Example: If you are testing a Sample using a Consumable, you can use the SDIRelation table because there is only one Consumable involved. However, if you need to retest, you must use another bottle of Consumable. Now, two Consumable SDIs are related to the Sample... and the Sample could possibly be linked to both. To help deal with this, the SDIDataRelation table lets you associate each Consumable with a different Data Set for the same SDI. In the diagram below, if DS1 and DS2 are different tests, each Data Set can point to a different Consumable (referred to as "Reagent" in the diagram).

Calculation for S-001:

CD1 = Concentration measured for Data Set 1
  = 15
  = [Volume]*[sdidatarelation:Salient|ParamList|C]

where ParamList is the Data Set information (such as Fluid;1;1;1)

Note that "Reagent" (Consumable) points to the "ToSDCId" column of the SDIDataRelation table, and "Salient" points to the "RelationType" column.

This expression finds Samples that have a relationship (in the SDIDataRelation table) to Consumables of RelationType = 'Salient'".

For an SDI Data Relation, you can omit the "sdidatarelation" operator and the qualifiers for the Data SDI. In the example above, you could begin the expression with the RelationType column, e.g.,

[Salient|ParamList|C]

If the ParamListId, ParamListVersionId, VariantId, and Data Set will be same as that of the target Data Set, you can omit the ParamList (Data Set information), e.g.,

[Salient||C]

In this case, if the Sample's Data Set is Fluid;1;1;1 the target SDI is determined based on ToSDCId, ToKeyId1 and Salient Relation Type from the SDIDataRelation table for the current Data Set. The target Data Item C also has the same Data Set (Fluid;1;1;1) as the source.

If the RelationType is not found in the SDIDataRelation table for the current Data Set:

1. The SDIWorkitemRelation table is checked to determine if an SDI Workitem Relation exists with the same RelationType for the current Workitem Instance.
2. If so, the Data Items of the target SDI defined in the SDIWorkitemRelation table are used.

Note that multiple Relation Types can also be specified. In the case of SDIDataRelation, this means multiple Consumable Types can be specified. For example:

[GC;H2SO4;NaOH|Alkali Metals;1;1;1|Astatine]

Array Calculations

 

If using Array Management, you can perform Calculations using data from Array Items. See Master Data Setup → Array Methods → Adding a New Array Method → Parameters → Calculation Rule.

Sample Parent/Child Relation

 

Calculations can be performed between Parent and Child Samples as follows:

Relation Type Performs Calculation on: Example Syntax
Parent Parent Sample of the current Sample. [Sample:Parent|Metals;#;#;#|Au;*;*]
Child Child Samples of the current Sample. [Sample:Child|Metals;#;#;#|Au;*;*]
Ancestor Parent Sample of the current Sample, and all Ancestor Samples of the current Sample. [Sample:Ancestor|Metals;#;#;#|Au;*;*]
Descendant Child Samples of the current Sample, and all Descendant Samples of the current Sample. [Sample:Descendant|Metals;#;#;#|Au;*;*]

 

Using Calculations with QC Samples (AQC)

Top../images/arwup.gif (846 bytes)

When dealing with QC Samples (AQC module), the following syntax can be used to perform Calculations on QC Samples in a QC Batch:

Syntax Example Provides access to . . .
[AQC:Linked|#;BlankCorrected;*] Linked QC Sample.
[AQC:QCParam|#;Concentration] Parameter relevant to the QC Batch Sample Type.
[AQC:Blank|*;*;*;*|#;Standard;*] Prior blank.

To perform inter-Sample Calculations on QC Samples in a QC Batch, the following syntax can be used:

AQC:<qcsampletype>;<mode>;<level>

where

<qcsampletype> is the value in the s_sample.qcsampletype column. This is required to locate the QC Sample.
<mode> is one of the following values:
mode Provides access to:
Previous The prior QC Sample. This is similar to the AQC:Blank syntax (third example above). If mode is not specified, the default is to match the Previous.
NextThe next QC Sample just after this position in the QC Batch.
BracketBoth the prior and next QC Samples in the QC Batch.
LeadingAll prior QC Samples before this position in the QC Batch.
TrailingAll following QC Samples after this position in the QC Batch.
AllAll QC Samples in the entire QC Batch.
FirstThe first QC Sample in the QC Batch.
LastThe last QC Sample in the QC Batch.
<level> is the level of the <qcsampletype> (standard). The value of <level> is persisted in the s_qcbatchsampletype record of each of qcsampletype. To filter on <level>, you must join s_sample to s_qcbatchItem to s_qcbatchsampletype. If <level> is not specified, the default is to match all levels.

For example, AQC:Blank:Previous;High selects the QCBatch Sample based on its position in the QCBatch relative to the current Sample.

 

Groovy Examples

Top ../images/arwup.gif (846 bytes)

Groovy Examples: Numeric

 
If-Then-Else Ternary Operator
Expression for Parameter P1: ${Calcium} > 10 ? 5 : 6
    TernaryOp;1;1
Sample DS Calcium;Std;1 P1;Std;1
S-001 1 20 5
    TernaryOp;1;1
Sample DS Calcium;Std;1 P1;Std;1
S-001 1 2 6
List Index
Expression for Parameter P1: def x=5;

if ( ${Calcium;Standard;*}[0] > 10 ) return x else return 6

    ListIndex;1;1
Sample DS Calcium;Std;1 Calcium;Std;2 Calcium;Std;3 P1;Std;1
S-001 1 5 10 20 6
List Size
Expression for Parameter P1: ${Calcium;Standard;*}.size()
    ListSize;1;1
Sample DS Calcium;Std;1 Calcium;Std;2 Calcium;Std;3 P1;Std;1
S-001 1 5 10 20 3

Also see Java Objects Passed Into Groovy Calculation Expressions.

Groovy Examples: Other Data Types

 

These are examples of passing other data types into a calculation (as described in Passing Other Data Types into a Calculation).

Strings
Concatenate
Expression for Parameter P1: ${Calcium} + ${Sodium}
    Concatenate;1;1
Sample DS Calcium;Std;1 Sodium;Std;1 P1;Std;1
S-001 1 Hello Goodbye HelloGoodbye
Conditional Count
Expression for Parameter P1: if ( ${Calcium} == 'Hello' ) return ${Sodium} * 3 else return ${Sodium} * 5
    ConditionalCount;1;1
Sample DS Calcium;Std;1 Sodium;Std;1 P1;Std;1
S-001 1 Hello 3 9

Enter a different string for Calcium:

    ConditionalCount;1;1
Sample DS Calcium;Std;1 Sodium;Std;1 P1;Std;1
S-001 1 Goodbye 3 15
Dates
Largest Integer
Expression for Parameter P1: Math.floor((${Sodium}.getTime().getTime() - ${Calcium}.getTime().getTime())/(1000*60*60*24))
    LargestInteger;1;1
Sample DS Calcium;Std;1 Sodium;Std;1 P1;Std;1
S-001 1 3/2/99 4/3/99 31
Combination of Numeric, String, and Date
Calculate and Return Date
Expression for Parameter TextMessage: "Your test will be ready in " + ${NumberOfDays;Standard} + " days"
Expression for Parameter CompleteDateTime: Calendar c = Calendar.getInstance(); c.add(Calendar.DATE, ${NumberOfDays;Standard}.intValue() ); return java.text.DateFormat.getInstance().format( c.getTime() )
Expression for Parameter CompleteDate: Calendar c = Calendar.getInstance(); c.add(Calendar.DATE, ${NumberOfDays;Standard}.intValue() ); return java.text.DateFormat.getDateInstance().format( c.getTime() )
    CalculateReturnDate;1;1
Sample DS NumberOfDays;Std;1 TextMessage;Std;1 CompleteDateTime;Std;1 CompleteDate;Std;1
S-001 1 5 Your test will be ready in 5 days Apr 5, 2016 9:37:00 Apr 5, 2016

The example above demonstrates a case for using "Calc" Data Types, which prevent editing a calculated field (as defined in the Data detail of the Parameter List). For example, defining the Data Types in the Parameter List as shown below would prevent the calculated fields from being edited:

Parameter Data Type
Text Message Text (Calc)
CompleteDateTime Date (Calc)
CompleteDate Date Only (Calc)

Java Objects Passed Into Groovy Calculation Expressions

 

The Java object passed into a Groovy expression depends on the Data Type of the Parameter, column, or Attribute being requested, as well as the number of Data Items found by the Calculation engine:

Data Type of Parameter,
Column, or Attribute
Java Object Passed Into Groovy Expression
when only 1 Data Item is found
Java Object Passed Into Groovy Expression
when more than 1 Data Items are found
Number BigDecimal BigDecimal[]
String String String[]
Date Calendar Calendar[]
(all) columns HashMap HashMap[]

For example, if a single Data Item is passed into ${Ag;Standard;*}.size(), that single Data Item is passed in as a BigDecimal object (not an "array of one"). An array of objects is passed only if multiple Data Items are found. If a Groovy expression must handle both single and multiple Data Items, try something like this:

def p = ${Ag;Standard;*}

def x= p instanceof BigDecimal ? 1 : p.size();

where instanceof is a Groovy command that returns the type of data object.

 

Expression Library and Expression Editor

Top ../images/arwup.gif (846 bytes)

To assist in generating expressions used in Calculations, LabVantage offers the Expression Library and Expression Editor.