Moving a plate onto an Alpaqua magnet using CO-RE grippers#

  • tags: #resourcemovement #plateadapter #hamiltonstar

Prerequisites#

  • Devices used:

    • Hamilton STARlet (on a STAR, build the device with STAR instead of STARlet)

  • Non-PLR dependencies: None

Preview of Device Behaviour#

Protocol Mode#

SIMULATION = True  # False to drive a real STARlet

Import Statements#

Non-PLR Dependencies#

None

Device & Visualizer#

import asyncio
import random

from pylabrobot.hamilton.star import STARlet
from pylabrobot.visualizer3D import Viewer3D

Required Resources#

from pylabrobot.resources import (
  hamilton_mfx_carrier_L5_base,
  hamilton_mfx_plateholder_DWP_metal_tapped,
  hamilton_mfx_plateholder_DWP_flat,
  alpaqua_96_plateadapter_magnum_flx,
  azenta_96_wellplate_200uL_Vb_4titudeframestar,
)

Note: if you’re unsure whether you have the resources mentioned in a PLR automated protocol, use Python’s built-in help function to check out the resource definition’s docstring - they always contain the manufacturer’s catalogue/part number (and if available a direct link to the product page):

help(hamilton_mfx_plateholder_DWP_metal_tapped) # for more information visit the docs 'Resource Management' section

Instantiate Device & Connect#

star = STARlet(simulation=SIMULATION)
await star.setup()
deck = star.deck

viewer = Viewer3D(star, name="alpaqua_magnet_recipe")
await viewer.start()
if SIMULATION:
  await viewer.wait_for_browser()  # a simulated run is over in milliseconds: watch it from the start

Configure Deck Layout#

# Setup MFX Carrier for Magnetic Bead Resuspension

mfx_plateholder_dwp_0 = hamilton_mfx_plateholder_DWP_metal_tapped(
    name="mfx_plateholder_dwp_tapped_dwp_0"
)

mfx_carrier_tapped_plate_holder_example = hamilton_mfx_carrier_L5_base(
  name="mfx_carrier_tapped_plate_holder_example",
  modules={
    0: mfx_plateholder_dwp_0,
  }
)

mfx_carrier_tapped_plate_holder_example[0] = azenta_96_wellplate_200uL_Vb_4titudeframestar(
  name="wash_plate_0"
)

deck.assign_child_resource(mfx_carrier_tapped_plate_holder_example, track=1)

# Setup Magnet-carrying MFX Carrier

plateholder_flat_0 = hamilton_mfx_plateholder_DWP_flat(name="plateholder_flat_0")
magnet_0 = alpaqua_96_plateadapter_magnum_flx(name="alpaqua_magnet_0")
plateholder_flat_0.assign_child_resource(magnet_0)

mfx_carrier_magnet_example = hamilton_mfx_carrier_L5_base(
  name="mfx_carrier_magnet_example",
  modules={
    0: plateholder_flat_0,
  }
)
magnet_0.plate_z_offset = 0.62  # <===== PLATE-SPECIFIC !
# measure for your plate: from the magnet's hole bottom to the cavity_bottom of the well on it
# (e.g. by z-touch probing both)

deck.assign_child_resource(mfx_carrier_magnet_example, track=8)

Execution#

Move Plate Onto Magnet PlateAdapter#

plate_index = 0 # always design for throughput adaptiveness ;)

plate_to_move = deck.get_resource(f"wash_plate_{plate_index}")
move_target = deck.get_resource(f"alpaqua_magnet_{plate_index}")

# Reduce wear & tear on any single channel: the tools ride front_channel - 1 and front_channel
front_channel = random.randint(1, star.pipettes.num_channels - 1)

if SIMULATION:
  await asyncio.sleep(2)

await star.core_grippers.pick_up_tools(front_channel=front_channel)
await star.core_grippers.pick_up_resource(
  plate_to_move,
  pickup_distance_from_top=6,
  grip_strength=40,
)
await star.core_grippers.place_resource(move_target)

if not SIMULATION:
  # "smart" command, will ask operator for input if it cannot find plate in move_target location
  # (1) check transfer success, (2) push plate flush
  await star.core_grippers.probe_resource_exists_using_ztouch(
    location=plate_to_move.get_location_wrt(deck),
    resource=plate_to_move,
    gripper_y_margin=9,
    enable_recovery=True,
  )

print(star.core_grippers.tools_mounted)
# >>> True # save time - keep CO-RE grippers on channels during magnetisation time

if SIMULATION:
  await asyncio.sleep(2)

Move Plate back onto tapped PlateHolder#

move_target = deck.get_resource(f"mfx_plateholder_dwp_tapped_dwp_{plate_index}")

await star.core_grippers.pick_up_resource(
  plate_to_move,
  pickup_distance_from_top=6,
  grip_strength=40,
)
await star.core_grippers.place_resource(move_target)

if not SIMULATION:
  await star.core_grippers.probe_resource_exists_using_ztouch(
    location=plate_to_move.get_location_wrt(deck),
    resource=plate_to_move,
    gripper_y_margin=9,
    enable_recovery=True,
  )

await star.core_grippers.return_tools()

print(star.core_grippers.tools_mounted)
# >>> False

Disconnect#

await viewer.stop()
await star.stop()