arrow-left

All pages
gitbookPowered by GitBook
1 of 14

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Working with Containers

The container entity makes the input, output, or submittedSample container available to the scripting engine.

  • The container can be queried for its name, for example:

    input.::container::.::name::
  • Container name, UDFs / fields, and entity information can be read or written, for example:

    output.::container::.::example udf1:: = input.::container::.::example udf1::

Example basic expressions:

-exp 'output.container.::containerUDF:: = ::This is a string::'
-exp 'input.::container::.::containerUDF:: = ::This is a string::'
-exp 'submittedSample.container.::containerUDF:: = ::This is a string::'
circle-info

The word 'container' may be optionally surrounded by "::"

Data Collection Entities

When working with the Lab Logic Toolkit evaluateDynamicExpression script, custom field values can originate from the following data collection entities (these will differ, depending on the step from which the script is being run):

  • input (analyte/derived sample)

  • output (analyte/derived sample or per-input result file, measurement, or file placeholder)¹

  • step

  • container

  • submittedSample / submittedSamples²

¹ Shared and per-reagent-label result files / measurements (e.g., those produced by a demultiplexing step) are not supported.

² Use 'submittedSamples' with pooled derived samples, and 'submittedSample' for single-source derived samples.

Working with Lab Logic Toolkit

hashtag
Script Parameters and Usage

The following table defines the parameters used by the evaluateDynamicExpression script.

Parameter

Description

-u {username}

(Required) LIMS login username

hashtag
Automation Command Line

hashtag
Using Special Characters—Rules and Constraints

hashtag
Joining Multiple Evaluations

Use the following special syntax to join multiple evaluations within an expression:

  • AND = &&

  • OR = ||

  • NOT = !

Boolean expressions should evaluate to true or false.

hashtag
Troubleshooting

For debugging errors, run through the following steps to determine the cause.

  1. Check custom field format (eg, step.::UDF Name::).

  2. Make sure that the custom fields have been created for the correct entity type.

  3. Check the mapping of the field type (see section) — if doing Math they need to be numeric.

