UniteLabs

Autoload Module

A guide on a liquid handler Autoload module.

In this guide the basic deck is extended with a loading tray and the Autoload is used to move carriers on and off the deck. The barcode scanner of the Autoload is used to scan barcodes of the carrier and plate placed on it.

Prerequisites

  • A switched on Hamilton STAR device with the Autoload module
  • A plate carrier with barcode, plate with a barcode
  • A running Hamilton STAR connector
  • Basic understanding of how labware is used (See the using standard labware tutorial)
  • Basic understanding of the liquid handler class (See the liquid handler tutorial)

Power On the System

Ensure that the Hamilton STAR is powered on and ready for operation. Verify that the connector is running and connected to the UniteLabs platform.

from unitelabs.sdk import AsyncApiClient
from unitelabs.liquid_handling.hamilton import MicrolabSTAR

client = AsyncApiClient()

# Initialize the Hamilton Microlab STAR
hamilton = MicrolabSTAR(
  name="Microlab STAR",
  client=client,
)
await hamilton.initialize()

Arrange the Deck

Arrange the deck layout using the components from the labware library. This guide uses

  • a plate carrier with one barcoded standard 96 well microtiter plate.
  • a sample carrier filled with barcoded tubes.

If the liquid handler is outfitted with a loading tray, this loading tray is configured during initialization and extends the regular main deck. The loading tray part of the deck can be accessed through the autoload module.

from unitelabs.labware import Standard96Plate, Vector
from unitelabs.labware.falcon import Standard15mLTube
from unitelabs.labware.hamilton import PLT_CAR_L5MD_A00, SMP_CAR_12_A00

# Sample carrier
sample_carrier = SMP_CAR_12_A00()
sample_carrier.fill(Standard15mLTube())
hamilton.autoload.loading_tray.add(sample_carrier, track=1)

# Plate carrier
plate_carrier = PLT_CAR_L5MD_A00()
plate = Standard96Plate()
plate_carrier[0] = plate
hamilton.autoload.loading_tray.add(plate_carrier, track=7)

Positioning & Movement

Before diving into loading and unloading, the current position of the autoload relative to the tracks is queried.

await hamilton.autoload.current_track()

The autoload carriage can also be moved to a defined track position or moved to safety using the move_to() and the park() method.

await hamilton.autoload.move_to(track=30)
await hamilton.autoload.park()

Loading

The load_carrier() method will drive the autoload carriage to the defined track and move the carrier onto the deck space. The in-built barcode reader can read barcodes of tubes and plates that are placed on the carrier. The following line of code loads the plate carrier and reads the barcodes of all plates placed on it. Passing read_barcode=True scans using the labware's default symbologies.

barcodes = await hamilton.autoload.load_carrier(carrier=plate_carrier, read_barcode=True, is_last=False)

In this example, the carriers are loaded one after another and thus the autoload carriage should remain in position after loading the first carrier. For this, the is_last=False is used. Otherwise, the carriage would return to its parking position after each loading procedure.

The method returns a list of strings with the decoded barcode information. The position in the list corresponds to the position of the labware on the carrier.

The load_carrier() method infers the orientation of the barcode on the labware and will turn the reader into a vertical or horizontal orientation respectively. The following line loads the sample carrier and reads the barcodes in a vertical orientation.

barcodes = await hamilton.autoload.load_carrier(carrier=sample_carrier)

Barcode Types

There is a variety of barcodes in use and in some cases it may be necessary to specify which symbologies the reader should scan for. Pass one or more BarcodeType flags to read_barcode. Because BarcodeType is a Flag enum, multiple symbologies can be combined with the bitwise | operator:

from unitelabs.liquid_handling.hamilton.modules.autoload import BarcodeType

barcodes = await hamilton.autoload.load_carrier(
    carrier=plate_carrier,
    read_barcode=BarcodeType.ISBT | BarcodeType.CODE_128,
)

The read_barcode parameter accepts:

  • True — scan using the carrier's/labware's default symbologies (all 1D types except Code 93).
  • A BarcodeType (or combination) — scan only for the given symbologies.
  • False / None — do not read barcodes.

