All pages
Powered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Assigning Samples to Workflows

You can use the API (v2 r21 and later) to automate the process of assigning samples to a workflow. This example shows how to create the required XML. The example also provides a brief introduction on how to use the route/artifacts endpoint, which is the endpoint used to perform the sample assignment.

The example takes two samples that exist in Clarity LIMS and assigns each of them to a different workflow.

Code example

Step 1. Define Assignment Endpoint URI

Define the assignment endpoint URI using the following example. The assignment endpoint allows you to assign the artifacts to the desired workflow.

// Define the assignment endpoint URI
assignmentOrderURI = "http://${hostname}/api/v2/route/artifacts/" 

Step 2. Retrieve the Samples' Base Artifact URIs

You can also retrieve the base artifact URIs of the samples using the following example:

// Retrieve the samples' base artifact URIs
sampleAArtifactURI = GLSRestApiUtils.httpGET(sampleURIs[0], username, password).'artifact'.@uri
sampleBArtifactURI = GLSRestApiUtils.httpGET(sampleURIs[1], username, password).'artifact'.@uri 

Step 3. Gather Workflow URIs

Use the following example to gather the workflow URIs:

// Gather the required workflow URIs
workflowAURI = workflowURIs[0]
workflowBURI = workflowURIs[1] 

Step 4. Construct and POST the XML

Next, you can construct the XML that is posted to perform the workflow assignment. You can do this construction by using the StreamingMarkupBuilder and the following example.

Assign the analyte (derived sample) artifact of the sample to a workflow as follows.

  1. Create an assign tag with the URI of the destination workflow as an attribute.

  2. Create an artifact tag inside the assign tag with the URI of the analyte as an attribute.

  3. After the assignment XML is defined, you can POST it to the API. This POST performs the sample assignment.

// Create a new routing assignment using the Markup Builder
def assignmentOrder = builder.bind {
    mkp.xmlDeclaration()
    mkp.declareNamespace(rt: 'http://genologics.com/ri/routing')
    'rt:routing' {
        'assign'('workflow-uri': workflowAURI) {
            'artifact'(uri: sampleAArtifactURI)
        }
        'assign'('workflow-uri': workflowBURI) {
            'artifact'(uri: sampleBArtifactURI)
        }
    }
}

// Post the commands to the API
assignmentOrderNode = GLSRestApiUtils.xmlStringToNode(assignmentOrder.toString())
assignmentOrderNode = GLSRestApiUtils.httpPOST(assignmentOrderNode, assignmentOrderURI, username, password)
println GLSRestApiUtils.nodeToXmlString(assignmentOrderNode)

Expected Output and Results

After the script has run, the samples display in the first step of the first protocol in the specified workflows.

Attachments

AssigningArtifactsToWorkflows.groovy:

2KB
AssigningArtifactsToWorkflows.groovy
Open

Adding Samples to the System

You can add samples to the system using API (v2 r21 and later). This example assumes that you have sample information in a file that is difficult to convert into a format suitable for importing into Clarity LIMS. The aim is to add the samples, and all associated data, into Clarity LIMS without having to translate the file manually. You can use the REST API to add the samples.

Prerequisites

Follow the instructions provided in the following examples:

  • Add a New Project to the System with UDF/Custom Field Value

  • Add an Empty Container to the System

Code example

To add a sample in Clarity LIMS, you must assign it to a project and place it into a container. This example assumes that you are adding a new project and container for the samples being created.

Step 1. Create a New Project

As shown in Add a New Project to the System with UDF/Custom Field Value, you define a project by using StreamingMarkupBuilder. StreamingMarkupBuilder is a built-in Groovy data structure designed to build XML structures. This structure creates the XML that is used in a POST to the projects resource:

def builder = new StreamingMarkupBuilder()
builder.encoding = "UTF-8"
String openDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date())
 
// Create a new project using the Markup Builder
def projectDoc = builder.bind {
    mkp.xmlDeclaration()
    mkp.declareNamespace(prj: 'http://genologics.com/ri/project')
    'prj:project' {
        'name'("${projectName}")
        'open-date'("${openDate}")
        'researcher'(uri:researcherURI)
    }
}
// Post the new project to the API
createdProjectNode = GLSRestApiUtils.xmlStringToNode(projectDoc.toString())
createdProjectNode = GLSRestApiUtils.httpPOST(createdProjectNode, "${projectListURI}", username, password)
println GLSRestApiUtils.nodeToXmlString(createdProjectNode)

