Rename Derived Samples Using the API

Lab scientists must understand the priority of the samples they are working with. To help them prioritize their work, you can rename the derived samples generated by a step so that they include the priority assigned to the original submitted sample.

If you would like to rename a batch of derived samples, you can increase the script execution speed by using batch operations. You can also use a script to rename a derived sample after a step completes.

Prerequisites

If you are using Clarity LIMS v5 and later, make sure that you have done the following actions:

  • Added samples to the system.

  • Defined a global custom field named Priority on the Submitted Sample object. The field should have default values sp1, sp2, and sp3, and it should be enabled on a step.

  • Run samples through the step with the Priority of each sample set to sp1, sp2, or sp3.

Code example

In this example, six samples have been added to a project in Clarity LIMS. The submitted samples names are Heart-1 through Heart-6. The samples are run through a step that generates derived samples, and the priority of each sample is set.

By default, the name of the derived samples generated by the step would follow the name of the original submitted samples as shown in the Assign Next Steps screen of the step.

This example appends the priority of the submitted sample to the name of the derived sample output. The priority is defined by the Priority sample UDF (in Clarity LIMS v4.2 or earlier) or the Priority submitted sample custom field (in Clarity LIMS v5 or later).

Renaming the derived sample consists of the following steps:

  • Request the step information (process resource) for the step that generated the derived sample (analyte resource).

  • Request the individual analyte resource for the derived sample to be renamed.

  • Request the sample resource linked from the analyte resource to get the submitted sample UDF/custom field value to use for the update.

  • Update the individual analyte output resource with the new name.

Step 1. Request the Step Information (Process Resource) for the Step that Generated the Derived Sample (Analyte Resource)

When using the REST API, you will often start with the LIMS ID for the step that generated a derived sample. The key API concepts are as follows.

  • Information about a step is stored in the process resource.

  • In general, automation scripts access information about a step using the processURI, which links to the individual process resource. The input-output-map in the XML returned by the individual process resource gives the script access to the artifacts that were inputs and outputs to the process.

  • Information about a derived sample is stored in the analyte resource. This is used as the input and output of a step.

  • Analytes are also used to record specific details from lab processing.

  • The XML representation for an individual analyte contains a link to the URI of its submitted sample, and to the URI of the process that generated it (parent process).

The following GET method returns the full XML structure for the step.

// Retrieve the process
processURI = "http://${hostname}/api/v2/processes/${processLIMSID}"
process = GLSRestApiUtils.httpGET(processURI, username, password)

The process variable now holds the complete XML structure returned from the process GET request, as shown in the following example. The URI for each analyte generated is given in the output node in each input-output-map element. For more information on the input-output-map, see View the Inputs and Outputs of a Process/Step.

<prc:process uri="http://yourIPaddress/api/v2/processes/A13-BMJ-100830-24-1475" limsid="A13-BMJ-100830-24-1475">
    <type>API Cookbook Example 1.3</type>
    <date-run>2010-08-30</date-run>
    <technician uri="http://yourIPaddress/api/v2/researchers/305">
        <first-name>Brandon</first-name>
        <last-name>Johnson</last-name>
    </technician>
    <input-output-map>
        <input uri="http://yourIPaddress/api/v2/artifacts/HAM754A3PA1?state=15657" post-process-uri="http://yourIPaddress/api/v2/artifacts/HAM754A3PA1?state=15678" limsid="HAM754A3PA1"/>
        <output uri="http://yourIPaddress/api/v2/artifacts/HAM754A3AP10?state=15683" output-type="Analyte" limsid="HAM754A3AP10"/>
    </input-output-map>
    <input-output-map>
        <input uri="http://yourIPaddress/api/v2/artifacts/HAM754A1PA1?state=15651" post-process-uri="http://yourIPaddress/api/v2/artifacts/HAM754A1PA1?state=15685" limsid="HAM754A1PA1"/>
        <output uri="http://yourIPaddress/api/v2/artifacts/HAM754A1AP10?state=15680" output-type="Analyte" limsid="HAM754A1AP10"/>
    </input-output-map>
    <input-output-map>
        <input uri="http://yourIPaddress/api/v2/artifacts/HAM754A2PA1?state=15656" post-process-uri="http://yourIPaddress/api/v2/artifacts/HAM754A2PA1?state=15686" limsid="HAM754A2PA1"/>
        <output uri="http://yourIPaddress/api/v2/artifacts/HAM754A2AP10?state=15681" output-type="Analyte" limsid="HAM754A2AP10"/>
    </input-output-map>
    <input-output-map>
        <input uri="http://yourIPaddress/api/v2/artifacts/HAM754A6PA1?state=15659" post-process-uri="http://yourIPaddress/api/v2/artifacts/HAM754A6PA1?state=15679" limsid="HAM754A6PA1"/>
        <output uri="http://yourIPaddress/api/v2/artifacts/HAM754A6AP10?state=15677" output-type="Analyte" limsid="HAM754A6AP10"/>
    </input-output-map>
    <input-output-map>
        <input uri="http://yourIPaddress/api/v2/artifacts/HAM754A4PA1?state=15655" post-process-uri="http://yourIPaddress/api/v2/artifacts/HAM754A4PA1?state=15682" limsid="HAM754A4PA1"/>
        <output uri="http://yourIPaddress/api/v2/artifacts/HAM754A4AP10?state=15687" output-type="Analyte" limsid="HAM754A4AP10"/>
    </input-output-map>
    <input-output-map>
        <input uri="http://yourIPaddress/api/v2/artifacts/HAM754A5PA1?state=15652" post-process-uri="http://yourIPaddress/api/v2/artifacts/HAM754A5PA1?state=15684" limsid="HAM754A5PA1"/>
        <output uri="http://yourIPaddress/api/v2/artifacts/HAM754A5AP10?state=15688" output-type="Analyte" limsid="HAM754A5AP10"/>
    </input-output-map>
