In [ ]:
import urllib
import ovation.lab.workflows as workflows
import ovation.session as session
Create a session
. Note the api endpoint, lab-services.ovation.io
for Ovation Service Lab.
In [ ]:
s = session.connect(input('Email: '), api='https://lab-services.ovation.io')
A QC activity determines the status of results for each Sample in a Workflow. Normally, QC activities are handled in the web application, but you can submit a new activity with the necessary information to complete the QC programaticallly.
First, we'll need a workflow and the label of the QC activity WorkflowActivity
:
In [ ]:
workflow_id = input('Workflow ID: ')
In [ ]:
qc_activity_label = input('QC activity label: ')
Next, we'll get the WorkflowSampleResults
for the batch. Each WorkflowSampleResult
contains the parsed data for a single Sample
within the batch. Each WorkflowSampleResult
has a result_type
that distinguishes each kind of data.
In [ ]:
result_type = input('Result type: ')
In [ ]:
workflow_sample_results = s.get(s.path('workflow_sample_results'), params={'workflow_id': workflow_id,
'result_type': result_type})
workflow_sample_results
Within each WorkflowSampleResult
you should see a result
object containing records for each assay. In most cases, the results parser created a record for each line in an uploaded tabular (csv or tab-delimited) file. When that record has an entry identifiying the sample and an entry identifying the assay, the parser places that record into the WorkflowSampleResult
for the corresponding Workflow Sample, result type, and assay. If more than one record matches this Sample > Result type > Assay, it will be appended to the records for that sample, result type, and assay.
A QC activity updates the status of assays and entire Workflow Sample Results. Each assay may recieve a status ("accepted", "rejected", or "repeat") indicating the QC outcome of that assay for a particular sample. In addition, the WorkflowSampleResult has a global status indicating the overall QC outcome for that sample and result type. Individual assay statuses may be used on repeat to determine which assays need to be repeated. The global status determines how the sample is routed following QC. In fact, there can be multiple routing options for each status (e.g. an "Accept and process for workflow A" and "Accept and process for workflow B" options). Ovation internally uses a routing
value to indicate (uniquely) which routing option to chose from the configuration. In many cases routing
is the same as status
(but not always).
WorkflowSampleResult
and assay statuses are set (overriding any existing status) by creating a QC activity, passing the updated status for each workflow sample result and contained assay(s).
In this example, we'll randomly choose statuses for each of the workflow samples above:
In [ ]:
import random
WSR_STATUS = ["accepted", "rejected", "repeat"]
ASSAY_STATUS = ["accepted", "rejected"]
qc_results = []
for wsr in workflow_sample_results:
assay_results = {}
for assay_name, assay in wsr.result.items():
assay_results[assay_name] = {"status": random.choice(ASSAY_STATUS)}
wsr_status = random.choice(WSR_STATUS)
result = {'id': wsr.id,
'result_type': wsr.result_type,
'status': wsr_status,
'routing': wsr_status,
'result': assay_results}
qc_results.append(result)
The activity
data we POST will look like this:
{"workflow_sample_results": [{"id": WORKFLOW_SAMPLE_RESULT_ID,
"result_type": RESULT_TYPE,
"status":"accepted"|"rejected"|"repeat",
"routing":"accepted",
"result":{ASSAY:{"status":"accepted"|"rejected"}}},
...]}}
In [ ]:
qc = workflows.create_activity(s, workflow_id, qc_activity_label,
activity={'workflow_sample_results': qc_results,
'custom_attributes': {} # Always an empty dictionary for QC activities
})