If the POST to projects is successful, the following XML is returned:

<prj:project xmlns:prj="http://genologics.com/ri/project" uri="http://yourIPaddress/api/v2/projects/EXA2248" limsid="EXA2248">
  <name>Cookbook Project POST 8.1</name>
  <open-date>2010-09-14</open-date>
  <researcher uri="http://yourIPaddress/api/v2/researchers/1"/>
</prj:project>

Step 2. Create a New Container

As shown in the Add an Empty Container to the System example, you can add a container by using StreamingMarkupBuilder to create the XML for a new container. This creates the XML that is used in a POST to the containers resource:

// Determine the URI of the containers list
containersListURI = "http://${hostname}/api/v2/containers"
// Create a new container using the Markup Builder
def containerDoc = builder.bind {
    mkp.xmlDeclaration()
    mkp.declareNamespace(con: 'http://genologics.com/ri/container')
    mkp.declareNamespace(udf: 'http://genologics.com/ri/userdefined')
    'con:container' {
        'name'("${containerName}")
        'type'(uri:"http://${hostname}/api/v2/containertypes/1", name:"96 well plate")
    }
}
// Post the new container to the API
createdContainerNode = GLSRestApiUtils.xmlStringToNode(containerDoc.toString())
println GLSRestApiUtils.nodeToXmlString(createdContainerNode)
createdContainerNode = GLSRestApiUtils.httpPOST(createdContainerNode, containersListURI, username, password)
println GLSRestApiUtils.nodeToXmlString(createdContainerNode)

If the POST to containers is successful, the following XML is returned:

/** NOTE: if the system has unique container name constraints enabled, change this
value every time script runs*/
<con:container xmlns:con="http://genologics.com/ri/container" uri="http://yourIPaddress/api/v2/containers/27-4075" limsid="27-4075">
  <name>Example 8.1 container</name>
  <type uri="http://yourIPaddress/api/v2/containertypes/1" name="96 well plate"/>
</con:container>

Step 3. Create a New Sample

Now that you have the project and container, you can use StreamingMarkupBuilder to create the sample. The XML created to add the sample uses the URIs for the project and container that were created in the previous steps.

// Determine the samples list URI
sampleListURI = "http://${hostname}/api/v2/samples"
// Create a sample using the Markup Builder
def sampleDoc = builder.bind {
  mkp.xmlDeclaration()
  mkp.declareNamespace(smp: 'http://genologics.com/ri/sample')
  'smp:samplecreation' {
    'name'("${sampleName}")
    'project'(uri:"${createdProjectNode.'@uri'}")
    'location' {
        'container'(limsid:"${createdContainerNode.'@limsid'}", uri:"${createdContainerNode.'@uri'}")
        'value'('A:1')
    }
  }
}
// Post the sample to the API
createdSampleNode = GLSRestApiUtils.xmlStringToNode(sampleDoc.toString())
createdSampleNode = GLSRestApiUtils.httpPOST(createdSampleNode, "${sampleListURI}", username, password)
println GLSRestApiUtils.nodeToXmlString(createdSampleNode)

This POST to the samples resource creates a sample in Clarity LIMS, adding it to the project and container specified in the POST.

Expected Output and Results

In Clarity LIMS Projects and Samples dashboard, open the project to find the new sample in its container.

Attachments

PostSample.groovy:

4KB
PostSample.groovy
Open

Work with Submitted Samples

When working with submitted samples, you can do the following:

  • Adding Samples to the System

  • Renaming Samples

  • Assigning Samples to Workflows

  • Updating Sample Information

  • Show the Relationship Between Samples and Analyte Artifacts (Derived Samples)

Renaming Samples

You can rename samples in the system using API (v2 r21 and later). The amount of information provided in the sample name is sometimes minimal. After the sample is in the system, you can add additional information to the name. For example, you can help lab scientists understand what they must do with a sample, or where it is in processing.