</prc:process>

Step 2. Request the Individual Resource for the Derived Sample to be Renamed (Analyte Resource)

Each output node has an output-type attribute that is the user-defined type name of the output. You can iterate through each input-output-map and request the output artifact resource for each output of a particular output-type.

In the code example shown below, we filter on output-type = Analyte

// For each input-output-map process.'input-output-map'.each { if (it.output.@'output-type'[0] == "Analyte") { // Retrieve the analyte analyteURI = it.output.@uri[0] analyte = GLSRestApiUtils.httpGET(analyteURI, username, password) // Retrieve the analyte's sample and get its Priority UDF's value sampleURI = analyte.sample.@uri[0] sample = GLSRestApiUtils.httpGET(sampleURI, username, password) samplePriority = sample.'udf:field'.find { it.@name== 'Priority' }?.text() // Rename the analyte nameNode = analyte.name[0]

The output-type attribute is the user-defined name for each of the output types generated by a process. This is not equivalent to the type element of an artifact whose value is one of several hard-coded artifact types.

If you must filter inputs or outputs from the input-output-map based on the artifact type, you need to GET each artifact in question to discover its type.

It is important that you remove the state from each of the analyteURIs before you GET them to make sure that you are working with the most recent state. Otherwise, when you PUT the analyteURI back with your UDF changes, you can inadvertently revert information (eg, QC, volume, and concentration) to their previous values.

Step 3. Request the Sample Resource to Get the Field Value to Use for the Update

From the analyte XML, you can use the submitted sample URI to return the sample that maps to that analyte.

Updating Sample Information shows how to set a sample UDF/global field. To get the value of a sample UDF/global field, use the same method to find the field, and then use the .text() method to get the field value.

The value of the UDF is stored in the variable samplePriority so that it is then available for the renaming step described below.

// For each input-output-map
process.'input-output-map'.each {
    if (it.output.@'output-type'[0] == "Analyte") {
        // Retrieve the analyte
        analyteURI = it.output.@uri[0]
        analyte = GLSRestApiUtils.httpGET(analyteURI, username, password)
 
        // Retrieve the analyte's sample and get its Priority UDF's value
        sampleURI = analyte.sample.@uri[0]
        sample = GLSRestApiUtils.httpGET(sampleURI, username, password)
        samplePriority = sample.'udf:field'.find { it.@name== 'Priority' }?.text()
 
        // Rename the analyte
        nameNode = analyte.name[0]

The variable analyte holds the complete XML structure returned from a GET on the URI in the output node. The variable nameNode references the XML element in that structure that contains the artifact's name. The XML for the analyte named Heart-1.

<art:artifact uri="http://yourIPaddress/api/v2/artifacts/AFF853A43AP2?state=20985" limsid="AFF853A43AP2">
    <name>Heart-1</name>
    <type>Analyte</type>
    <output-type>Analyte</output-type>
    <parent-process uri="http://yourIPaddress/api/v2/processes/A13-BMJ-100923-24-2182" limsid="A13-BMJ-100923-24-2182"/>
    <qc-flag>UNKNOWN</qc-flag>
    <location>
        <container uri="http://yourIPaddress/api/v2/containers/27-303" limsid="27-303"/>
        <value>1:1</value>
    </location>
    <working-flag>true</working-flag>
    <sample uri="http://yourIPaddress/api/v2/samples/AFF853A43" limsid="AFF853A43"/>
</art:artifact>

Step 4. Update the Analyte Resource with the Name Change

Renaming the derived sample consists of two steps:

  1. The name change in the XML.

  2. The PUT call to update the analyte resource.

The name change can be performed with the nameNode XML element node defined. The following example shows this element defined.

newName = nameNode.text() + " " + samplePriority
        nameNode.setValue(newName)
        returnNode = GLSRestApiUtils.httpPUT(analyte, analyte.@uri, username, password)
    }

The http PUT command updates the artifact resource using the complete XML representation, including the new name.

Expected Output and Results

After a successful PUT, the results can be reviewed in a web browser at http://yourIPaddress/api/v2/artifacts/TST110A291AP45.

The following XML resource is returned from the PUT command and is stored in returnNode.

<art:artifact uri="http://yourIPaddress/api/v2/artifacts/AFF853A43AP2?state=20985" limsid="AFF853A43AP2">
    <name>Heart-1 sp1</name>
    <type>Analyte</type>
    <output-type>Analyte</output-type>
    <parent-process uri="http://yourIPaddress/api/v2/processes/A13-BMJ-100923-24-2182" limsid="A13-BMJ-100923-24-2182"/>
    <qc-flag>UNKNOWN</qc-flag>
    <location>
        <container uri="http://yourIPaddress:/api/v2/containers/27-303" limsid="27-303"/>
        <value>1:1</value>
    </location>
    <working-flag>true</working-flag>
    <sample uri="http://yourIPaddress/api/v2/samples/AFF853A43" limsid="AFF853A43"/>
</art:artifact> 

In Clarity LIMS, the Assign Next Steps screen shows the new names for the generated derived samples.

This example shows simple renaming of derived samples based on a submitted sample UDF/global field. However, you can use step names, step UDFs (known as master step fields in Clarity LIMS v5 or later), project information, and so on, to rename derived samples and provide critical information to scientists working in the lab.

Attachments

UpdateAnalyteName.groovy:

Last updated