@@ -1206,7 +1206,8 @@ def transfer_with_liquid_class( # noqa: C901
1206
1206
trash_location : Union [Location , TrashBin , WasteChute ],
1207
1207
return_tip : bool ,
1208
1208
keep_last_tip : bool ,
1209
- ) -> None :
1209
+ last_tip_location : Optional [Tuple [Location , WellCore ]],
1210
+ ) -> Optional [Tuple [Location , WellCore ]]:
1210
1211
"""Execute transfer using liquid class properties.
1211
1212
1212
1213
Args:
@@ -1220,8 +1221,18 @@ def transfer_with_liquid_class( # noqa: C901
1220
1221
types.Location is only necessary for saving the last accessed location.
1221
1222
new_tip: Whether the transfer should use a new tip 'once', 'never', 'always',
1222
1223
or 'per source'.
1223
- tiprack_uri: The URI of the tiprack that the transfer settings are for.
1224
- tip_drop_location: Location where the tip will be dropped (if appropriate).
1224
+ tip_racks: List of tipracks that the transfer will pick up tips from, represented
1225
+ as tuples of types.Location and WellCore.
1226
+ starting_tip: The user-chosen starting tip to use when deciding what tip to pick
1227
+ up, if the user has set it.
1228
+ trash_location: The chosen trash container to drop tips in and dispose liquid in.
1229
+ return_tip: If `True`, return tips to the tip rack location they were picked up from,
1230
+ otherwise drop in `trash_location`
1231
+ keep_last_tip: When set to `True`, do not drop the final tip used in the transfer.
1232
+ last_tip_location: If a tip is already attached, this will be the tiprack and well it was
1233
+ picked up from, represented as a tuple of types.Location and WellCore.
1234
+ Used so a tip can be returned if it was picked up outside this function
1235
+ as could be the case for a new_tip of `never`.
1225
1236
"""
1226
1237
if not tip_racks :
1227
1238
raise RuntimeError (
@@ -1273,14 +1284,15 @@ def transfer_with_liquid_class( # noqa: C901
1273
1284
)
1274
1285
)
1275
1286
1276
- last_tip_picked_up_from : Optional [ WellCore ] = None
1287
+ last_tip = last_tip_location
1277
1288
1278
1289
def _drop_tip () -> None :
1279
1290
if return_tip :
1280
- assert last_tip_picked_up_from is not None
1291
+ assert last_tip is not None
1292
+ _ , tip_well = last_tip
1281
1293
self .drop_tip (
1282
1294
location = None ,
1283
- well_core = last_tip_picked_up_from ,
1295
+ well_core = tip_well ,
1284
1296
home_after = False ,
1285
1297
alternate_drop_location = False ,
1286
1298
)
@@ -1298,7 +1310,7 @@ def _drop_tip() -> None:
1298
1310
alternate_drop_location = True ,
1299
1311
)
1300
1312
1301
- def _pick_up_tip () -> WellCore :
1313
+ def _pick_up_tip () -> Tuple [ Location , WellCore ] :
1302
1314
next_tip = self .get_next_tip (
1303
1315
tip_racks = [core for loc , core in tip_racks ],
1304
1316
starting_well = starting_tip ,
@@ -1324,10 +1336,10 @@ def _pick_up_tip() -> WellCore:
1324
1336
presses = None ,
1325
1337
increment = None ,
1326
1338
)
1327
- return tip_well
1339
+ return tiprack_loc , tip_well
1328
1340
1329
1341
if new_tip == TransferTipPolicyV2 .ONCE :
1330
- last_tip_picked_up_from = _pick_up_tip ()
1342
+ last_tip = _pick_up_tip ()
1331
1343
1332
1344
prev_src : Optional [Tuple [Location , WellCore ]] = None
1333
1345
prev_dest : Optional [
@@ -1365,7 +1377,7 @@ def _pick_up_tip() -> WellCore:
1365
1377
):
1366
1378
if prev_src is not None and prev_dest is not None :
1367
1379
_drop_tip ()
1368
- last_tip_picked_up_from = _pick_up_tip ()
1380
+ last_tip = _pick_up_tip ()
1369
1381
post_disp_tip_contents = [
1370
1382
tx_comps_executor .LiquidAndAirGapPair (
1371
1383
liquid = 0 ,
@@ -1414,8 +1426,10 @@ def _pick_up_tip() -> WellCore:
1414
1426
1415
1427
if not keep_last_tip :
1416
1428
_drop_tip ()
1429
+ last_tip = None
1430
+
1431
+ return last_tip
1417
1432
1418
- # TODO(spp, 2025-02-25): wire up return tip
1419
1433
def distribute_with_liquid_class ( # noqa: C901
1420
1434
self ,
1421
1435
liquid_class : LiquidClass ,
@@ -1432,7 +1446,8 @@ def distribute_with_liquid_class( # noqa: C901
1432
1446
trash_location : Union [Location , TrashBin , WasteChute ],
1433
1447
return_tip : bool ,
1434
1448
keep_last_tip : bool ,
1435
- ) -> None :
1449
+ last_tip_location : Optional [Tuple [Location , WellCore ]],
1450
+ ) -> Optional [Tuple [Location , WellCore ]]:
1436
1451
"""Execute a distribution using liquid class properties.
1437
1452
1438
1453
Args:
@@ -1447,16 +1462,26 @@ def distribute_with_liquid_class( # noqa: C901
1447
1462
'never': the transfer will never pick up a new tip
1448
1463
'once': the transfer will pick up a new tip once at the start of transfer
1449
1464
'always': the transfer will pick up a new tip before every aspirate
1450
- tiprack_uri: The URI of the tiprack that the transfer settings are for.
1451
- tip_drop_location: Location where the tip will be dropped (if appropriate).
1465
+ tip_racks: List of tipracks that the transfer will pick up tips from, represented
1466
+ as tuples of types.Location and WellCore.
1467
+ starting_tip: The user-chosen starting tip to use when deciding what tip to pick
1468
+ up, if the user has set it.
1469
+ trash_location: The chosen trash container to drop tips in and dispose liquid in.
1470
+ return_tip: If `True`, return tips to the tip rack location they were picked up from,
1471
+ otherwise drop in `trash_location`
1472
+ keep_last_tip: When set to `True`, do not drop the final tip used in the distribute.
1473
+ last_tip_location: If a tip is already attached, this will be the tiprack and well it was
1474
+ picked up from, represented as a tuple of types.Location and WellCore.
1475
+ Used so a tip can be returned if it was picked up outside this function
1476
+ as could be the case for a new_tip of `never`
1452
1477
1453
1478
This method distributes the liquid in the source well into multiple destinations.
1454
1479
It can accomplish this by either doing a multi-dispense (aspirate once and then
1455
1480
dispense multiple times consecutively) or by doing multiple single-dispenses
1456
1481
(going back to aspirate after each dispense). Whether it does a multi-dispense or
1457
1482
multiple single dispenses is determined by whether multi-dispense properties
1458
1483
are available in the liquid class and whether the tip in use can hold multiple
1459
- volumes to be dispensed whithout having to refill.
1484
+ volumes to be dispensed without having to refill.
1460
1485
"""
1461
1486
if not tip_racks :
1462
1487
raise RuntimeError (
@@ -1512,7 +1537,7 @@ def distribute_with_liquid_class( # noqa: C901
1512
1537
tip_working_volume = working_volume ,
1513
1538
)
1514
1539
):
1515
- self .transfer_with_liquid_class (
1540
+ return self .transfer_with_liquid_class (
1516
1541
liquid_class = liquid_class ,
1517
1542
volume = volume ,
1518
1543
source = [source for _ in range (len (dest ))],
@@ -1523,8 +1548,8 @@ def distribute_with_liquid_class( # noqa: C901
1523
1548
trash_location = trash_location ,
1524
1549
return_tip = return_tip ,
1525
1550
keep_last_tip = keep_last_tip ,
1551
+ last_tip_location = last_tip_location ,
1526
1552
)
1527
- return
1528
1553
1529
1554
# TODO: use the ID returned by load_liquid_class in command annotations
1530
1555
self .load_liquid_class (
@@ -1551,14 +1576,15 @@ def distribute_with_liquid_class( # noqa: C901
1551
1576
)
1552
1577
)
1553
1578
1554
- last_tip_picked_up_from : Optional [ WellCore ] = None
1579
+ last_tip = last_tip_location
1555
1580
1556
1581
def _drop_tip () -> None :
1557
1582
if return_tip :
1558
- assert last_tip_picked_up_from is not None
1583
+ assert last_tip is not None
1584
+ _ , tip_well = last_tip
1559
1585
self .drop_tip (
1560
1586
location = None ,
1561
- well_core = last_tip_picked_up_from ,
1587
+ well_core = tip_well ,
1562
1588
home_after = False ,
1563
1589
alternate_drop_location = False ,
1564
1590
)
@@ -1576,7 +1602,7 @@ def _drop_tip() -> None:
1576
1602
alternate_drop_location = True ,
1577
1603
)
1578
1604
1579
- def _pick_up_tip () -> WellCore :
1605
+ def _pick_up_tip () -> Tuple [ Location , WellCore ] :
1580
1606
next_tip = self .get_next_tip (
1581
1607
tip_racks = [core for loc , core in tip_racks ],
1582
1608
starting_well = starting_tip ,
@@ -1602,10 +1628,10 @@ def _pick_up_tip() -> WellCore:
1602
1628
presses = None ,
1603
1629
increment = None ,
1604
1630
)
1605
- return tip_well
1631
+ return tiprack_loc , tip_well
1606
1632
1607
1633
if new_tip != TransferTipPolicyV2 .NEVER :
1608
- last_tip_picked_up_from = _pick_up_tip ()
1634
+ last_tip = _pick_up_tip ()
1609
1635
1610
1636
tip_contents = [
1611
1637
tx_comps_executor .LiquidAndAirGapPair (
@@ -1682,7 +1708,7 @@ def _pick_up_tip() -> WellCore:
1682
1708
1683
1709
if not is_first_step and new_tip == TransferTipPolicyV2 .ALWAYS :
1684
1710
_drop_tip ()
1685
- last_tip_picked_up_from = _pick_up_tip ()
1711
+ last_tip = _pick_up_tip ()
1686
1712
tip_contents = [
1687
1713
tx_comps_executor .LiquidAndAirGapPair (
1688
1714
liquid = 0 ,
@@ -1741,6 +1767,9 @@ def _pick_up_tip() -> WellCore:
1741
1767
1742
1768
if not keep_last_tip :
1743
1769
_drop_tip ()
1770
+ last_tip = None
1771
+
1772
+ return last_tip
1744
1773
1745
1774
def _tip_can_hold_volume_for_multi_dispensing (
1746
1775
self ,
@@ -1779,7 +1808,36 @@ def consolidate_with_liquid_class( # noqa: C901
1779
1808
trash_location : Union [Location , TrashBin , WasteChute ],
1780
1809
return_tip : bool ,
1781
1810
keep_last_tip : bool ,
1782
- ) -> None :
1811
+ last_tip_location : Optional [Tuple [Location , WellCore ]],
1812
+ ) -> Optional [Tuple [Location , WellCore ]]:
1813
+ """Execute consolidate using liquid class properties.
1814
+
1815
+ Args:
1816
+ liquid_class: The liquid class to use for transfer properties.
1817
+ volume: Volume to transfer per well.
1818
+ source: List of source wells, with each well represented as a tuple of
1819
+ types.Location and WellCore.
1820
+ types.Location is only necessary for saving the last accessed location.
1821
+ dest: List of destination wells, with each well represented as a tuple of
1822
+ types.Location and WellCore.
1823
+ types.Location is only necessary for saving the last accessed location.
1824
+ new_tip: Whether the transfer should use a new tip 'once', 'always' or 'never'.
1825
+ 'never': the transfer will never pick up a new tip
1826
+ 'once': the transfer will pick up a new tip once at the start of transfer
1827
+ 'always': the transfer will pick up a new tip after every dispense
1828
+ tip_racks: List of tipracks that the transfer will pick up tips from, represented
1829
+ as tuples of types.Location and WellCore.
1830
+ starting_tip: The user-chosen starting tip to use when deciding what tip to pick
1831
+ up, if the user has set it.
1832
+ trash_location: The chosen trash container to drop tips in and dispose liquid in.
1833
+ return_tip: If `True`, return tips to the tip rack location they were picked up from,
1834
+ otherwise drop in `trash_location`
1835
+ keep_last_tip: When set to `True`, do not drop the final tip used in the consolidate.
1836
+ last_tip_location: If a tip is already attached, this will be the tiprack and well it was
1837
+ picked up from, represented as a tuple of types.Location and WellCore.
1838
+ Used so a tip can be returned if it was picked up outside this function
1839
+ as could be the case for a new_tip of `never`.
1840
+ """
1783
1841
if not tip_racks :
1784
1842
raise RuntimeError (
1785
1843
"No tipracks found for pipette in order to perform transfer"
@@ -1839,14 +1897,15 @@ def consolidate_with_liquid_class( # noqa: C901
1839
1897
)
1840
1898
)
1841
1899
1842
- last_tip_picked_up_from : Optional [ WellCore ] = None
1900
+ last_tip = last_tip_location
1843
1901
1844
1902
def _drop_tip () -> None :
1845
1903
if return_tip :
1846
- assert last_tip_picked_up_from is not None
1904
+ assert last_tip is not None
1905
+ _ , tip_well = last_tip
1847
1906
self .drop_tip (
1848
1907
location = None ,
1849
- well_core = last_tip_picked_up_from ,
1908
+ well_core = tip_well ,
1850
1909
home_after = False ,
1851
1910
alternate_drop_location = False ,
1852
1911
)
@@ -1864,7 +1923,7 @@ def _drop_tip() -> None:
1864
1923
alternate_drop_location = True ,
1865
1924
)
1866
1925
1867
- def _pick_up_tip () -> WellCore :
1926
+ def _pick_up_tip () -> Tuple [ Location , WellCore ] :
1868
1927
next_tip = self .get_next_tip (
1869
1928
tip_racks = [core for loc , core in tip_racks ],
1870
1929
starting_well = starting_tip ,
@@ -1890,10 +1949,10 @@ def _pick_up_tip() -> WellCore:
1890
1949
presses = None ,
1891
1950
increment = None ,
1892
1951
)
1893
- return tip_well
1952
+ return tiprack_loc , tip_well
1894
1953
1895
1954
if new_tip in [TransferTipPolicyV2 .ONCE , TransferTipPolicyV2 .ALWAYS ]:
1896
- last_tip_picked_up_from = _pick_up_tip ()
1955
+ last_tip = _pick_up_tip ()
1897
1956
1898
1957
tip_contents = [
1899
1958
tx_comps_executor .LiquidAndAirGapPair (
@@ -1930,7 +1989,7 @@ def _pick_up_tip() -> WellCore:
1930
1989
enable_lpd = True
1931
1990
elif not is_first_step and new_tip == TransferTipPolicyV2 .ALWAYS :
1932
1991
_drop_tip ()
1933
- last_tip_picked_up_from = _pick_up_tip ()
1992
+ last_tip = _pick_up_tip ()
1934
1993
tip_contents = [
1935
1994
tx_comps_executor .LiquidAndAirGapPair (
1936
1995
liquid = 0 ,
@@ -1977,6 +2036,9 @@ def _pick_up_tip() -> WellCore:
1977
2036
1978
2037
if not keep_last_tip :
1979
2038
_drop_tip ()
2039
+ last_tip = None
2040
+
2041
+ return last_tip
1980
2042
1981
2043
def _get_location_and_well_core_from_next_tip_info (
1982
2044
self ,
0 commit comments