The following symbologies are supported. 2D symbologies require an instrument with a 2D autoload module (see 2D Barcode Reader below).

1D symbologies2D symbologies
ISBT (ISBT Standard)DATA_MATRIX
CODE_128 (subset B and C)QR_CODE
CODE_39MAXI_CODE
CODABARAZTEC
ITF (Code 2 of 5 Interleaved)PDF_417
UPC_A (UPC A/E)MICRO_PDF_417
EAN_8GS1_DATABAR
CODE_93EAN_UCC_COMP
Passing barcode types as plain integers (e.g. read_barcode=1) is no longer supported starting from liqid-handling version sdk 0.31.0 — use the BarcodeType flags or True.

Unloading

Unloading is performed with the unload_carrier() method. In the following snippet, the last unload method returns the autoload carriage to its home position after completing the unload process using the is_last parameter.

await hamilton.autoload.unload_carrier(carrier=sample_carrier)
await hamilton.autoload.unload_carrier(carrier=plate_carrier, is_last=True)

2D Barcode Reader

Instruments fitted with a 2D autoload module can read 2D symbologies (Data Matrix, QR, etc.) and expose additional controls over the reading region and illumination. When reading a configuration from the instrument, this capability is detected directly, however the user can also explicitly enable the 2D features by configuring the autoload with two_d=True:

await hamilton.autoload.configure(two_d=True)

All 2D-only methods raise a ModuleError if the autoload was not configured as a 2D reader.

Region of Interest & Illumination

When loading a carrier on a 2D reader, you can constrain the scan to a Region of Interest (ROI) and override the illumination. Passing either roi or illumination automatically enables the free-definable grid and requires a 2D reader.

barcodes = await hamilton.autoload.load_carrier(
    carrier=plate_carrier,
    read_barcode=BarcodeType.DATA_MATRIX,
    # ROI in mm: (YR0, ZR, ΔYR, ΔZR)
    roi=(0.0, 0.0, 20.0, 10.0),
    # 7 illumination values: internal 1-4, external on, gain, exposure time
    illumination=(0, 0, 0, 0, 1, 5, 100),
)

Free Definable Carrier

For non-standard carriers, the reading position, ROI, direction and illumination can be defined per labware position. Configure each position, then reset when done.

await hamilton.autoload.set_free_definable_carrier(
    position=1,            # labware position (0 is reserved for the carrier ID)
    reading_position=12.5, # code reading position in mm
    roi=(0.0, 0.0, 20.0, 10.0),
    direction=2,           # 0=vertical, 1=horizontal, 2=free orientation
    illumination=(0, 0, 0, 0, 1, 5, 100),
)

# Reset all free definable carrier settings
await hamilton.autoload.reset_free_definable_carrier()

Reading Codes by Position

After a load_carrier() call, individual codes and their lengths can be queried by labware position:

# Barcode at a specific position (0 = carrier ID, 1 = first labware position)
code = await hamilton.autoload.request_code_by_position(position=1)

# Code lengths for all positions from the last load (0 = unread or > 255 chars)
lengths = await hamilton.autoload.request_code_lengths()

Selected Low-level Methods

More useful methods can be accessed through the low-level api using hamilton.autoload.api. These methods only check basic parameter constraint and not any logical or collision-related constraints. The can be invoked as follows:

await hamilton.autoload.api.get_deck_presences()

Useful low-level methods include, among others:

  • get_deck_presences()
    Check the presence of carriers on the deck without movement. Presence sensors can only check the highest track number that is occupied by the carrier, not its width.
  • get_loading_tray_presences()
    Check the presence of carriers on the loading tray by moving along the tracks. Presence sensors can only check the highest track number that is occupied by the carrier, not its width.
  • get_carrier_presence(track)
    Check the presence of a single carrier on the loading tray by moving to the specified tracks.
  • set_loading_indicators(status)
    Set the loading indicators (LED's) of the autoload unit.
  • get_module_type()
    Request the installed autoload module type ("Microlab STAR", "Microlab STAR 2D", "XRP Lite", or None).