Tasks and Transport

Overview

This section covers tasks, the fundamental building blocks of workflows. It explains the various types of tasks and their relationship to transport capabilities within a workflow.

Tasks are any action that must occur in a sequence in a workflow. A LINQ workflow is, fundamentally, a graph of tasks that take place on instruments with labware or execute via custom code or data integrations.

ActionTask basics

The ActionTask class represents the execution of an action on a workcell. This could be the positioning of labware from one point to another, an instrument doing something via a driver, or a step requiring a manual operator’s confirmation.

uncap_tubes = ActionTask(
    id="uncap_tubes",
    description="Uncap tubes",
    instrument_type=uncapper.type,
    action="uncap",
    time_estimate=30,
    labware_sources=[centrifuge_tubes.forward(labware=tubes)],
    labware_outputs=[LabwareOutput(tubes)],
)

For the relationship of ActionTasks to instruments and drivers, see Instruments and Drivers.

For controlling the order and timings of tasks, see Time and Transport.

For tasks involving a technician mid-workflow, see Operator Intervention.

For mid-workflow conditional task execution, see Workflow Branching.

ActionTask

class linq.task.ActionTask(*, id: str = '', description: str = '', dependencies: list[ActionTask | CodeTask | Conditional] = ..., action: str = '', time_estimate: int, instrument_type: str, labware_sources: list[LabwareSource | StoredLabware], labware_outputs: list[LabwareOutput | StoredLabware] = ..., instrument_mappings: list[str] | None = None, available_failure_actions: AvailableFailureActions = ..., skip: bool = False, mock_behaviour: MockBehaviour | None = None, inputs: Inputs = ..., static_arguments: dict[str, Any] | None = None, shared_arguments: dict[str, str] | None = None)

A Task executing an action.

action: str

ID of the action taken (see driver CLI for possible actions for each instrument.)

time_estimate: int

Estimated time to execute the task.

instrument_type: str

Type of the instrument this task runs on.

labware_sources: list[LabwareSource | StoredLabware]

Defines the source of each labware required for this task.

labware_outputs: list[LabwareOutput | StoredLabware]

Outputs of this task. If left empty, defaults to a labware output for each labware source.

instrument_mappings: list[str] | None

Restrict task to run on an instrument from one of these mappings.

available_failure_actions: AvailableFailureActions

Available actions to be taken in case of failure.

skip: bool

Set to true to skip this task.

mock_behaviour: MockBehaviour | None

Overrides for the behaviour of the task on mock drivers

inputs: Inputs

Inputs to be passed to the task. The key is the name of the input. Can be a TaskOutputReference to the output of another task, a ReferenceData to some stored data, or a literal value.

static_arguments: dict[str, Any] | None

Deprecated, use typed ‘inputs’ field instead

shared_arguments: dict[str, str] | None

Deprecated, use typed ‘inputs’ field instead

forward(*, output: int, destination_slot: int | SlotFillingRule = 1, units_consumed: int | None = None, dependencies: list[ActionTask | CodeTask | Conditional] | None = None) LabwareSource
forward(*, labware: Labware | None = None, destination_slot: int | SlotFillingRule = 1, units_consumed: int | None = None, dependencies: list[ActionTask | CodeTask | Conditional] | None = None) LabwareSource

Create a labware source from an output of a previous task.

This can be used to forward previously used labware to another task without having to reference the source task multiple times.

out(output_name: str | None = None) TaskOutputReference

Reference to the output of this task. If the task has only one output, output_name can be left as None.

CodeTask

For tasks involving custom code execution, see Data Manipulation.

Implicit Actions

Sometimes, a task may implement multiple driver actions for a given instrument that frequently occur in sequence. A prototypical example is loading: devices may, for example, require sending of an open_door command, a labware movement into the exposed loading bay, a close_door command, and then a mount command.

While these tasks can be planned individually for specific use cases, for convenience, some task actions, like the load task, will be compiled into the needed series of actions. This is configured on a per-instrument, per-driver basis.

Implicit Transport

It is only necessary to specify the series of instrument tasks in a workflow, e.g. seal centrifuge peel - etc. Transport tasks, the movements of the SCARA arm and the LINQ transport layer, do not need to be explicitly specified; they are derived from labware inputs and outputs.

For more detail on controlling the movement of labware through slots in instruments, see Labware Flow

For detail about estimating the timings of transport from one bench to another for purposes of optimal planning and simulation, see Time and Sequence.