Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions docs/api/pylabrobot.hamilton.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,73 @@ STAR Liquid Handler

.. autoclass:: pylabrobot.hamilton.liquid_handlers.star.iswap.iSWAPBackend.MoveToLocationParams
:members:


Vantage Liquid Handler
----------------------

.. currentmodule:: pylabrobot.hamilton.liquid_handlers.vantage

.. autosummary::
:toctree: _autosummary
:nosignatures:
:recursive:

Vantage

.. currentmodule:: pylabrobot.hamilton.liquid_handlers.vantage.pip_backend

.. autosummary::
:toctree: _autosummary
:nosignatures:
:recursive:

VantagePIPBackend

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.pip_backend.VantagePIPBackend.PickUpTipsParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.pip_backend.VantagePIPBackend.DropTipsParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.pip_backend.VantagePIPBackend.AspirateParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.pip_backend.VantagePIPBackend.DispenseParams
:members:

.. currentmodule:: pylabrobot.hamilton.liquid_handlers.vantage.head96_backend

.. autosummary::
:toctree: _autosummary
:nosignatures:
:recursive:

VantageHead96Backend

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.head96_backend.VantageHead96Backend.PickUpTipsParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.head96_backend.VantageHead96Backend.DropTipsParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.head96_backend.VantageHead96Backend.AspirateParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.head96_backend.VantageHead96Backend.DispenseParams
:members:

.. currentmodule:: pylabrobot.hamilton.liquid_handlers.vantage.ipg

.. autosummary::
:toctree: _autosummary
:nosignatures:
:recursive:

IPGBackend

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.ipg.IPGBackend.PickUpParams
:members:

.. autoclass:: pylabrobot.hamilton.liquid_handlers.vantage.ipg.IPGBackend.DropParams
:members:
1 change: 1 addition & 0 deletions docs/user_guide/hamilton/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
:maxdepth: 1

