{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# PlateCarrier\n", "\n", "Plate carriers slide into rails on railed-decks like Hamilton STAR(let) and Tecan EVO, and are used to hold Plates." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Using a plate carrier\n", "\n", "The PyLabRobot Resource Library (PLR-RL) has a big number of predefined carriers. You can find these in the [PLR-RL docs](https://docs.pylabrobot.org/resources/index.html). [Hamilton Plate Carriers](https://docs.pylabrobot.org/resources/library/ml_star.html#plate-carriers) may be of particular interest." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from pylabrobot.resources.hamilton import PLT_CAR_L5AC_A00" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_plate_carrier = PLT_CAR_L5AC_A00(name=\"my_plate_carrier\")\n", "my_plate_carrier.capacity" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To assign a plate at a specific location in the plate carrier, simply set it at a specific index. In PLR, carriers are 0-indexed where the site at the front of the robot (nearest to the door) is 0." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from pylabrobot.resources import Cor_96_wellplate_360ul_Fb\n", "\n", "my_plate = Cor_96_wellplate_360ul_Fb(name=\"my_plate\")\n", "my_plate_carrier[0] = my_plate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can assign plates to a variable and to the carrier in a single line." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "my_plate_carrier[1] = my_other_plate = Cor_96_wellplate_360ul_Fb(name=\"my_other_plate\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The children (in the arborescence) of a plate carrier are {class}`pylabrobot.resources.carrier.PlateHolder` objects. These model the sites for plates on the carrier. A `PlateHolder` may or may not have a `Plate` as a child, depending on whether the spot is occupied." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PlateHolder(name=my_plate_carrier-0, location=Coordinate(004.000, 008.500, 086.150), size_x=127.0, size_y=86.0, size_z=0, category=plate_holder)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_plate_carrier[0]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PlateHolder(name=my_plate_carrier-0, location=Coordinate(004.000, 008.500, 086.150), size_x=127.0, size_y=86.0, size_z=0, category=plate_holder)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_plate.parent" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use the `PlateHolder.resource` attribute to access the `Plate` object, if it exists." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Plate(name=my_plate, size_x=127.76, size_y=85.48, size_z=14.2, location=Coordinate(000.000, 000.000, -03.030))" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_plate_carrier[0].resource" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_plate_carrier[2].resource is None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Moving plates onto carrier sites\n", "\n", "If your liquid handling robot has a robotic arm, or if you are using an external robot arm that can interface with carriers, you can move plates out of or onto carriers using the `move_plate` method. For this, you can specify the destination by indexing into the carrier. This will return a `PlateHolder` object.\n", "\n", "As an example, we will use the LiquidHandlerChatterboxBackend, but this code will work on any robot that supports moving plates." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Resource my_plate_carrier was assigned to the liquid handler.\n", "Setting up the liquid handler.\n", "Resource deck was assigned to the liquid handler.\n", "Resource trash was assigned to the liquid handler.\n", "Resource trash_core96 was assigned to the liquid handler.\n", "Resource teaching_carrier was assigned to the liquid handler.\n", "Resource my_plate_carrier was assigned to the liquid handler.\n" ] } ], "source": [ "from pylabrobot.liquid_handling import LiquidHandler, LiquidHandlerChatterboxBackend\n", "from pylabrobot.resources import STARDeck\n", "lh = LiquidHandler(backend=LiquidHandlerChatterboxBackend(), deck=STARDeck())\n", "lh.deck.assign_child_resource(my_plate_carrier, rails=1)\n", "await lh.setup()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Picking up resource: ResourcePickup(resource=Plate(name=my_plate, size_x=127.76, size_y=85.48, size_z=14.2, location=Coordinate(000.000, 000.000, -03.030)), offset=Coordinate(x=0, y=0, z=0), pickup_distance_from_top=0, direction=)\n", "Dropping resource: ResourceDrop(resource=Plate(name=my_plate, size_x=127.76, size_y=85.48, size_z=14.2, location=Coordinate(000.000, 000.000, -03.030)), destination=Coordinate(x=104.0, y=263.5, z=183.12), destination_absolute_rotation=Rotation(x=0, y=0, z=0), offset=Coordinate(x=0, y=0, z=0), pickup_distance_from_top=0, pickup_direction=, drop_direction=, rotation=0)\n", "Resource my_plate was unassigned from the liquid handler.\n", "Resource my_plate was assigned to the liquid handler.\n" ] } ], "source": [ "await lh.move_resource(my_plate, my_plate_carrier[2])" ] } ], "metadata": { "kernelspec": { "display_name": "env", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.15" } }, "nbformat": 4, "nbformat_minor": 2 }