Check that the step has a log file placeholder configured.
  • The 'unexpanded placeholders in string' error often refers to the last -log parameter — where the step has not been configured to produce one.

  • If no log file is created, find additional error logging from the command line of the instance. This often shows the location of a syntax error. Find the log file at /opt/gls/clarity/automation_worker/node/logs/automatedinformatics.log.

  • Set -t parameter to false if an automatic trigger is used.

  • -p {password}

    (Required) LIMS login password

    -i {URI}

    (Required) LIMS step URI Provides context to resolve all token values.

    -t {true/false}

    (Optional) Test mode The script may be executed automatically on step transition, or manually — by selecting the button on the Record Details screen.

    • For automatic script execution—set test mode to false.

    • For manual script execution—set test mode to true.

    Defaults to false if not specified.

    -h {true/false}

    (Optional) Halt on any error. By default, if the expression fails to evaluate, or evaluates to a non-numeric/non-sensical value, the script logs the problem and continue. A warning message advises the user to review the generated log file. Supplying the optional -h parameter with a value of true will cause the script to fail, preventing a step transition from proceeding, if any nonfatal errors arise.

    -exp {expression}

    (Required) The expression to be evaluated. The expression must be enclosed in single quotes, eg, -exp 'expression'. See Using section.

    -log {logFileLIMSID} -logFileName {logFileLIMSID}

    (Required) The LIMS ID of the log file placeholder

    -excludeControls {true/false} (Cannot be used withonlyControls; these two parameters are mutually exclusive)

    (Optional) Control sample handling Set this parameter to true to make sure that:

    • The nextStep (if used) is set to REMOVE for control samples.

    • Controls are excluded from any calculations in the expression.

    See and .

    -onlyControls {true/false} -onlyControlSamples {true/false} (Cannot be used withexcludeControls; these two parameters are mutually exclusive)

    (Optional) Control sample handling Set this parameter to true to make sure that calculations are performed on control samples only.

    -s {true/false} -stopwatch {true/false}

    (Optional) Tool logging Set this parameter to true to record the time needed to run the tool as an entry in the log file.

    Special Character

    Symbol

    Rules and Constraints

    Single quote

    '

    As the ‘exp’ argument supplied to the script must be enclosed in single quotes, the single quote character cannot be used anywhere in the expression—including as part of any custom field that contains the single quote in its name.

    Double quote

    "

    The entire command line must be enclosed in double quotes. Therefore, the double quote character cannot be used anywhere in the expression — including as part of any custom field that contains the double quote in its name.

    Double colon

    ::

    This two character string is used to delimit strings and custom field names. This character may not appear inside a custom field or string.

    Example

    Description

    A; B

    Run A and then B, regardless of success of A.

    A && B

    Run B if A succeeded.

    A || B

    Run B if A failed.

    if (!A) {B}

    If A condition is not met, run B.

    bash -l -c "/opt/gls/clarity/bin/java -jar /opt/gls/clarity/extensions/ngs-common/v5/EPP/ngs-extensions.jar \
    -i {stepURI:v2:http} \
    -u {username} \
    -p {password} \
    script:evaluateDynamicExpression \
    -t <false/true> \
    -h <false/true> \
    -exp 'INSERT EXPRESSION HERE' \
    -log {logFileLIMSID}"
    Special Characters - Rules and Constraints
    Setting Next Actions
    Handling Control Samples

    Lab Logic Toolkit FAQ

    hashtag
    What Java/Groovy methods can I use in a Lab Logic Toolkit (LLTK) Expression?

    You can use all methods included in the Java and Groovy base packages.

    Commonly used Java classes are:

    • String: http://docs.oracle.com/javase/8/docs/api/java/lang/String.html

    • Math: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html

    For information on Groovy closures, see .

    hashtag
    How do I handle attempts to access custom fields that do not exist or do not have a value set?

    Use the hasValue function to check for nonexistent fields and fields that do not have a value set - including toggle switches in LIMS v5 and later.

    See .

    hashtag
    How do I prevent a user from moving to the next screen if certain criteria are not met?

    Use the hasValue function together with the fail() method to check for step UDF / custom field values when the Record Details screen is exited, and prevent the user from advancing to the next screen if they have not entered values for these fields.

    See .

    hashtag
    How do I control the number of decimal places for a custom field?

    Use the following expression:

    1. Use Groovy syntax to format the following string:

    2. Replace step.::counter:: with the field you want to apply the formatting to.

    3. Replace %.0f with the number of decimal places needed. For example, for three decimal places, use %.3f.

    Example:

    hashtag
    How do I round to the closest integer below a value using Math.floor?

    Use the following expression:

    hashtag
    How do I use LLTK with required custom fields?

    Custom fields are set as a bulk group in the API. The API checks all required fields.

    When LLTK updates a field, all required fields must be set or an error will occur.

    Workaround:

    1. Set the required fields with a value such "Please fill in this value".

    2. Use another LLTK expression triggered on step completion to check whether this value has been updated.

      • If the field value has been updated, allow the step to proceed.

    Mapping Field Types

    The following tables summarize the mapping of UDF/custom field types.

    Field Type

    Groovy Data Type

    Text

    String

    Multiline Text

    String

    Text Dropdown

    String

    Hyperlink

    String

    Hyperlink Dropdown

    hashtag
    Working with Toggle Switches

    The LIMS and API treat the toggle switch field type as boolean when its value is set to true or false. However, it is possible to configure a toggle switch to not have to set a boolean true / false value. In this case, the value of the field is None Set and the field is treated as a 'nonexistent' field. To make sure that a toggle switch value has been set, you can use the hasValue function. For details, see .

    Comparing Stop/Start Dates and Times with LLTK

    Lab scientists need to record both a start and stop date/time for an incubation. As a second evaluation of how many hours the incubation lasted, the scientists want BaseSpace Clarity LIMS to calculate the elapsed time.

    The Lab Logic Toolkit evaluateDynamicExpression script can compare date/time entries and calculate elapsed hours. As Date fields in the LIMS do not display the required time component for this calculation, Text fields are needed.

    The bash command uses a 'Date' function to convert the Text date/time entries into dates, and also uses a 'getTime' method to convert those dates into milliseconds since 1 January 1970 00:00:00 UTC. The difference between the two converted entries is then changed from milliseconds to hours.

    hashtag
    Example

    1. Create a step level Text field for the Start Date/Time.

      • In this example, the field is named Incubation Start yyyy-mm-dd hh24:mi. The format is included in the name to assist the scientist entering the date/time.

    2. Create a step level Text field for the Stop Date/Time.

    If you want to use a button to populate a Text field with the current date/time, then use:

    Failing a Script

    Use the fail() method to halt the script and display an error message. If the script is used on a step transition, this method also prevents the step from proceeding to the next screen.

    Example expression:

    Note that this example also uses the hasValue function (see ).

    Lab Logic Toolkit

    Lab Logic Toolkit (LLTK) provides the evaluateDynamicExpression script, which allows for the evaluation of simple dynamic expressions — Excel-like formulas that can be used to perform calculations. The expressions may include full Java or Groovy syntax.

    Each Clarity LIMS step comprises a series of mappings that relate a single input to a single output. The script applies and evaluates the expression for each input-output-mapping in the step.

    For example, the following expression sets the next step for each output sample, depending on whether the input sample has passed or failed QC:

    Often, the formulas are used to set the values of one or more custom fields. However, LLTK can do a great deal more than simply manipulate field values.

    String

    Toggle Switch

    Boolean

    Date

    Date

    Numeric

    double, float, log, int, BigDecimal, BigInteger

    Numeric Dropdown

    double, float, log, int, BigDecimal, BigInteger

    Handling Non-Existent UDFs/Custom Fields
    If the field value has not been updated, log an error and halt progress of the step.
    Groovy Closuresarrow-up-right
    Non-UDF Custom Field Properties
    Failing a Script
  • In this example, the field is named Incubation Stop yyyy-mm-dd hh24:mi.

  • Create a step level Numeric field for the Incubation Hours. Set your preferred decimal place limit.

  • Create an automation and enter the following command line (if you have used different field names, edit the example command line to match):

  • Set the automation to be triggered by a button on the step. This allows the scientist to enter/edit the Start and Stop Date/Time before the elapsed hours are calculated.

    ℹ Adjustment for the Start/Stop events taking place over the 'daylight savings change events' is not included in this example.

  • -exp 'if (!step.hasValue( ::Batch ID:: )) { fail(::Batch ID step UDF is required::) }'
    Handling Non-Existent UDFs/Custom Fields
    -exp 'if (input.QC == true) { nextStep = ::ADVANCE:: } else { nextStep = ::ESCALATE:: }'
    String.format(::%.0f::, step.::counter::)
    String.format(::%.2f::, Concentration::).
    -exp 'output.::NTP Uses:: = Math.floor((input.::NTP Volume (uL):: - step.::NTP Dead Volume (uL)::)/ step.::NTP Volume Per Lane (uL)::)'
    bash -l -c "/opt/gls/clarity/bin/java -jar /opt/gls/clarity/extensions/ngs-common/v5/EPP/ngs-extensions.jar -i {stepURI:v2} -u {username} -p {password} script:evaluateDynamicExpression 
    -exp 'step.::Incubation Hours:: = (Date.parse(::yyyy-mm-dd H:m::, step.::Incubation Stop yyyy-mm-dd hh24:mi::).getTime() - Date.parse(::yyyy-mm-dd H:m::, step.::Incubation Start yyyy-mm-dd hh24:mi::).getTime()) / (1000*60*60)' -log {compoundOutputFileLuid0}"
    bash -l -c "/opt/gls/clarity/bin/java -jar /opt/gls/clarity/extensions/ngs-common/v5/EPP/ngs-extensions.jar -i {stepURI:v2} -u {username} -p {password} script:evaluateDynamicExpression -exp 'step.::Formulation:: = new Date().getDateTimeString()' -log {compoundOutputFileLuid0}"

    Working with Submitted Samples

    For a pooled derived sample consisting of several submitted samples, Lab Logic Toolkit exposes a submittedSamples property that is a collection of the submitted samples represented in the well.

    • submittedSamples returns a list of submitted samples.

    • If it is not a pooled sample, it will return a list of 1.

    submittedSample returns an error if sample is pooled.

    Use this collection to read and/or update all related submitted samples.

    For example:

    • To set the sample level UDF/custom field for each of the related submitted samples:

      -exp 'submittedSamples.each { sample -> sample.::My Sample-Level UDF:: = 123 }'
    • To sum the Volume UDF/custom field on all the related submitted samples into a single value written to the input analyte / derived sample:

      -exp 'input.::Total Origin Sample Volume:: = submittedSamples.sum { sample -> sample.::Volume:: }'

    For information on Groovy syntax and closures, see Groovy Closuresarrow-up-right.

    Non-UDF/Custom Field Properties

    The following table summarizes the non-UDF/custom field properties available for each entity type. Column headers are the types available. The bold row entries are the properties available.

    Property

    Input Sample

    Output Sample

    Per Input Result File/Measurement

    Submitted Sample

    Container

    Step

    name

    yes

    yes

    yes

    circle-info

    LIMSID is supported via Groovy node access. See section.

    hashtag
    name

    The name read-only property makes the name of the entity available to the scripting engine.

    Example basic expression:

    hashtag
    workflowName

    The workflowName read-only property makes the workflow name of input samples available to the scripting engine.

    This property contains a string representing the current IN_PROGRESS workflow names. The string is formatted as a comma-delimited list, with a space inserted before each new item.

    Example basic expressions:

    circle-info

    Workflows are not assigned to output samples until the step that creates those samples completes (this will always be the current step). For this reason, the workflow name should always be retrieved from the input entity.

    hashtag
    replicateCount

    The replicateCount read-only property is available for input samples.

    This property contains an integer value representing the number of output replicates (samples or result files / measurements or files / file placeholders) generated from the input sample in the current step.

    Example basic expressions:

    circle-info

    Because the replicateCount property is only available for input samples, its value for output samples will always be zero.

    hashtag
    pooledInputsCount

    The number of input analytes/derived samples that contributed to this analyte / derived sample.

    • For pooled analytes / derived samples, this is > 1.

    • For non-pooled analytes this is 1.

    • Replicated samples that are then pooled are still counted separately in pooledInputsCount.

    Example basic expression:

    When working with the pooledInputsCount property, the script looks at the step that created the derived sample or result file / measurement, and doesnot look upstream for a pooling step.

    Example scenario:

    Step 1: Pooling step that creates pooled samples.

    Step 2: Nonpooling step that takes in the pooled samples and creates new derived samples (that are themselves still pools).

    Step 3: Nonpooling step with expression that calls input.pooledInputsCount.

    The expression in step 3 returns '1' because it onlys look at the previous step (step 2)—the step that created the current derived samples.

    hashtag
    limsid

    You can access the limsid field with some knowledge of Groovy and the LLTK. Use the following examples with any supported entity:

    Example basic expressions:

    hashtag
    well

    The well read-only property makes the well location of input, output, or submittedSample available to dynamic expressions. Result file / measurement outputs are supported if they have placement information (eg, on QC steps).

    Example basic expression:

    yes

    yes

    yes

    container

    yes

    yes

    yes

    yes

    no

    no

    workflowName

    yes

    yes

    no

    no

    no

    no

    replicateCount

    yes

    no

    no

    no

    no

    no

    pooledInputsCount

    yes

    yes

    yes

    no

    no

    no

    well

    yes

    yes

    yes

    yes

    no

    no

    limsid
    -exp 'input.::Latest Step:: = step.name'
    -exp 'submittedSample.::Current Workflow:: = input.workflowName'
    -exp 'if(input.workflowName.contains(::TruSeq Nano DNA Sample Prep::)) { submittedSample.::Status:: = ::Prep:: }'
    -exp 'output.::Active Workflow Count:: = input.workflowName.split(::, ::).size()'
    -exp 'input.::Replicate Count UDF:: = input.replicateCount'
    -exp 'step.::Total Replicates:: = step.::Total Replicates:: + input.replicateCount'
    -exp 'output.::Count:: = input.pooledInputsCount'
    input.node.@limsid
    step.node.@limsid
    output.container.node.@limsid
    -exp 'output.::Input well:: = input.well'

    Specifying Custom Fields

    Each custom field is specified by using one of the data collection entity names (see Data Collection Entities), followed by a dot separator, followed by the field name enclosed in :: characters.

    For example:

    UDF/Custom Field Specification

    Description

    input.::Concentration (ng/mol)::

    The value of the field Concentration (ng/mol) from the input sample

    submittedSample.::Batch ID::

    The value of the field Batch ID from the submitted sample

    step.::Priority in Process::

    The value of the field Priority In Process on the current step

    hashtag
    Rules and Constraints

    • The expression is evaluated and the target field value set for each input/output pair in the step.

    • Where there are replicates or pooling this may mean that a particular input or output item is evaluated multiple times.

    • Lab Logic Toolkit can write to read-only fields.

    The evaluateDynamicExpression script evaluates the expression and sets the target field value for each input/output pair in the step.

    • Where there are replicates or pooling this may mean that a particular input or output item will be evaluated multiple times.

    • The output data collection is treated specially. The script performs the following actions:

      • Searches the per-input output sample and the per-input output result file/measurement (if they exist) for any output field names found in the expression.

    hashtag
    Example Expressions

    Example 1

    In this example expression, the sample output DNA Concentration field is assigned the value resulting from the following calculation:

    1. Multiplying the value of the step Ideal Volume by the value of its Ideal Concentration.

    2. Dividing that result by the Volume defined on the sample input.

    Note the following:

    • step.::Ideal Volume:: is the value of a UDF/custom field. The period between step and Ideal Volume signifies that Ideal Volume is associated with the step.

    • The part of the expression to the left of the = sign is always the destination or result of the expression, that is:

    • The part of the expression to the right of the = sign is always the source of the value to be stored in the destination, that is:

    Example 2

    Copy a step or analyte / derived sample field value to a field configured on the step output - for use in downstream steps:

    This expression will be evaluated one time for each output.

    Example 3

    Copy a result file or measurement field value to the output analyte / derived field for use in downstream step:

    Example 4

    Automatically set a text-string field value:

    hashtag
    Handling Non-Existent UDFs/Custom Fields

    In the API, fields that do not exist and fields that do not have a value set are considered the same and are handled in the same way.

    Attempting to access a nonexistent UDF / custom field will usually result in an error. Sometimes this may not be the desired behavior.

    Before attempting to access a field, you can use the hasValue function to check if it exists.

    The hasValue function:

    • May be used on any item.

    • Takes one parameter - the name of the field.

    • Returns true if the field exists and has a non-null value.

    Example Expressions:

    The following expression checks that the Concentration field has a non-null value, and then checks that this value is greater than 1:

    The following expression checks that a toggle switch field has a non-null value - ie, that it is set to true or false, and then checks that the value is set to true:

    Lab Logic Toolkit can write to all hidden fields.

    Returns any values found.

  • In the event of a name collision (ie, the same field name exists on both sample output and result file / measurement output) the sample value is used.

  • In this case, multiplying the value of the protocol step Ideal Volume by the value of its Ideal Concentration, and then dividing the result by the Volume defined on the sample input.
    -exp 'output.::DNA Concentration:: = (step.::Ideal Volume:: * step.::Ideal Concentration::) / input.::Volume::
    -exp 'destination = (step.::Ideal Volume:: * step.::Ideal Concentration::) / input.::Volume::'
    -exp 'destination = source value'
    -exp 'output.::PCR Cycles:: = step.::PCR Cycles::'
    -exp 'output.::Concentration:: = input.::Concentration::'
    -exp 'output.::Conc. Units:: = ::nM::'
    -exp 'input.::QC:: = input.hasValue( ::Concentration:: ) && input.::Concentration:: > 1'
    -exp 'if (step.hasValue(::Toggle UDF::) && step.::Toggle UDF::)'

    Lab Logic Toolkit Script Examples

    BaseSpace Clarity LIMS Lab Logic Toolkit (LLTK) provides the evaluateDynamicExpression script, which allows for the evaluation of simple dynamic expressions.

    This article provides examples that you can modify to suit the needs of your lab.

    For details on script parameters and usage, and additional examples, see the Working with Lab Logic Toolkit article.

    hashtag
    Setting QC flags

    See the article.

    hashtag
    Setting next actions

    See the article.

    hashtag
    Create string from multiple UDFs and add additional characters

    hashtag
    Determine total number of samples

    This example assumes that the step UDF / custom field Total samples has a default numeric value of 0:

    Without a default value, the expression must set the initial value before continuing to sum:

    hashtag
    Calculate concentration from a dilution factor

    hashtag
    Calculate volume of buffer and source sample to dilute

    hashtag
    Calculate the remaining amount of submitted sample left after the step

    hashtag
    Calculate volumes of all components to add to master mix (e.g., PCR reaction)

    hashtag
    Calculate nM from concentration and size

    hashtag
    Determine dilution to populate robot file

    hashtag
    Calculate average concentration

    This example demonstrates the use of step UDFs / custom fields to store temporary values in order to enable calculations between iteration.

    hashtag
    Check container name changed from default value

    This example checks that the container name has been changed from the default value (container LIMSID)

    hashtag
    Calculate yield of sequenced samples using the submittedSamples entity

    This example includes , using both implicit variables (it) and explicit variable names (for example, currentSample).

    hashtag
    Concatenate strings

    hashtag
    Regex example: Validate output container barcode mask

    hashtag
    Regex example: Verify format of flow cell / reagent cartridge barcode

    Check the flow cell/reagent cartridge format (Illumina’s flow cell check) as follows:

    hashtag
    Regex example: Validate a scanned / manually entered container barcode

    hashtag
    Populate a Timestamp (Single-line Text and Text) UDF / custom field

    The following expression results in the format: Wed Apr 03 21:28:38 EDT 2015

    hashtag
    Populate a Timestamp (Date) UDF / custom field

    The following expression results in the format: 2015-04-03

    hashtag
    Add values within a pool

    This example assumes that the analyte / derived sample UDF Pool Volume (uL) has a default numeric value of 0.

    This can also be done without setting a default value for the UDF:

    hashtag
    Convert placement information to a numeric position

    The example below assumes the following:

    • The placement is alphanumeric (e.g., A:1)

    • The offset for the alphabetical row is 0, and the offset for the numeric column is 1

    • The placement order desired is horizontal: A:1 maps to 1, A:2 maps to 2, etc.

    Note the following:

    • The call to split() here will return a list of row:column, so we use [0] and [1] to access these values, respectively.

    • :: : ::.trim() is used to obtain the result ':' - because :: is used as a reserved character, and thus ::::: directly results in '': and errors.

    hashtag
    Set the error status bar message

    See the article.

    hashtag
    Check for special characters

    In some cases, special characters are not permitted in a field in the LIMS. To prevent users from entering special characters, the best practice is to include validation to check that the field contains only letters and/or numbers. Wherever possible, we recommend that you use this 'positive checking' method as it is much less error-prone. However, if this preferred method is not possible, you can use the Lab Logic Toolkit to check for the presence of special characters, and display an error message if one is found.

    The following example use the Groovy matches command to check step output container names for the characters ? ( ) [ ] / \ and quotes or spaces.

    The matches command

    The matches command takes a regular expression (regex) as its input. Call this command on the field you want to check.

    In our example, the matches command is:

    If we isolate the regex, we have:

    Here, we're checking for any text that contains any one of the special characters listed. It's important to note that the way regex is supported in Java (and therefore Groovy) leads to some quirks, noted in the following table.

    Escaping characters Normally, in regex we would need to escape the following characters using a single backslash:

    However, because of how matches works, not all of these characters need to be escaped - for example the '?' character. Characters that do still need to be escaped, need to be escaped with an additional backslash (e.g., \\).

    Checking for quotes Because the command is run via Automated Informatics / Automation Worker, we also need to use a different approach for checking for quotes.

    We cannot use them as we typically would when writing a regex expression (e.g., "), or escape them as we would in a call to matches (e.g., \"). Instead, we need to provide them as their unicode number, shown in our example as \u0022 and \u00.

    hashtag
    Resources

    The placement of interest is the output placement
  • Placement is configured for a specific, known container type, and the dimensions of this container type are also known. This example uses a 96 well container configuration (12 columns are available and this value is used directly in the expression below). This value can be replaced for other container types.

  • \/

    Forward slash

    \

    \\

    Backslash

    (space)

    \s

    Spaces

    Regex testerarrow-up-right
  • Groovy dates and timesarrow-up-right

  • Entry

    Standard regex representation

    Character being checked for

    \u0022 and \u0027

    ' and "

    Single and double quotes

    ?

    \?

    Question mark

    ( and )

    \( and \)

    Brackets

    [ and ]

    \[ and \]

    Square brackets

    Setting QC Flags
    Setting Next Actions
    Groovy Closuresarrow-up-right
    Failing a Script
    Unicode character tablearrow-up-right
    Java Pattern documentationarrow-up-right
    Regex visual toolarrow-up-right

    /

    -exp 'submittedSample.::Run Name:: = step.::Source:: + ::_:: + step.::Numeric ID::'
    -exp '(step.::Total samples:: = step.::Total samples:: + 1)'
    -exp 'if(step.hasValue(::Total samples::)) { step.::Total samples:: = step.::Total samples:: + 1 } 
    else { step.::Total samples:: = 1 }'
    -exp 'output.::Concentration (nM):: = (input.::Concentration:: * step.::Dilution Factor::)'
    -exp 'output.::Diluent Needed:: = step.::Desired Volume:: - output.::Sample Volume::'
    -exp 'submittedSample.::Sample Volume:: = submittedSample.::Sample Volume:: - output.::VolumeUsed::'
    -exp ‘(step.::Component1:: = step.::NumberofSamples:: * 1.5) ; 
    (step.::Component2:: = step.::NumberofSamples:: * 0.5) ; 
    (step.::Component3:: = step.::NumberofSamples:: * 5)’ -log {compoundOutputFileLuid0}"
    -exp 'output.::Concentration (nM):: = (input.::Concentration:: / input.::Average length (bp)::)
    * 1540.832'
    -exp 'output.::Sample Needed (uL):: = step.::Input Amount (ng):: / input.::Library Concentration:: ;
     if ( output.::Sample Needed (uL):: > step.::Final Volume (uL):: ) { output.::Sample Needed (uL):: =
     step.::Final Volume (uL):: } ; if (output.::Sample Needed (uL):: < 1.0 ) 
    { output.::Sample Needed (uL):: == 1.0 } ; output.::Diluent Volume (uL):: = 
    step.::Final Volume (uL):: - output.::Sample Needed (uL):: ; output.::Final Amount (ng):: =
     output.::Sample Needed (uL):: * input.::Library Concentration::'
    -exp 'output.::Concentration::=input.Concentration ;
    if(!step.hasValue(::No. of samples::)) { step.::No. of samples:: = 0 } else { step.::No. of samples:: += 1 }; 
    if(!step.hasValue(::Total Conc.::)) { step.::Total Conc.:: = 0 } else { step.::Total Conc.:: += output.Concentration };
    if(!step.hasValue(::Average Conc.::)) { step.::Average Conc.:: = 0 } 
    else { step.::Average Conc.:: = step.::Total Conc.:: / step.::No. of samples:: };' 
    -exp 'if (output.container.name == output.container.node.@limsid) { fail(::Invalid Barcode. 
    Please verify and try again.::) }'
    submittedSamples.each { it.::Workflow Progress:: = ::Sequencing Finished:: }; 
    if (!input.hasValue(::Lane Failed?::) || !input.::Lane Failed?::) { def acquiredYield = 0; 
    if (input.hasValue(::Yield PF (Gb) R1::)) { acquiredYield += input.::Yield PF (Gb) R1:: }; 
    if (input.hasValue(::Yield PF (Gb) R2::)) { acquiredYield += input.::Yield PF (Gb) R2:: }; 
    acquiredYield = acquiredYield / submittedSamples.size(); submittedSamples.each { currentSample -> 
    def currentSampleAcquiredYield = acquiredYield; 
    if (currentSample.hasValue(::Acquired Yield (Gb)::)) { currentSampleAcquiredYield += 
    currentSample.::Acquired Yield (Gb):: }; currentSample.::Acquired Yield (Gb):: =
    currentSampleAcquiredYield; currentSample.::Missing Yield (Gb):: = 
    currentSample.::Required Yield (Gb):: - currentSampleAcquiredYield }
    submittedSample.::Lab Comments:: = output.::Sample Comment::.toString() + ::; :: 
    + submittedSample.::Lab Comments::.toString()
    -exp 'if ( !output.container.name.matches( ::LP[0-9]{7}-QSTD:: )) 
    {fail ( ::Invalid QSTD Plate Barcode. Please verify and try again.:: ) }'
    -exp 'if(!output.container.name.matches(::^[Hh][0-9A-Za-z]{4}([Bb][Bb]|[Cc][Cc]|[Aa][Ll])[Xx][Xx]$::)) 
    { fail(::Invalid Patterned Flowcell Barcode. Please verify and try again.::) }'
    -exp 'if ( !output.container.name.matches( ::LP[0-9]{7}-QNT:: ) &&
     !output.container.name.matches( ::LP[0-9]{7}-SQNT:: ) ) 
    {fail ( ::Invalid QNT & SQNT Plate Barcodes. Please verify and try again.:: ) }'
    -exp 'step.::Timestamp:: = new Date().toString()'
    -exp 'step.::Timestamp:: = new Date().format(::yyyy-MM-dd::)'
    -exp 'output.::Pool Volume (uL):: = output.::Pool Volume (uL):: + input.::Volume (uL)::'
    -exp 'if(output.hasValue(::Pool Volume (uL)::)) { output.::Pool Volume (uL):: = output.::Pool Volume (uL):: 
    + input.::Volume (uL):: } else { output.::Pool Volume (uL):: = input.::Volume (uL):: }'
    -exp 'output.::Position:: = (((output.well.split(:: : ::.trim())[0].toString().toUpperCase() as char) 
    - (::A:: as char)) * (int) Math.pow(26, 0)*12) + output.well.split(:: : ::.trim())[1].toInteger()'
    -exp 'if (output.container.name.matches(::.*[\u0022\u0027?()\\[\\]/\\\\ ].*::)) 
    { fail(::The following characters are not allowed in the Container Name: ? ( ) [ ] / \ and quotes or spaces.::) }'
    output.container.name.matches(::.*[\u0022\u0027?()\\[\\]/\\\\ ].*::)
    .*[\u0022\u0027?()\\[\\]/\\\\ ].*
    .^$*+?()[{|-]\

    Setting Next Actions

    The nextStep property is similar to the input, output, submittedSample, container, and step entities. However, nextStep can only be used on the left side of a dynamic expression; it cannot be used in the calculation on the right side of the expression.

    The basic syntax is as follows:

    Depending on how the step is configured, a nextStep expression may set the next action for the step inputs or the step outputs. For example, in steps that do not produce output samples — such as QC steps, it is the step inputs that proceed (provided they pass QC) to the next step in the workflow.

    When creating an expression that calls the nextStep property, there is no need to differentiate between step inputs and step outputs. The LIMS is able to determine this from how the API represents the entities that are available to set next actions on.

    Note also that this property is evaluated for each input/output, and can set a different nextStep value for each.

    hashtag
    Supported Values for nextStep

    For samples to advance to the next step via an LLTK expression, the next step must be specified in the Configuration area of the LIMS.

    Configure next steps on the protocol configuration form, in the Next Steps table.

    The possible next step values listed in the following table are intended for non-QC protocols. There is no nextStep entity for a QC protocol. However, samples in a QC step in a QC protocol can move to REMOVE or ESCALATE via LLTK.

    <next step value> can be one of the following:

    • Any Groovy expression that includes the top-level entity UDFs/custom fields on input, output, submittedSample, and evaluates to one of the options described.

    • A valid next step name, for example, ::Sample Pooling:: (remember that text / string values must be inside double colon delimiters).

    • One of the following 'special values' described in the following table.

    The following conditions must be met:

    • If <next step value> is not a valid next step, or is not one of the special values described in the table above, an error is raised and the script will fail by returning a nonzero value.

    • The <next step value> must be in 'choose next steps' or 'record details' transition when the script is executed. If not, the script will fail and will return an error message.

    Example expressions:

    hashtag
    Handling Control Samples

    When working with control samples, single-use control samples cannot have their next steps set to anything other than REMOVE.

    Supplying the optional -excludeControls parameter with a value of true ensures the following:

    • The script calculation is only evaluated for noncontrol samples.

    • If next steps are set, the value is set to REMOVE for control samples.

    Note also that the Java contains() method provides a simple way of identifying controls to be removed:

    nextStep = <next step value>

    Used to select Complete and Repeat option, selecting the named step as the next step to continue with.

    ::REWORK:<step name>::

    Used to select Rework to a previous step, selecting the named step as the step to rework the samples from.

    Special Value

    Description

    ::ADVANCE::

    Used to move the samples to the logical next step in the protocol (provided only one next step is permitted)

    ::REPEAT::

    Used to select Repeat this step.

    ::REMOVE::

    Used to remove sample from workflow.

    ::ESCALATE::

    Used to select Request Manager Review. Reviewer name is left unset.

    ::COMPLETE::

    Used to select Mark protocol as Complete.

    ::COMPLETE_REPEAT::

    Used to select Complete and Repeat this step.

    ::COMPLETE_REPEAT:<step name>::

    -exp 'nextStep = ::ADVANCE::'
    -exp 'if (input.QC == true) { nextStep = ::ADVANCE:: } else { nextStep = ::ESCALATE:: }'
    -exp 'if (output.QC == true) { nextStep = ::ADVANCE:: } else { nextStep = ::ESCALATE:: }'
    -exp 'if (input.::QC:: == true) { nextStep = ::TP53 Make Master Mix Deep Well Plate:: } else { nextStep = ::Dilute/Concentrate:: }'
    -exp ‘if (step.::Concentration:: >= 25) { input.QC = true } else {input.QC = false }'
    -exp 'if ( step.::Visual QC Result:: == ::Passed Visual QC:: ) { nextStep = ::SEMI-AUTOMATED - Make DNA Quant and Eval Standard Quant:: } else { nextStep = ::REMOVE:: }'
    -exp 'if (input.::Avg Concentration:: > 25) { nextStep = ::Cluster Generation (LLT):: } else { nextStep = ::ESCALATE:: }'
    -exp 'if (input.name.contains( ::No Template Control::)) { nextStep = ::REMOVE:: }' 
    -exp 'if (input.name.contains( ::CTLl::)) { nextStep = ::REMOVE:: }’

    Setting QC Flags

    In QC steps, some items have a QC flag associated with them. This flag can be read and set from script expressions. The value may be set to true or false.

    Example expressions:

    -exp 'input.QC = input.::Concentration:: >= step.::minConcentration:: && input.::Concentration:: <= step.::maxConcentration::' -exp 'output.QC = input.QC'-exp 'if(Step.::Concentration:: >= 1) { input.QC = true } else { input.QC = false }'