As of Clarity LIMS v5, the term user-defined field (UDF) has been replaced with custom field in the user interface. However, the API resource is still called UDF.

There are two types of custom fields:

  • Master step fields—Configured on master steps. Master step fields only apply to the following:

    • The master step on which the fields are configured.

    • The steps derived from those master steps.

  • Global fields—Configured on entities (eg, submitted sample, derived sample, measurement, etc.). Global fields apply to the entire Clarity LIMS system.

Code example

Clarity LIMS displays detailed information for each sample, including its name, container, well, and date submitted.

In this example, the sample name is Colon-1. To help keep context when samples are processed by default, the submitted sample name is used for the downstream samples (or derived samples) generated by a step in Clarity LIMS.

Step 1. Retrieve the Sample

Before you rename a sample, you must first request the resource via a GET. As REST resources are self-contained entities, always request the full XML representation before editing the portion that you wish to change.

The XML representations of individual REST resources are self-contained entities. Always request the full XML representation before editing any portion of the XML. If you do not use the complete XML when you update the resource, you can inadvertently change data.

The following GET method below returns the full XML structure for the sample:

// Retrieve the sample
sampleURI = "http://${hostname}/api/v2/samples/${sampleLIMSID}"
sample = GLSRestApiUtils.httpGET(sampleURI, username, password)

The variable sample now holds the complete XML structure returned from the sampleURI.

The following example shows the XML for the sample, with the name element on the second line. In this particular case, the Clarity LIMS configuration has expanded the sample with 18 custom fields that provide sample information.

<smp:sample uri="http://yourIPaddress/api/v2/samples/HAM754A1" limsid="HAM754A1">
<name>Colon-1</name>
<date-received>2010-03-25</date-received>
<project uri="http://yourIPaddress/api/v2/projects/HAM754" limsid="HAM754"/>
<artifact uri="http://yourIPaddress/api/v2/artifacts/HAM754A1PA1?state=11822" limsid="HAM754A1PA1"/>
<udf:field type="String" name="Organism">Homo sapiens</udf:field>
<udf:field type="String" name="Gender">Unknown</udf:field>
<udf:field type="Numeric" name="Concentration (ng/uL)">200.0</udf:field>
<udf:field type="Numeric" name="Total Volume (uL)">50</udf:field>
<udf:field type="String" name="Investigator Sample Name">F3_5016</udf:field>
<udf:field type="String" name="Sample Group Phase">Pick Plate</udf:field>
<udf:field type="String" name="Date of Sample Group Phase">2010-05-19</udf:field>
<udf:field type="String" name="Sample QC">FAILED</udf:field>
<udf:field type="String" name="Sample QC Date">2010-04-12</udf:field>
<udf:field type="String" name="Sample Picked">Yes</udf:field>
<udf:field type="String" name="Sample Latest Pick Date">2010-05-19</udf:field>
<udf:field type="Numeric" name="Sample Picked Iteration">3</udf:field>
<udf:field type="String" name="Sample Library Requeue Status"/>
<udf:field type="String" name="Sample Library Requeue Date">2010-05-19</udf:field>
<udf:field type="Numeric" name="Paired End Read Sequencing Lane Iteration">2</udf:field>
<udf:field type="String" name="Paired End Read Sequencing Last Date">2010-01-15</udf:field>
<udf:field type="String" name="Investigator Last Name">Hershberger</udf:field>
<udf:field type="String" name="Cohort">Not Applicable</udf:field>
</smp:sample>

Step 2. Rename the Sample

Renaming the sample consists of the following:

  1. The name change in the XML

  2. The PUT call to update the sample resource

The name change is executed with the nameNode XML element node, which references the XML element containing the name of the sample.

// Rename the sample
nameNode = sample.name[0]
nameNode.setValue(newName)
returnNode = GLSRestApiUtils.httpPUT(sample, sample.@uri, username, password)

The PUT method updates the individual sample resource using the complete XML representation, which includes the new name. Such complete updates provide a simple interaction between client and server.

Expected Output and Results

The updated sample view displays the new name. You can also view the results in a web browser via the URI at

http://<YourIPaddress>/api/v2/samples/<SampleLIMSID>

