When samples are placed onto containers in BaseSpace Clarity LIMS, the default operation is that containers produced by the system are named with their LIMS ID (for example 27-1234 etc). The expectation is that after samples have been placed, the user will rename the containers with the barcode that is on the plate, chip, or other container.
There are places in the workflow in which issues will occur with integrations if the user renames the container incorrectly.
For example, when loading libraries onto a flow cell for sequencing, the flow cell container must be renamed with the actual ID/barcode of the flow cell in order for the Illumina integration to complete its work successfully.
This example provides a short script that checks to see if the user has correctly renamed containers after the placement of samples. It also shows what occurs in the Clarity LIMS Web Interface when the script encounters a naming issue.
In this example, the protocol step is configured to invoke the script when the user exits the step's Sample Placement screen.
The EPP command is configured to pass the following parameters:
An example of the full syntax to invoke the script is as follows:
When the user enters the Sample Placement screen, the rightmost Placed Samples area will show the containers created with their default, system-assigned names:
When the user tries to leave the Sample Placement screen, the script is invoked:
If the script finds any containers that still have their default, system-assigned names, an error message is generated:
To complete the protocol step, the user must first rename the containers:
The main method of interest is validateContainerNames().
This method queries the placements resource for the current step, and gathers the LIMS IDs of the selected containers.
For each selected container associated with the protocol step, the containers resource is called:
The container name is compared to the LIMS ID.
If the values are identical, an error message is generated.
Additional validation: Ideally, this script is set up to also validate the renamed containers against a specific goal. For example, the attached example script checks to see that the new name is at least 10 characters in length. You may choose to replace or supplement this optional, additional validation to provide specific logic to suit your business needs.\
Both of the attached files are placed on the Clarity LIMS server, in the /opt/gls/clarity/customextensions folder.
You will need to update the HOSTNAME global variable such that it points to your Clarity LIMS server.
The example code is provided for illustrative purposes only. It does not contain sufficient exception handling for use 'as is' in a production environment.
validateContainerNames.py:
When pooling samples, there are often numerous complex rules and restrictions regarding which combinations of adapters are acceptable.
As a method of applying custom business logic, it is possible to automate the verification of your pools using Clarity LIMS.
This example shows how to confirm the composition of pools before they are created, allowing the lab scientist to alter the composition of pools that have caused an error.
In this example, we will enforce the following Illumina TruSeq DNA LT adapter tube pooling guidelines:
The example script is configured to run on the Library Pooling (Illumina SBS) 4.0 process.
The EPP command is configured to pass the following parameters to the script:
An example of the full syntax to invoke the script is as follows:
NOTE: The location of Groovy on your server may be different from the one shown in this example. If this is the case, modify the script accordingly.
Assuming samples have been worked through the protocol and have reached the Library Pooling (Illumina SBS) 4.0 protocol step, the user pools the samples following the specified guidelines.
When the pools are created, the user attempts to proceed to the next page.
A message box displays alerting the user that a custom program is executing.
On successful completion, a success message displays.
Once the script has processed the input and ensured that all the required information is available, we process the pools to determine if they meet the required specifications.
The first challenge is to represent the adapter combinations in the script.
This is accomplished by a map comprised of the adapter names, indexed by their respective number, ie. AD001 indexed at 1.
Next, we define the three combination groups: 2 plex, 3 plex, and 4 plex.
This is achieved by creating a List of Lists, with the inner lists representing our combinations.
To facilitate the required fallback through lower plexity combinations, we store the combinations groups in a list, in ascending plexity.\
Once the combinations are defined, we need to create a method which will compare the actual combination of adapters in a pool with our ideal combinations. There are two cases we need to handle:
When we are comparing two equal plexity combinations.
When we are comparing a higher plexity pool to a lower plexity combination.
To handle the first case, we create a function that takes in our actual combination, and the ideal combination.
If the actual combination contains the entire combination, we remove those adapters. We then ensure that the leftover adapters are not in our Illumina TruSeq DNA LT adapter.\
The second case is similar to the first.
We create a function that takes in our actual combination, the ideal combination, and the amount of wildcards. A wildcard represents an 'any adapter' condition in Illumina's TruSeq DNA LT adapter tube pooling guidelines.
Like the first case, we ensure that the actual list contains the entire ideal combination.
After removing the ideal adapters, we ensure that the amount of leftover Illumina TruSeq DNA LT adapters is equal to the amount of wildcards.
To represent the adapter combination fallbacks, we require a method which will attempt to match the highest possible plexity for a given list of adapters. If it cannot do this, it will attempt to match it with a lower plexity combination with a wildcard.
To achieve this, we define a recursive function that handles both the exact and wildcard cases. The ideal combination plexitys will be chosen by the patternIndex input.
If no wildcards are present, we check each combination in the designated plexity.
If a match is not found, we call the match function again. This time, we increase the amount of wildcards by 1 and reduce the plexity of the combinations by 1. The function will now compare the adapter list using the wildCardMatch function. If a match is found, the function will exit and return true.
Now, with our supporting functions defined, we can start processing our pools.
First we retrieve the definitions of the pools from the API. This node contains a list of the output pools, in addition to what input each pool contains.
Using this list, we create a map that stores the URIs of the output pools and the amount of inputs to each pool.
We then retrieve the output pools using a batchGET.
Once we have the pools, we iterate through the list.
If a pool is valid, we increment a counter which will be used in our success message.
If invalid, we set the script outcome to failure, and append to the failure message.
The script continues searching for other issues and adding their information to the failure message.
After each pool has been checked, we determine how to alert the user of the script's completion.
If a pool is invalid, an error is thrown containing the list of failures and a recommendation to review the Illumina pooling guidelines.
If all pools are valid, we alert the user of a success.
Your configuration conforms with the script's requirements, as documented in #solution.
You are running a version of Groovy that is supported by Clarity LIMS, as documented in the Clarity LIMS Technical Requirements.
The attached Groovy file is placed on the LIMS server, in the /opt/gls/clarity/customextensions folder.
GLSRestApiUtils.groovy is placed in your Groovy lib folder.
You have imported the attached Reagent XML file into your system using the Config Slicer tool.
The example code is provided for illustrative purposes only. It does not contain sufficient exception handling for use 'as is' in a production environment.
ConfirmationOfPoolComposition.groovy:
Single Indexing ReagentTypes.xml:
In this example, the protocol step is configured to invoke a script that is triggered when the user exits the step's Record Details screen.
The EPP command is configured to pass the following parameters to the script:
An example of the full syntax to invoke the script is as follows:
When the lab scientist attempts to exit the Record Details screen, the script is invoked and the UDF names specified in the -f parameter will be checked to see that they have been populated. If they ALL have been, the script issues no message, and the process will continue as normal. If however, SOME of the UDFs have not been populated, a message will be displayed to the user indicating which mandatory fields need to be populated, and the user will be unable to move forward until all the specified fields have been populated.
The method of central interest in the script is checkFields(). The method in turn carries out several operations:
The list of fields passed to the script via the -f parameter is broken into its component UDF names
For each UDF name in the list, the corresponding value is checked via the API, and if the value is empty, the UDF name is noted as absent
If any UDF names are noted as being absent, an error dialog will be displayed to the user.
Both of the attached files are placed on the LIMS server, in the /opt/gls/clarity/customextensions folder.
The HOSTNAME global variable needs to be updated so that it points to your Clarity LIMS server.
The example code is provided for illustrative purposes only. It does not contain sufficient exception handling for use 'as is' in a production environment.
If required, this script could be enhanced so that it not only checked to see that the UDFs had been populated, but that their values also matches a regexp pattern for additional validation.
checkprocessFields.py:
While not a common scenario, it is possible to have two molecular barcodes/indices in BaseSpace Clarity LIMS that share the same sequence.
Within Clarity LIMS, there is logic that can be enabled to prevent pooling of samples with the same index name. However, this check is based upon the index name, not the sequence. In the case of identical indexes with differing names, additional logic is required to prevent index clashes based upon the index sequence.
This example provides a solution that looks for index clashes based upon sequence.
In this example, the protocol step that is responsible for pooling is configured to invoke the script as soon as the user exits the step's Pooling screen.
The EPP command is configured to pass the following parameters:
An example of the full syntax to invoke the script is as follows:
When the user exits the Pooling screen, the script is invoked.
If no index clashes are found, the step proceeds and the script does not report back to the user.
If an index clash is found, a message is returned to the user, informing them of the problematic components within the affected pool. The user is not able to continue the step without first re-constituting the pools.
The main method in the script is checkIndexes(). The method in turn carries out several operations:
The step's pools resource is queried.
The constituent artifacts of each pool are identified, along the with name of the reagent-label applied.
For each reagent-label:
The associated sequence is identified.
A dictionary is constructed using the sequence as key, the value being the name of the derived sample(s) associated with the sequence
If any sequence in the dictionary is associated with more than one derived sample, an error message is constructed and is reported to the user once all pools have been considered.
Both of the attached files are placed on the Clarity LIMS server, in the /opt/gls/clarity/customextensions folder.
You will need to update the HOSTNAME global variable such that it points to your Clarity LIMS server.
The example code is provided for illustrative purposes only. It does not contain sufficient exception handling for use 'as is' in a production environment.
NOTE: The current script uses caching to avoid unnecessary GETs, but does not use batch transactions. In the case of large levels of multiplexing, the script could be reworked to gather all of the constituent artifacts in a single batch transaction.
checkIndexes.py:
-l
The limsid of the process invoking the script (Required)
-u
The username of the current user (Required)
-p
The password of the current user (Required)
-s
The URI of the step that launches the script (Required)
-i
The URI of the step that launches the script (Required)
The {stepURI:v2:http} token - in the form http://<Hostname>/api/v2/steps/<ProtocolStepLimsid>
-u
The username of the current user (Required)
The {username} token
-p
The password of the current user (Required)
The {password} token
-l
The limsid of the process invoking the script (Required)
-u
The username of the current user (Required)
-p
The password of the current user (Required)
-f
The names(s) of the UDF(s) that should be considered mandatory
Multiple UDF names should be separated by a comma
-l
The limsid of the process invoking the code (Required)
The {processLuid} token
-u
The username of the current user (Required)
The {username} token
-p
The password of the current user (Required)
The {password} token
-s
The URI of the step that launches the script (Required)
The {stepURI:v2:http} token