star/index
vantage/index
heater_cooler/hello-world
heater_shaker/hello-world
hepa_fan/hello-world
Expand Down
308 changes: 308 additions & 0 deletions docs/user_guide/hamilton/vantage/hello-world.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "vantage-intro-001",
"metadata": {},
"source": [
"# Hamilton Vantage\n",
"\n",
"The Hamilton Vantage is a liquid handler with independent pipetting channels, an optional 96-head, and an optional Integrated Plate Gripper (IPG). This notebook walks through the `Vantage` device API, covering setup, deck layout, tip pickup, aspiration and dispensing, IPG plate transport, and teardown.\n",
"\n",
"**Prerequisites:**\n",
"\n",
"- Installed PyLabRobot with USB support: `pip install pylabrobot[usb]`\n",
"- Platform-specific driver setup (libusb on Mac, Zadig on Windows) — see [the installation guide](../../_getting-started/installation)\n",
"- Connected the Vantage to your computer using the USB cable\n",
"\n",
"All commands in this notebook are sent to a chatterbox driver that logs firmware strings to the console without touching real hardware. Remove `chatterbox=True` and supply a real USB address to run on an actual instrument."
]
},
{
"cell_type": "markdown",
"id": "vantage-setup-heading",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"Import {class}`~pylabrobot.hamilton.liquid_handlers.vantage.vantage.Vantage` and {class}`~pylabrobot.resources.hamilton.vantage_decks.VantageDeck`. `Vantage` is the device class that owns the driver and exposes capabilities: `vantage.pip` (independent channels), `vantage.head96` (96-head, if installed), and `vantage.ipg` (plate gripper arm, if installed).\n",
"\n",
"`VantageDeck` requires a `size` parameter. The standard 1.3 m configuration is used here."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-setup-code",
"metadata": {},
"outputs": [],
"source": [
"from pylabrobot.hamilton.liquid_handlers.vantage import Vantage\n",
"from pylabrobot.resources.hamilton import VantageDeck\n",
"\n",
"deck = VantageDeck(size=1.3)\n",
"vantage = Vantage(deck=deck, chatterbox=True)"
]
},
{
"cell_type": "markdown",
"id": "vantage-setup-call-note",
"metadata": {},
"source": [
"Call {meth}`~pylabrobot.hamilton.liquid_handlers.vantage.vantage.Vantage.setup` to initialise the driver and wire up the PIP, Head96, and IPG capability frontends."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-setup-run",
"metadata": {},
"outputs": [],
"source": [
"await vantage.setup()\n",
"\n",
"print(f\"pip channels : {vantage.pip.num_channels}\")\n",
"print(f\"head96 present: {vantage.head96 is not None}\")\n",
"print(f\"ipg present : {vantage.ipg is not None}\")"
]
},
{
"cell_type": "markdown",
"id": "vantage-deck-heading",
"metadata": {},
"source": [
"## Creating the deck layout\n",
"\n",
"Define the physical deck layout by assigning carriers with tip racks and plates. This tutorial uses:\n",
"\n",
"- {class}`~pylabrobot.resources.hamilton.tip_carriers.TIP_CAR_480_A00` tip carrier\n",
"- {class}`~pylabrobot.resources.hamilton.plate_carriers.PLT_CAR_L5AC_A00` plate carrier\n",
"- {class}`~pylabrobot.resources.corning.plates.Cor_96_wellplate_360ul_Fb` 96-well plate\n",
"- {class}`~pylabrobot.resources.hamilton.tip_racks.hamilton_96_tiprack_1000uL_filter` tip rack"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-deck-code",
"metadata": {},
"outputs": [],
"source": [
"from pylabrobot.resources import (\n",
" Cor_96_wellplate_360ul_Fb,\n",
" PLT_CAR_L5AC_A00,\n",
" TIP_CAR_480_A00,\n",
" hamilton_96_tiprack_1000uL_filter,\n",
")\n",
"\n",
"tip_car = TIP_CAR_480_A00(name=\"tip_carrier\")\n",
"tip_car[0] = hamilton_96_tiprack_1000uL_filter(name=\"tips_01\")\n",
"tip_car[1] = hamilton_96_tiprack_1000uL_filter(name=\"tips_02\")\n",
"deck.assign_child_resource(tip_car, rails=3)\n",
"\n",
"plt_car = PLT_CAR_L5AC_A00(name=\"plate_carrier\")\n",
"plt_car[0] = Cor_96_wellplate_360ul_Fb(name=\"plate_01\")\n",
"plt_car[1] = Cor_96_wellplate_360ul_Fb(name=\"plate_02\")\n",
"deck.assign_child_resource(plt_car, rails=15)"
]
},
{
"cell_type": "markdown",
"id": "vantage-deck-summary-note",
"metadata": {},
"source": [
"Inspect the deck layout using {meth}`~pylabrobot.resources.deck.Deck.summary`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-deck-summary",
"metadata": {},
"outputs": [],
"source": [
"deck.summary()"
]
},
{
"cell_type": "markdown",
"id": "vantage-pip-heading",
"metadata": {},
"source": [
"## Picking up tips\n",
"\n",
"`vantage.pip` is a {class}`~pylabrobot.capabilities.liquid_handling.pip.PIP` capability frontend. Its API is identical to `star.pip` on the STAR. Indexing a tip rack with `[\"A1:C1\"]` returns the first three tip spots in column 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-pickup-tips",
"metadata": {},
"outputs": [],
"source": [
"tiprack = deck.get_resource(\"tips_01\")\n",
"await vantage.pip.pick_up_tips(tiprack[\"A1:C1\"])"
]
},
{
"cell_type": "markdown",
"id": "vantage-aspirate-heading",
"metadata": {},
"source": [
"## Aspirating and dispensing\n",
"\n",
"Aspirate from wells `A1:C1` of the source plate and dispense into `A1:C1` of the destination plate, using channels 0, 1, and 2."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-aspirate",
"metadata": {},
"outputs": [],
"source": [
"src = deck.get_resource(\"plate_01\")\n",
"dst = deck.get_resource(\"plate_02\")\n",
"\n",
"await vantage.pip.aspirate(src[\"A1:C1\"], vols=[100.0, 50.0, 200.0])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-dispense",
"metadata": {},
"outputs": [],
"source": [
"await vantage.pip.dispense(dst[\"A1:C1\"], vols=[100.0, 50.0, 200.0])"
]
},
{
"cell_type": "markdown",
"id": "vantage-move-back-note",
"metadata": {},
"source": [
"Move the liquid back to the source plate:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-move-back",
"metadata": {},
"outputs": [],
"source": [
"await vantage.pip.aspirate(dst[\"A1:C1\"], vols=[100.0, 50.0, 200.0])\n",
"await vantage.pip.dispense(src[\"A1:C1\"], vols=[100.0, 50.0, 200.0])"
]
},
{
"cell_type": "markdown",
"id": "vantage-drop-tips-heading",
"metadata": {},
"source": [
"## Dropping tips\n",
"\n",
"Return tips to their original positions:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-drop-tips",
"metadata": {},
"outputs": [],
"source": [
"await vantage.pip.drop_tips(tiprack[\"A1:C1\"])"
]
},
{
"cell_type": "markdown",
"id": "vantage-backend-params-heading",
"metadata": {},
"source": "## Backend parameters\n\nFor Vantage-specific tuning, pass `backend_params` to any PIP operation. The available parameter dataclasses live on `VantagePIPBackend` in `pylabrobot.hamilton.liquid_handlers.vantage.pip_backend`. For example, to aspirate with capacitive liquid level detection (cLLD, `lld_mode=1`) enabled on two channels:"
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-backend-params-code",
"metadata": {},
"outputs": [],
"source": "from pylabrobot.hamilton.liquid_handlers.vantage.pip_backend import VantagePIPBackend\n\ntiprack2 = deck.get_resource(\"tips_02\")\nawait vantage.pip.pick_up_tips(tiprack2[\"A1:B1\"])\n\nawait vantage.pip.aspirate(\n src[\"A1:B1\"],\n vols=[100.0, 100.0],\n backend_params=VantagePIPBackend.AspirateParams(\n lld_mode=[1, 1], # 1 = cLLD (capacitive liquid level detection)\n ),\n)\n\nawait vantage.pip.dispense(dst[\"A1:B1\"], vols=[100.0, 100.0])\nawait vantage.pip.drop_tips(tiprack2[\"A1:B1\"])"
},
{
"cell_type": "markdown",
"id": "vantage-ipg-heading",
"metadata": {},
"source": [
"## IPG: Integrated Plate Gripper\n",
"\n",
"`vantage.ipg` is an {class}`~pylabrobot.capabilities.arms.orientable_arm.OrientableArm` capability frontend backed by {class}`~pylabrobot.hamilton.liquid_handlers.vantage.ipg.IPGBackend`. It is `None` if the IPG is not installed on this configuration. The chatterbox driver always provides one.\n",
"\n",
"Use {meth}`~pylabrobot.capabilities.arms.orientable_arm.OrientableArm.move_resource` to pick up a plate from one carrier slot and place it in another. Pass `pickup_backend_params` and `drop_backend_params` to override IPG-specific firmware parameters.\n",
"\n",
"```{note}\n",
"`press_on_distance` on `IPGBackend.DropParams` is accepted for API compatibility but is not forwarded to the firmware: the `zi` parameter on the A1RM:DR command is uncharacterised on real hardware and has been left unsent until it can be verified safe.\n",
"```\n",
"\n",
"```{warning}\n",
"`vantage.ipg.halt()`, `vantage.ipg.close_gripper()`, `vantage.ipg.is_gripper_closed()`, and `vantage.ipg.request_gripper_location()` raise `NotImplementedError` — they have not yet been ported from the legacy backend. Do not rely on `halt()` for emergency stop.\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-ipg-code",
"metadata": {},
"outputs": [],
"source": [
"if vantage.ipg is not None:\n",
" plate = deck.get_resource(\"plate_01\")\n",
" destination_slot = plt_car[2] # empty slot 2\n",
"\n",
" await vantage.ipg.move_resource(\n",
" resource=plate,\n",
" to=destination_slot,\n",
" pickup_distance_from_top=13.2,\n",
" )\n",
"else:\n",
" print(\"IPG not present on this configuration — skipping.\")"
]
},
{
"cell_type": "markdown",
"id": "vantage-teardown-heading",
"metadata": {},
"source": [
"## Teardown\n",
"\n",
"Call {meth}`~pylabrobot.hamilton.liquid_handlers.vantage.vantage.Vantage.stop` to stop all capability frontends in reverse order and close the driver connection."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "vantage-stop",
"metadata": {},
"outputs": [],
"source": [
"await vantage.stop()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.11.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
7 changes: 7 additions & 0 deletions docs/user_guide/hamilton/vantage/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Hamilton Vantage

```{toctree}
:maxdepth: 1

hello-world
```
Loading
Loading