Quality Check API Example


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')

Create a Quality Check (QC) activity

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
                                       })