<smp:sample uri="http://yourIPaddress/api/v2/samples/HAM754A1" limsid="HAM754A1">
<name>Colon-1 Updated</name>
<date-received>2010-03-25</date-received>
<project uri="http://yourIPaddress/api/v2/projects/HAM754" limsid="HAM754"/>
<artifact uri="http://yourIPaddress/api/v2/artifacts/HAM754A1PA1?state=11822" limsid="HAM754A1PA1"/>
<udf:field type="String" name="Organism">Homo sapiens</udf:field>
<udf:field type="String" name="Gender">Unknown</udf:field>
<udf:field type="Numeric" name="Concentration (ng/uL)">200.0</udf:field>
<udf:field type="Numeric" name="Total Volume (uL)">50</udf:field>
<udf:field type="String" name="Investigator Sample Name">F3_5016</udf:field>
<udf:field type="String" name="Sample Group Phase">Pick Plate</udf:field>
<udf:field type="String" name="Date of Sample Group Phase">2010-05-19</udf:field>
<udf:field type="String" name="Sample QC">FAILED</udf:field>
<udf:field type="String" name="Sample QC Date">2010-04-12</udf:field>
<udf:field type="String" name="Sample Picked">Yes</udf:field>
<udf:field type="String" name="Sample Latest Pick Date">2010-05-19</udf:field>
<udf:field type="Numeric" name="Sample Picked Iteration">3</udf:field>
<udf:field type="String" name="Sample Library Requeue Status"/>
<udf:field type="String" name="Sample Library Requeue Date">2010-05-19</udf:field>
<udf:field type="Numeric" name="Paired End Read Sequencing Lane Iteration">2</udf:field>
<udf:field type="String" name="Paired End Read Sequencing Last Date">2010-01-15</udf:field>
<udf:field type="String" name="Investigator Last Name">Hershberger</udf:field>
<udf:field type="String" name="Cohort">Not Applicable</udf:field>
</smp:sample>

Attachments

RenamingSample.groovy:

1KB
RenamingSample.groovy
Open

Updating Sample Information

The most important information about a sample is often recorded in custom fields in API (v2 r21 and later). These fields often contain information that is critical to the processing of the sample, such as species or sample type.

When samples come into the lab, you can provide lab scientists with information about priority or quality. You can provide this information by changing the value of specific sample custom fields.

This example shows how to change the value of a sample custom field called Priority after you have entered a submitted sample into the system.

As of Clarity LIMS v5, the term user-defined field (UDF) has been replaced with custom field in the user interface. However, the API resource is still called UDF.

There are two types of custom fields:

  • Master step fields—Configured on master steps. Master step fields only apply to the following:

    • The master step on which the fields are configured.

    • The steps derived from those master steps.

  • Global fields—Configured on entities (eg, submitted sample, derived sample, measurement, etc.). Global fields apply to the entire Clarity LIMS system.

Code example

In Clarity LIMS, you can display detailed information for a sample, including the following:

  • Name

  • Clarity LIMS ID

  • Custom fields

In the following figure, you can see that the sample name is DNA Sample-1 and the field named Priority has the value High.

In this example, change the value of the Priority custom field to Critical.

Step 1. Retrieve the Resource

Before you can change the value of the field, you must first request the resource via a GET method.

To change a sample submitted in Clarity LIMS, use the individual sample resource. The XML returned from a GET on the individual sample resource contains the information about the sample.

The following GET method returns the full XML structure for the sample:

// Retrieve the sample
sampleURI = "http://${hostname}/api/v2/samples/${sampleID}"
sample = GLSRestApiUtils.httpGET(sampleURI, username, password) 

The sample variable now holds the complete XML structure returned from the sample GET request.

The XML representations of individual REST resources are self-contained entities. Always request the complete XML representation before editing any portion of the XML. If you do not use the complete XML when you update the resource, you can inadvertently change data.

The following shows XML returned for the sample, with the Priority field shown in red in the second to last line. In this example:

  • The Clarity LIMS configuration has added three fields to the expanded sample information.

  • The UDFs are named Sample Type, Phenotypic Information, and Priority.

<smp:sample uri="http://yourIPaddress/api/v2/samples/ADM201A1" limsid="ADM201A1">
    <name>DNA sample-1</name>
    <date-received>2017-04-18</date-received>
    <project uri="http://yourIPaddress/api/v2/projects/ADM201" limsid="ADM201"/>
    <artifact uri="http://yourIPaddress/api/v2/artifacts/ADM201A1PA1?state=2995" limsid="ADM201A1PA1"/>
    <udf:field type="String" name="Sample Type">DNA</udf:field>
    <udf:field type="String" name="Phenotypic Information">Human</udf:field>
    <udf:field type="String" name="Priority">High</udf:field>
</smp:sample>

Step 2. Update the Sample UDF

When updating the Priority field, you need to do the following:

  • Change the value in the XML.

  • Use a PUT method to update the sample resource.

You can change the value for Priority to Critical by using the utility files setUdfValue method.

The subsequent PUT method updates the sample resource at the specified URI using the complete XML representation, which includes the new custom field value for XML.

// Update the sample's Priority UDF value
sample = GLSRestApiUtils.setUdfValue(sample, 'Priority', 'Critical')
returnNode = GLSRestApiUtils.httpPUT(sample, sample.@uri, username, password)
println GLSRestApiUtils.nodeToXmlString(returnNode)

A successful PUT returns the new XML in the returnNode. The results can also be reviewed in a web browser at <YourIPaddress>/api/v2/samples/<SampleLIMSID> URI.

An unsuccessful PUT returns the HTTP response code and message in the returnNode XML .

NOTE: The values for the other two fields, Sample Type and Phenotypic Information, did not change. These values did not change because they were included in the XML used in the PUT (eg, they were held in the sample variable as part of the complete XML structure).

If those custom fields had not been included in the XML, they would have been updated to have no value.

Expected Output and Results

The following XML from our example shows the expected output:

<smp:sample uri="http://yourIPaddress/api/v2/samples/ADM201A1" limsid="ADM201A1">
    <name>DNA sample-1</name>
    <date-received>2017-04-18</date-received>
    <project uri="http://yourIPaddress/api/v2/projects/ADM201" limsid="ADM201"/>
    <artifact uri="http://yourIPaddress/api/v2/artifacts/ADM503A1PA1?state=2995" limsid="ADM201A1PA1"/>
    <udf:field type="String" name="Sample Type">DNA</udf:field>
    <udf:field type="String" name="Phenotypic Information">Human</udf:field>
    <udf:field type="String" name="Priority">Critical</udf:field>
</smp:sample>

In Clarity LIMS, the updated sample details now show the new Priority value.

Attachments

UpdateSampleUDF.groovy:

1KB
UpdateSampleUDF.groovy
Open

Show the Relationship Between Samples and Analyte Artifacts (Derived Samples)

In the Clarity LIMS API (v2 r21 or later), the initial submitted sample is referred to as a sample (or root artifact). Any derived sample output from a process/step is referred to as an analyte, or artifact of type analyte. This example demonstrates the relationship between samples and analyte artifacts. You must have a sample in the system and one or more processes/steps done that output analyte (derived sample) artifacts.

As of Clarity LIMS v5, the term user-defined field (UDF) has been replaced with custom field in the user interface. However, the API resource is still called UDF.

There are two types of custom fields:

  • Master step fields—Configured on master steps. Master step fields only apply to the following:

    • The master step on which the fields are configured.

    • The steps derived from those master steps.

  • Global fields—Configured on entities (eg, submitted sample, derived sample, measurement, etc.). Global fields apply to the entire Clarity LIMS system.

Code example

The code example does the following when it is used:

  • Retrieves the URI of an arbitrary analyte artifact.

  • Retrieves the corresponding sample of the artifact

  • Retrieves the original root analyte artifact from the sample, as shown in the following example:

Expected Output and Results

You can generate XML for an arbitrary analyte artifact. The analyte artifact is downstream and has a parent-process element (as shown in line 5). The sample artifact is an original artifact. Downstream artifacts relate to at least one sample, but can also relate to more than one sample, like with pooling or shared result files. The following is an example of XML generated for an analyte artifact:

You can also generate XML for a submitted sample. Every submitted sample has exactly one corresponding original root artifact. A sample representation does not link to downstream artifacts, but you can find them using query parameters in the artifacts list resource. The following is an example of XML generated for a submitted sample:

