Skip to content

Commit 77843d9

Browse files
authored
remove z_travel from tecan resources (#553)
1 parent a9f2261 commit 77843d9

File tree

6 files changed

+43
-122
lines changed

6 files changed

+43
-122
lines changed

pylabrobot/liquid_handling/backends/tecan/EVO_backend.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ def __init__(
212212
self._pnp_connected: Optional[bool] = None
213213
self._mca_connected: Optional[bool] = None
214214

215+
self._z_traversal_height = 210 # mm, the default value for SHZ command
216+
self._z_roma_traversal_height = (
217+
68.7 # mm, is what was used to develop this but possibly too low
218+
)
219+
215220
@property
216221
def num_channels(self) -> int:
217222
"""The number of pipette channels present on the robot."""
@@ -412,7 +417,7 @@ async def aspirate(
412417
await self.liha.set_search_z_start(z_positions["start"])
413418
await self.liha.set_search_z_max(list(z if z else self._z_range for z in z_positions["max"]))
414419
await self.liha.set_search_submerge(sbl)
415-
shz = [min(z for z in z_positions["travel"] if z)] * self.num_channels
420+
shz = [min(z for z in z_positions["travel"] if z)] * self.num_channels # TODO: max?
416421
await self.liha.set_z_travel_height(shz)
417422
await self.liha.move_detect_liquid(self._bin_use_channels(use_channels), zadd)
418423
await self.liha.set_z_travel_height([self._z_range] * self.num_channels)
@@ -686,9 +691,9 @@ def get_z_position(z, z_off, tip_length):
686691
raise ValueError(f"Operation is not supported by resource {par}.")
687692
# TODO: calculate defaults when z-attribs are not specified
688693
tip_length = int(ops[i].tip.total_tip_length * 10)
689-
z_positions["travel"][channel] = get_z_position(
690-
par.z_travel, par.get_absolute_location().z + op.offset.z, tip_length
691-
)
694+
# z travel seems to only be used for aspiration and dispense right now
695+
if isinstance(op, (SingleChannelAspiration, SingleChannelDispense)):
696+
z_positions["travel"][channel] = round(self._z_traversal_height * 10)
692697
z_positions["start"][channel] = get_z_position(
693698
par.z_start, par.get_absolute_location().z + op.offset.z, tip_length
694699
)
@@ -850,27 +855,28 @@ def _roma_positions(
850855
) -> Tuple[int, int, Dict[str, int]]:
851856
"""Creates x, y, and z positions used by RoMa ops."""
852857

853-
par = resource.parent
854-
if par is None:
858+
parent = resource.parent # PlateHolder
859+
if parent is None:
855860
raise ValueError(f"Operation is not supported by resource {resource}.")
856-
par = par.parent
857-
if not isinstance(par, TecanPlateCarrier):
858-
raise ValueError(f"Operation is not supported by resource {par}.")
861+
parent = parent.parent # PlateCarrier
862+
# TODO: this is probably the current plate carrier, not the destination.
863+
# Also, we should just support any coordinate as the destination.
864+
if not isinstance(parent, TecanPlateCarrier):
865+
raise ValueError(f"Operation is not supported by resource {parent}.")
859866

860867
if (
861-
par.roma_x is None
862-
or par.roma_y is None
863-
or par.roma_z_safe is None
864-
or par.roma_z_travel is None
865-
or par.roma_z_end is None
868+
parent.roma_x is None
869+
or parent.roma_y is None
870+
or parent.roma_z_safe is None
871+
or parent.roma_z_end is None
866872
):
867-
raise ValueError(f"Operation is not supported by resource {par}.")
868-
x_position = int((offset.x - 100) * 10 + par.roma_x)
869-
y_position = int((347.1 - (offset.y + resource.get_absolute_size_y())) * 10 + par.roma_y)
873+
raise ValueError(f"Operation is not supported by resource {parent}.")
874+
x_position = int((offset.x - 100) * 10 + parent.roma_x)
875+
y_position = int((347.1 - (offset.y + resource.get_absolute_size_y())) * 10 + parent.roma_y)
870876
z_positions = {
871-
"safe": z_range - int(par.roma_z_safe),
872-
"travel": z_range - int(par.roma_z_travel - offset.z * 10),
873-
"end": z_range - int(par.roma_z_end - offset.z * 10),
877+
"safe": z_range - int(parent.roma_z_safe),
878+
"travel": int(self._z_roma_traversal_height * 10),
879+
"end": z_range - int(parent.roma_z_end - offset.z * 10),
874880
}
875881

876882
return x_position, y_position, z_positions
@@ -933,8 +939,20 @@ async def initialize_plunger(self, tips):
933939
async def report_z_param(self, param: int) -> List[int]:
934940
"""Report current parameters for z-axis.
935941
936-
Args:
937-
param: 0 - current position, 5 - actual machine range
942+
Param:
943+
0 Report current position in 1/10 mm.
944+
1 Report acceleration in 1/10 mm/s².
945+
2 Report fast speed in 1/10 mm/s.
946+
3 Report initialization speed in 1/10 mm.
947+
4 Report initialization offset in 1/10 mm.
948+
5 Report actual machine range in 1/10 mm.
949+
6 Report deviation in encoder increments.
950+
7 Report every time 0.
951+
8 Report scale adjust factor.
952+
9 Report slow speed in 1/10 mm/s.
953+
10 Report axis scale factor.
954+
11 Report target position in 1/10 mm.
955+
12 Report travel position in 1/10 mm.
938956
"""
939957

940958
resp: List[int] = (

pylabrobot/liquid_handling/backends/tecan/EVO_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ async def test_aspirate(self):
160160
3829,
161161
2051,
162162
90,
163-
1455,
163+
2100,
164164
2000,
165165
2000,
166166
2000,
@@ -214,7 +214,7 @@ async def test_aspirate(self):
214214
call(
215215
module="C5",
216216
command="SHZ",
217-
params=[1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455],
217+
params=[2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100],
218218
),
219219
call(
220220
module="C5",

pylabrobot/resources/tecan/plate_carriers.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ def __init__(
2323
roma_x: Optional[float] = None,
2424
roma_y: Optional[float] = None,
2525
roma_z_safe: Optional[float] = None,
26-
roma_z_travel: Optional[float] = None,
2726
roma_z_end: Optional[float] = None,
2827
sites: Optional[Dict[int, PlateHolder]] = None,
2928
category="tecan_plate_carrier",
@@ -44,7 +43,6 @@ def __init__(
4443
self.roma_x = roma_x
4544
self.roma_y = roma_y
4645
self.roma_z_safe = roma_z_safe
47-
self.roma_z_travel = roma_z_travel
4846
self.roma_z_end = roma_z_end
4947

5048

@@ -106,7 +104,6 @@ def MP_3Pos_PCR(name: str) -> TecanPlateCarrier:
106104
roma_x=1876,
107105
roma_y=423,
108106
roma_z_safe=946,
109-
roma_z_travel=1938,
110107
roma_z_end=2566,
111108
sites=create_homogeneous_resources(
112109
klass=PlateHolder,
@@ -136,7 +133,6 @@ def MP_3Pos_TePS(name: str) -> TecanPlateCarrier:
136133
roma_x=1876,
137134
roma_y=405,
138135
roma_z_safe=780,
139-
roma_z_travel=2012,
140136
roma_z_end=2543,
141137
sites=create_homogeneous_resources(
142138
klass=PlateHolder,
@@ -166,7 +162,6 @@ def LI___MP_3Pos(name: str) -> TecanPlateCarrier:
166162
roma_x=1878,
167163
roma_y=423,
168164
roma_z_safe=946,
169-
roma_z_travel=1938,
170165
roma_z_end=2537,
171166
sites=create_homogeneous_resources(
172167
klass=PlateHolder,
@@ -359,7 +354,6 @@ def MP_3Pos(name: str) -> TecanPlateCarrier:
359354
roma_x=1878,
360355
roma_y=423,
361356
roma_z_safe=946,
362-
roma_z_travel=1938,
363357
roma_z_end=2537,
364358
sites=create_homogeneous_resources(
365359
klass=PlateHolder,
@@ -389,7 +383,6 @@ def MP_3Pos_Cooled(name: str) -> TecanPlateCarrier:
389383
roma_x=1810,
390384
roma_y=421,
391385
roma_z_safe=946,
392-
roma_z_travel=1853,
393386
roma_z_end=2534,
394387
sites=create_homogeneous_resources(
395388
klass=PlateHolder,
@@ -418,7 +411,6 @@ def MP_3Pos_Fixed(name: str) -> TecanPlateCarrier:
418411
roma_x=1870,
419412
roma_y=420,
420413
roma_z_safe=946,
421-
roma_z_travel=1938,
422414
roma_z_end=2537,
423415
sites=create_homogeneous_resources(
424416
klass=PlateHolder,
@@ -472,7 +464,6 @@ def MP_3Pos_Flat(name: str) -> TecanPlateCarrier:
472464
roma_x=2056,
473465
roma_y=441,
474466
roma_z_safe=610,
475-
roma_z_travel=2418,
476467
roma_z_end=2503,
477468
sites=create_homogeneous_resources(
478469
klass=PlateHolder,
@@ -527,7 +518,6 @@ def MP_4Pos(name: str) -> TecanPlateCarrier:
527518
roma_x=1840,
528519
roma_y=386,
529520
roma_z_safe=946,
530-
roma_z_travel=1938,
531521
roma_z_end=2476,
532522
sites=create_homogeneous_resources(
533523
klass=PlateHolder,
@@ -558,7 +548,6 @@ def MP_4Pos_flat(name: str) -> TecanPlateCarrier:
558548
roma_x=1835,
559549
roma_y=388,
560550
roma_z_safe=946,
561-
roma_z_travel=1938,
562551
roma_z_end=2475,
563552
sites=create_homogeneous_resources(
564553
klass=PlateHolder,

pylabrobot/resources/tecan/plates.py

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ def __init__(
2121
size_x: float,
2222
size_y: float,
2323
size_z: float,
24-
z_travel: float,
2524
z_start: float,
2625
z_dispense: float,
2726
z_max: float,
@@ -42,7 +41,6 @@ def __init__(
4241
model=model,
4342
)
4443

45-
self.z_travel = z_travel
4644
self.z_start = z_start
4745
self.z_dispense = z_dispense
4846
self.z_max = z_max
@@ -77,7 +75,6 @@ def Microplate_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
7775
with_lid=with_lid,
7876
lid_height=8,
7977
model="Microplate_96_Well",
80-
z_travel=1750.0,
8178
z_start=1800.0,
8279
z_dispense=1970.0,
8380
z_max=2026.0,
@@ -104,7 +101,6 @@ def Microplate_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
104101
size_z=7.6,
105102
lid=Microplate_96_Well_Lid(name=name + "_lid") if with_lid else None,
106103
model="Microplate_96_Well",
107-
z_travel=1900.0,
108104
z_start=1957.0,
109105
z_dispense=1975.0,
110106
z_max=2005.0,
@@ -146,7 +142,6 @@ def Microplate_portrait_96_Well(name: str, with_lid: bool = False) -> TecanPlate
146142
size_z=11.0,
147143
lid=Microplate_portrait_96_Well_Lid(name=name + "_lid") if with_lid else None,
148144
model="Microplate_portrait_96_Well",
149-
z_travel=1900.0,
150145
z_start=1940.0,
151146
z_dispense=1960.0,
152147
z_max=2050.0,
@@ -188,7 +183,6 @@ def DeepWell_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
188183
size_z=39.0,
189184
lid=DeepWell_96_Well_Lid(name=name + "_lid") if with_lid else None,
190185
model="DeepWell_96_Well",
191-
z_travel=1590.0,
192186
z_start=1670.0,
193187
z_dispense=1690.0,
194188
z_max=2060.0,
@@ -230,7 +224,6 @@ def HalfDeepWell_384_Well(name: str, with_lid: bool = False) -> TecanPlate:
230224
size_z=18.8,
231225
lid=HalfDeepWell_384_Well_Lid(name=name + "_lid") if with_lid else None,
232226
model="HalfDeepWell_384_Well",
233-
z_travel=1789.0,
234227
z_start=1869.0,
235228
z_dispense=1889.0,
236229
z_max=2057.0,
@@ -272,7 +265,6 @@ def DeepWell_portait_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
272265
size_z=38.0,
273266
lid=DeepWell_portait_96_Well_Lid(name=name + "_lid") if with_lid else None,
274267
model="DeepWell_portait_96_Well",
275-
z_travel=1625.0,
276268
z_start=1670.0,
277269
z_dispense=1690.0,
278270
z_max=2050.0,
@@ -314,7 +306,6 @@ def Plate_portrait_384_Well(name: str, with_lid: bool = False) -> TecanPlate:
314306
size_z=11.0,
315307
lid=Plate_portrait_384_Well_Lid(name=name + "_lid") if with_lid else None,
316308
model="Plate_portrait_384_Well",
317-
z_travel=1900.0,
318309
z_start=1940.0,
319310
z_dispense=1960.0,
320311
z_max=2050.0,
@@ -356,7 +347,6 @@ def Macherey_Nagel_Plate_96_Well(name: str, with_lid: bool = False) -> TecanPlat
356347
size_z=29.9,
357348
lid=Macherey_Nagel_Plate_96_Well_Lid(name=name + "_lid") if with_lid else None,
358349
model="Macherey_Nagel_Plate_96_Well",
359-
z_travel=1514.0,
360350
z_start=1532.0,
361351
z_dispense=1578.0,
362352
z_max=1831.0,
@@ -398,7 +388,6 @@ def Qiagen_Plate_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
398388
size_z=26.6,
399389
lid=Qiagen_Plate_96_Well_Lid(name=name + "_lid") if with_lid else None,
400390
model="Qiagen_Plate_96_Well",
401-
z_travel=1493.0,
402391
z_start=1541.0,
403392
z_dispense=1549.0,
404393
z_max=1807.0,
@@ -440,7 +429,6 @@ def AB_Plate_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
440429
size_z=19.5,
441430
lid=AB_Plate_96_Well_Lid(name=name + "_lid") if with_lid else None,
442431
model="AB_Plate_96_Well",
443-
z_travel=1772.0,
444432
z_start=1822.0,
445433
z_dispense=1837.0,
446434
z_max=2017.0,
@@ -482,7 +470,6 @@ def PCR_Plate_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
482470
size_z=19.5,
483471
lid=PCR_Plate_96_Well_Lid(name=name + "_lid") if with_lid else None,
484472
model="PCR_Plate_96_Well",
485-
z_travel=1857.0,
486473
z_start=1900.0,
487474
z_dispense=1915.0,
488475
z_max=2095.0,
@@ -524,7 +511,6 @@ def DeepWell_Greiner_1536_Well(name: str, with_lid: bool = False) -> TecanPlate:
524511
size_z=8.6,
525512
lid=DeepWell_Greiner_1536_Well_Lid(name=name + "_lid") if with_lid else None,
526513
model="DeepWell_Greiner_1536_Well",
527-
z_travel=1946.0,
528514
z_start=1984.0,
529515
z_dispense=2004.0,
530516
z_max=2070.0,
@@ -566,7 +552,6 @@ def Hibase_Greiner_1536_Well(name: str, with_lid: bool = False) -> TecanPlate:
566552
size_z=5.4,
567553
lid=Hibase_Greiner_1536_Well_Lid(name=name + "_lid") if with_lid else None,
568554
model="Hibase_Greiner_1536_Well",
569-
z_travel=1946.0,
570555
z_start=1984.0,
571556
z_dispense=2004.0,
572557
z_max=2038.0,
@@ -608,7 +593,6 @@ def Lowbase_Greiner_1536_Well(name: str, with_lid: bool = False) -> TecanPlate:
608593
size_z=6.2,
609594
lid=Lowbase_Greiner_1536_Well_Lid(name=name + "_lid") if with_lid else None,
610595
model="Lowbase_Greiner_1536_Well",
611-
z_travel=1946.0,
612596
z_start=2024.0,
613597
z_dispense=2034.0,
614598
z_max=2086.0,
@@ -650,7 +634,6 @@ def Separation_Plate_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
650634
size_z=26.6,
651635
lid=Separation_Plate_96_Well_Lid(name=name + "_lid") if with_lid else None,
652636
model="Separation_Plate_96_Well",
653-
z_travel=1493.0,
654637
z_start=1541.0,
655638
z_dispense=1549.0,
656639
z_max=1807.0,
@@ -692,7 +675,6 @@ def DeepWell_square_96_Well(name: str, with_lid: bool = False) -> TecanPlate:
692675
size_z=39.0,
693676
lid=DeepWell_square_96_Well_Lid(name=name + "_lid") if with_lid else None,
694677
model="DeepWell_square_96_Well",
695-
z_travel=1590.0,
696678
z_start=1670.0,
697679
z_dispense=1690.0,
698680
z_max=2060.0,
@@ -734,7 +716,6 @@ def CaCo2_Plate_24_Well(name: str, with_lid: bool = False) -> TecanPlate:
734716
size_z=6.5,
735717
lid=CaCo2_Plate_24_Well_Lid(name=name + "_lid") if with_lid else None,
736718
model="CaCo2_Plate_24_Well",
737-
z_travel=1774.0,
738719
z_start=1960.0,
739720
z_dispense=2007.0,
740721
z_max=2025.0,
@@ -777,7 +758,6 @@ def Plate_384_Well(name: str, with_lid: bool = False) -> TecanPlate:
777758
size_z=12.1,
778759
lid=Plate_384_Well_Lid(name=name + "_lid") if with_lid else None,
779760
model="Plate_384_Well",
780-
z_travel=1900.0,
781761
z_start=1940.0,
782762
z_dispense=1960.0,
783763
z_max=2061.0,
@@ -820,7 +800,6 @@ def Microplate_24_Well(name: str, with_lid: bool = False) -> TecanPlate:
820800
size_z=17.6,
821801
lid=Microplate_24_Well_Lid(name=name + "_lid") if with_lid else None,
822802
model="Microplate_24_Well",
823-
z_travel=1841.0,
824803
z_start=1885.0,
825804
z_dispense=1917.0,
826805
z_max=2061.0,
@@ -862,7 +841,6 @@ def TecanExtractionPlate_96_Well(name: str, with_lid: bool = False) -> TecanPlat
862841
size_z=23.0,
863842
lid=TecanExtractionPlate_96_Well_Lid(name=name + "_lid") if with_lid else None,
864843
model="TecanExtractionPlate_96_Well",
865-
z_travel=1793.0,
866844
z_start=1831.0,
867845
z_dispense=1910.0,
868846
z_max=2061.0,
@@ -905,7 +883,6 @@ def Microplate_48_Well(name: str, with_lid: bool = False) -> TecanPlate:
905883
size_z=17.3,
906884
lid=Microplate_48_Well_Lid(name=name + "_lid") if with_lid else None,
907885
model="Microplate_48_Well",
908-
z_travel=1839.0,
909886
z_start=1887.0,
910887
z_dispense=1921.0,
911888
z_max=2060.0,

0 commit comments

Comments
 (0)