{ "cells": [ { "cell_type": "markdown", "id": "1fabc0d7", "metadata": {}, "source": [ "# ResourceHolder\n", "\n", "`ResourceHolder` is a mixin class for resources that can hold exactly one other\n", "resource. Examples include the sites of plate carriers which hold a single\n", "plate, or the docking position of a module that accepts one plate or trough.\n", "\n", "`ResourceHolder` ensures that the child resource is placed correctly inside the\n", "holder. When the holder is rotated the child resource is automatically shifted\n", "so that its local origin lines up with the correct corner of the holder. This\n", "avoids having to manually adjust coordinates for every rotation." ] }, { "cell_type": "markdown", "id": "c71e1e1b", "metadata": {}, "source": [ "## Why use a ResourceHolder?\n", "\n", "Many pieces of labware are designed to accommodate another resource at a\n", "fixed position. A `PlateHolder` inside a carrier for example always contains\n", "exactly one plate. The `ResourceHolder` abstraction models this behaviour.\n", "It guarantees that only one resource is assigned at a time and exposes\n", "convenient methods to work with the contained resource.\n", "\n", "By subclassing from `ResourceHolder` your own holder classes immediately gain\n", "these behaviours without duplicating logic." ] }, { "cell_type": "markdown", "id": "9e89a6c0", "metadata": {}, "source": [ "## Basic usage" ] }, { "cell_type": "code", "execution_count": null, "id": "2a758652", "metadata": {}, "outputs": [], "source": [ "from pylabrobot.resources import Resource, ResourceHolder\n", "\n", "holder = ResourceHolder(name=\"holder\", size_x=100, size_y=80, size_z=10)\n", "plate = Resource(name=\"plate\", size_x=100, size_y=80, size_z=15)\n", "\n", "holder.assign_child_resource(plate)\n", "holder.resource.name" ] }, { "cell_type": "markdown", "id": "73233494", "metadata": {}, "source": [ "After assignment the `resource` property returns the held item." ] }, { "cell_type": "code", "execution_count": null, "id": "4ae35102", "metadata": {}, "outputs": [], "source": [ "holder.resource is plate" ] }, { "cell_type": "markdown", "id": "fbde07d7", "metadata": {}, "source": [ "## Custom child location\n", "\n", "By default the child is positioned at the holder's origin. You can offset this\n", "by passing ``child_location`` when constructing the holder." ] }, { "cell_type": "code", "execution_count": null, "id": "34a1b2b4", "metadata": {}, "outputs": [], "source": [ "from pylabrobot.resources import Coordinate\n", "\n", "offset_holder = ResourceHolder(\n", " name=\"offset_holder\",\n", " size_x=100,\n", " size_y=80,\n", " size_z=10,\n", " child_location=Coordinate(x=10, y=5, z=0),\n", ")\n", "lid = Resource(name=\"lid\", size_x=95, size_y=75, size_z=5)\n", "offset_holder.assign_child_resource(lid)\n", "offset_holder.resource.location" ] } ], "metadata": { "kernelspec": { "display_name": "env", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }