Run a Process/Step

When samples are processed in the lab, they are sometimes re-arrayed in complex ways that are pre-defined.

You can use the REST API and automation functionality that will allow a user to initiate a step that:

  1. Uses a file to define a re-array pattern

  2. Executes the step using that re-array pattern. Since the pattern is pre-defined, this will decrease the likelihood of an error in recording the re-array.

To accomplish this automation, you must be able to execute a step using the REST API. This example shows a simple step execution that you can apply to any automated step execution needed in your lab.

For a high-level overview of REST resource structure in Clarity LIMS, including how processes are the key to tracking work, see REST General Concepts.

Prerequisites

Before you follow the example, make sure that you have the following items:

  • Samples that have been added to the system.

  • A configured step/process that generates analytes (derived samples) and a shared result file.

  • Samples that have been run through the configured process/step.

  • A compatible version of API (v2 r21 or later).

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

Information about a derived sample is stored in the analyte resource in the API. This resource is used as the input and output of a step, and also used to record specific details from lab processing.

Code Example

To run a step/process on a set of samples, you must first identify the set of samples to be used as inputs.

The samples that are inputs to a step/process can often be identified because they are all in the same container, or because they are all outputs of a previous step / process.

For more information, refer to Find the Contents of a Well Location in a Container and View the Inputs and Outputs of a Process/Step.

In this example, you run the step/process on the samples listed in the following table.

After you have identified the samples, use their LIMS IDs to construct the URIs for the respective analyte (derived sample) artifacts. The artifact URIs are used as the inputs in constructing the XML to POST and execute a process.

You can use StreamingMarkupBuilder to construct the XML needed for the POST, as shown in the following example code:

// Determine the list URIs and the specified analyte URIs
processListURI = "http://${hostname}/api/v2/processes"
researcherURI = "http://${hostname}/api/v2/researchers/1"
analyte1URI = "http://${hostname}/api/v2/artifacts/${analyteLIMSIDs[0]}"
analyte2URI = "http://${hostname}/api/v2/artifacts/${analyteLIMSIDs[1]}"
analyte3URI = "http://${hostname}/api/v2/artifacts/${analyteLIMSIDs[2]}"

// Retrieve the process type
processTypeNode = GLSRestApiUtils.httpGET(processTypeURI, username, password)
 
// Create a new process using the Markup Builder
def processDoc = new StreamingMarkupBuilder().bind {
    mkp.xmlDeclaration()
    mkp.declareNamespace(prx: 'http://genologics.com/ri/processexecution')
    'prx:process'{
        'type'(processTypeNode.'@name')
        'technician'(uri:researcherURI)
        'input-output-map' {
            'input'(uri:analyte1URI)
            'output'(type:'Analyte') {
                'location' {
                    'container'(uri:container96WellsURI)
                    'value'("A:1")
                }
            }
        }
        'input-output-map' {
            'input'(uri:analyte2URI)
            'output'(type:'Analyte') {
                'location' {
                    'container'(uri:container96WellsURI)
                    'value'("A:2")
                }
            }
        }
        'input-output-map' {
            'input'(uri:analyte3URI)
            'output'(type:'Analyte') {
                'location' {
                    'container'(uri:container96WellsURI)
                    'value'("A:3")
                }
            }
        }
        'input-output-map'(shared:'true') {
            'input'(uri:analyte1URI)
            'input'(uri:analyte2URI)
            'input'(uri:analyte3URI)
            'output'(type:'ResultFile')
        }
    }
}
// Post the new process to the API
unresolvedProcessNode = GLSRestApiUtils.xmlStringToNode(processDoc.toString())
returnNode = GLSRestApiUtils.httpPOST(unresolvedProcessNode, "${processListURI}", username, password)

Executing a process uses the processexecution (prx) namespace (shown in bold in the code example above).

The required elements for a successful POST are:

  • type – the name of the process being run

  • technician uri – the URI for the technician that will be listed as running the process

  • input-output-map – one input output map element for each pair of inputs and outputs

  • input uri – the URI for the input artifact

  • output type – the type of artifact of the output

In addition, if the outputs of the process are analytes, then the following are also needed:

  • container uri – the URI for the container the output will be placed in

  • value – the well placement for the output

The process type, technician, input artifact, and container must all exist in the system before the process can be executed. So, for example, if there is no container with an empty well, you must create a container before running the process.

The XML constructed must match the configuration of the process type. For example, if the process is configured to have both samples and a shared result file as outputs, you must have both of the following:

  • An input-output-map for each pair of sample inputs and outputs

  • An additional input-output-map for the shared result file

If the POST is successful, the process XML is returned:

<prc:process xmlns:prc="http://genologics.com/ri/process" uri="http://yourIPaddress/api/v2/processes/A22-BMJ-100930-24-2203" limsid="A22-BMJ-100930-24-2203">
  <type>HiSEQ PE</type>
  <date-run>2016-09-30</date-run>
  <technician uri="http://yourIPaddress/api/v2/researchers/305">
    <first-name>John-Luck</first-name>
    <last-name>Pikkard</last-name>
  </technician>
  <input-output-map>
    <input uri="http://yourIPaddress/api/v2/artifacts/AFF853A55AP11?state=21128" post-process-uri="http://yourIPaddress/api/v2/artifacts/AFF853A55AP11?state=21135" limsid="AFF853A55AP11">
      <parent-process uri="http://yourIPaddress/api/v2/processes/A33-BMJ-100930-24-2200" limsid="A33-BMJ-100930-24-2200"/>
    </input>
    <output uri="http://yourIPaddress/api/v2/artifacts/92-2538?state=21134" output-type="ResultFile" limsid="92-2538"/>
  </input-output-map>
  <input-output-map>
    <input uri="http://yourIPaddress/api/v2/artifacts/AFF853A55AP11?state=21128" post-process-uri="http://yourIPaddress/api/v2/artifacts/AFF853A55AP11?state=21135" limsid="AFF853A55AP11">
      <parent-process uri="http://yourIPaddress/api/v2/processes/A33-BMJ-100930-24-2200" limsid="A33-BMJ-100930-24-2200"/>
    </input>
    <output uri="http://yourIPaddress/api/v2/artifacts/AFF853A55AP13?state=21136" output-type="Analyte" limsid="AFF853A55AP13"/>
  </input-output-map>
  <input-output-map>
    <input uri="http://yourIPaddress/api/v2/artifacts/AFF853A53AP11?state=21124" post-process-uri="http://yourIPaddress/api/v2/artifacts/AFF853A53AP11?state=21130" limsid="AFF853A53AP11">
      <parent-process uri="http://yourIPaddress/api/v2/processes/A33-BMJ-100930-24-2200" limsid="A33-BMJ-100930-24-2200"/>
    </input>
    <output uri="http://yourIPaddress/api/v2/artifacts/92-2538?state=21134" output-type="ResultFile" limsid="92-2538"/>
  </input-output-map>
  <input-output-map>
    <input uri="http://yourIPaddress/api/v2/artifacts/AFF853A53AP11?state=21124" post-process-uri="http://yourIPaddress/api/v2/artifacts/AFF853A53AP11?state=21130" limsid="AFF853A53AP11">
      <parent-process uri="http://yourIPaddress/api/v2/processes/A33-BMJ-100930-24-2200" limsid="A33-BMJ-100930-24-2200"/>
    </input>
    <output uri="http://yourIPaddress/api/v2/artifacts/AFF853A53AP13?state=21132" output-type="Analyte" limsid="AFF853A53AP13"/>
  </input-output-map>
  <input-output-map>
    <input uri="http://yourIPaddress/api/v2/artifacts/AFF853A54AP11?state=21125" post-process-uri="http://yourIPaddress/api/v2/artifacts/AFF853A54AP11?state=21133" limsid="AFF853A54AP11">
      <parent-process uri="http://yourIPaddress/api/v2/processes/A33-BMJ-100930-24-2200" limsid="A33-BMJ-100930-24-2200"/>
    </input>
    <output uri="http://yourIPaddress/api/v2/artifacts/92-2538?state=21134" output-type="ResultFile" limsid="92-2538"/>
  </input-output-map>
  <input-output-map>
    <input uri="http://yourIPaddress/api/v2/artifacts/AFF853A54AP11?state=21125" post-process-uri="http://yourIPaddress/api/v2/artifacts/AFF853A54AP11?state=21133" limsid="AFF853A54AP11">
      <parent-process uri="http://yourIPaddress/api/v2/processes/A33-BMJ-100930-24-2200" limsid="A33-BMJ-100930-24-2200"/>
    </input>
    <output uri="http://yourIPaddress/api/v2/artifacts/AFF853A54AP13?state=21131" output-type="Analyte" limsid="AFF853A54AP13"/>
  </input-output-map>
</prc:process>

If the POST is not successful, the XML returned will contain the error that occurred when the POST completed:

<exc:exception xmlns:exc="http://genologics.com/ri/exception">
  <message>The process type named 'HiSEQ PE' cannot produce the following types of shared outputs: 'ResultFile'.</message>
</exc:exception>

Expected Output and Results

After the step / process has successfully executed, you can open the Record Details screen and see the step outputs.

Attachments

RunningAProcess.groovy:

Last updated