Lastly, you can generate XML for an original sample artifact called a root artifact. The following is an example of XML generated from an original sample artifact. In this case, both the downstream artifact and the original root artifact point to the same original sample (eg, LIMS ID EXA2241A1).

Attachments

SampleAndAnalyteRelations.groovy:

// Determine the analyte's URI and retrieve it
arbitraryAnalyteArtifactURI = "http://${hostname}/api/v2/artifacts/${artifactLIMSID}"
arbitraryArtifactNode = GLSRestApiUtils.httpGET(arbitraryAnalyteArtifactURI, username, password)
println GLSRestApiUtils.nodeToXmlString(arbitraryArtifactNode)
 
// Retrieve the analyte's sample
def rootSampleURI = arbitraryArtifactNode.'sample'[0].'@uri'
rootSampleNode = GLSRestApiUtils.httpGET(rootSampleURI, username, password)
println GLSRestApiUtils.nodeToXmlString(rootSampleNode)
 
// Retrieve the sample's root analyte
def rootAnalyteArtifactURI = rootSampleNode.'artifact'[0].'@uri'
rootAnalyteArtifactNode = GLSRestApiUtils.httpGET(rootAnalyteArtifactURI, username, password)
println GLSRestApiUtils.nodeToXmlString(rootAnalyteArtifactNode)
<art:artifact xmlns:art="http://genologics.com/ri/artifact" uri="http://yourIPaddress/api/v2/artifacts/EXA2241A1DN3?state=18882" limsid="EXA2241A1DN3">
  <name>Example Analyte Artifact</name>
  <type>Analyte</type>
  <output-type>Analyte</output-type>
  <parent-process uri="http://yourIPaddress/api/v2/processes/DNA-SA1-100914-24-1917" limsid="DNA-SA1-100914-24-1917"/>
  <qc-flag>UNKNOWN</qc-flag>
  <location>
    <container uri="http://yourIPaddress/api/v2/containers/27-3543" limsid="27-3543"/>
    <value>A:2</value>
  </location>
  <working-flag>false</working-flag>
  <sample uri="http://yourIPaddress0/api/v2/samples/EXA2241A1" limsid="EXA2241A1"/>
</art:artifact> 
<smp:sample xmlns:smp="http://genologics.com/ri/sample" uri="http://yourIPaddress/api/v2/samples/EXA2241A1" limsid="EXA2241A1">
  <name>Example Sample</name>
  <project uri="http://yourIPaddress/api/v2/projects/EXA2241" limsid="EXA2241"/>
  <artifact uri="http://yourIPaddress/api/v2/artifacts/EXA2241A1SAM1?state=18879" limsid="EXA2241A1SAM1"/>
  <biosource/>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" type="String" name="String Type UDF">Updated String UDF Value</udf:field>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" type="Text" name="Text Type UDF">Updated Text UDF Value</udf:field>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" unit="u" type="Numeric" name="Numeric Type UDF">3.140</udf:field>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" type="Boolean" name="Boolean Type UDF">true</udf:field>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" type="Date" name="Date Type UDF">2010-09-14</udf:field>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" type="URI" name="URI Type UDF">http://www.genologics.com</udf:field>
  <udf:field xmlns:udf="http://genologics.com/ri/userdefined" type="Executable" name="Executable Type UDF">/usr/bin/yes</udf:field>
</smp:sample> 
<art:artifact xmlns:art="http://genologics.com/ri/artifact" uri="http://yourIPaddress/api/v2/artifacts/EXA2241A1SAM1?state=18879" limsid="EXA2241A1SAM1">
  <name>Example Analyte Artifact</name>
  <type>Analyte</type>
  <output-type>Analyte</output-type>
  <qc-flag>UNKNOWN</qc-flag>
  <location>
    <container uri="http://yourIPaddress/api/v2/containers/27-3543" limsid="27-3543"/>
    <value>A:1</value>
  </location>
  <working-flag>true</working-flag>
  <sample uri="http://yourIPaddress/api/v2/samples/EXA2241A1" limsid="EXA2241A1"/>
</art:artifact>
2KB
SampleAndAnalyteRelations.groovy
Open