Skip to content

Commit a1df799

Browse files
authored
docs: add ResourceHolder tutorial (#568)
1 parent 401c0be commit a1df799

File tree

2 files changed

+167
-12
lines changed

2 files changed

+167
-12
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "1fabc0d7",
6+
"metadata": {},
7+
"source": [
8+
"# ResourceHolder\n",
9+
"\n",
10+
"`ResourceHolder` is a mixin class for resources that can hold exactly one other\n",
11+
"resource. Examples include the sites of plate carriers which hold a single\n",
12+
"plate, or the docking position of a module that accepts one plate or trough.\n",
13+
"\n",
14+
"`ResourceHolder` ensures that the child resource is placed correctly inside the\n",
15+
"holder. When the holder is rotated the child resource is automatically shifted\n",
16+
"so that its local origin lines up with the correct corner of the holder. This\n",
17+
"avoids having to manually adjust coordinates for every rotation."
18+
]
19+
},
20+
{
21+
"cell_type": "markdown",
22+
"id": "c71e1e1b",
23+
"metadata": {},
24+
"source": [
25+
"## Why use a ResourceHolder?\n",
26+
"\n",
27+
"Many pieces of labware are designed to accommodate another resource at a\n",
28+
"fixed position. A `PlateHolder` inside a carrier for example always contains\n",
29+
"exactly one plate. The `ResourceHolder` abstraction models this behaviour.\n",
30+
"It guarantees that only one resource is assigned at a time and exposes\n",
31+
"convenient methods to work with the contained resource.\n",
32+
"\n",
33+
"By subclassing from `ResourceHolder` your own holder classes immediately gain\n",
34+
"these behaviours without duplicating logic."
35+
]
36+
},
37+
{
38+
"cell_type": "markdown",
39+
"id": "9e89a6c0",
40+
"metadata": {},
41+
"source": [
42+
"## Basic usage"
43+
]
44+
},
45+
{
46+
"cell_type": "code",
47+
"execution_count": null,
48+
"id": "2a758652",
49+
"metadata": {},
50+
"outputs": [],
51+
"source": [
52+
"from pylabrobot.resources import Resource, ResourceHolder\n",
53+
"\n",
54+
"holder = ResourceHolder(name=\"holder\", size_x=100, size_y=80, size_z=10)\n",
55+
"plate = Resource(name=\"plate\", size_x=100, size_y=80, size_z=15)\n",
56+
"\n",
57+
"holder.assign_child_resource(plate)\n",
58+
"holder.resource.name"
59+
]
60+
},
61+
{
62+
"cell_type": "markdown",
63+
"id": "73233494",
64+
"metadata": {},
65+
"source": [
66+
"After assignment the `resource` property returns the held item."
67+
]
68+
},
69+
{
70+
"cell_type": "code",
71+
"execution_count": null,
72+
"id": "4ae35102",
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"holder.resource is plate"
77+
]
78+
},
79+
{
80+
"cell_type": "markdown",
81+
"id": "fbde07d7",
82+
"metadata": {},
83+
"source": [
84+
"## Custom child location\n",
85+
"\n",
86+
"By default the child is positioned at the holder's origin. You can offset this\n",
87+
"by passing ``child_location`` when constructing the holder."
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": null,
93+
"id": "34a1b2b4",
94+
"metadata": {},
95+
"outputs": [],
96+
"source": [
97+
"from pylabrobot.resources import Coordinate\n",
98+
"\n",
99+
"offset_holder = ResourceHolder(\n",
100+
" name=\"offset_holder\",\n",
101+
" size_x=100,\n",
102+
" size_y=80,\n",
103+
" size_z=10,\n",
104+
" child_location=Coordinate(x=10, y=5, z=0),\n",
105+
")\n",
106+
"lid = Resource(name=\"lid\", size_x=95, size_y=75, size_z=5)\n",
107+
"offset_holder.assign_child_resource(lid)\n",
108+
"offset_holder.resource.location"
109+
]
110+
},
111+
{
112+
"cell_type": "markdown",
113+
"id": "6c54c505",
114+
"metadata": {},
115+
"source": [
116+
"## Reassigning\n",
117+
"\n",
118+
"To replace the current child, call ``assign_child_resource`` again. The previous\n",
119+
"child will be unassigned automatically."
120+
]
121+
},
122+
{
123+
"cell_type": "code",
124+
"execution_count": null,
125+
"id": "db3b133e",
126+
"metadata": {},
127+
"outputs": [],
128+
"source": [
129+
"replacement = Resource(name=\"replacement\", size_x=100, size_y=80, size_z=15)\n",
130+
"offset_holder.assign_child_resource(replacement)\n",
131+
"offset_holder.resource.name"
132+
]
133+
},
134+
{
135+
"cell_type": "markdown",
136+
"id": "eb813c6a",
137+
"metadata": {},
138+
"source": [
139+
"Attempting to assign another resource without allowing reassignment raises an\n",
140+
"error."
141+
]
142+
},
143+
{
144+
"cell_type": "code",
145+
"execution_count": null,
146+
"id": "ece40649",
147+
"metadata": {},
148+
"outputs": [],
149+
"source": [
150+
"try:\n",
151+
" holder.assign_child_resource(Resource(\"extra\", 10, 10, 10), reassign=False)\n",
152+
"except ValueError as e:\n",
153+
" error_message = str(e)\n",
154+
"error_message"
155+
]
156+
}
157+
],
158+
"metadata": {
159+
"kernelspec": {
160+
"display_name": "env",
161+
"language": "python",
162+
"name": "python3"
163+
}
164+
},
165+
"nbformat": 4,
166+
"nbformat_minor": 5
167+
}

docs/resources/resource-holder/resource-holder.rst

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)