-
Notifications
You must be signed in to change notification settings - Fork 135
Closed
Description
Capturing communication in the io layer of PLR, like in this example, doesn't work. Minimal reproducible example and error below:
import asyncio
from datetime import datetime
from pylabrobot.io import start_capture, stop_capture
from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.liquid_handling.backends.hamilton import STAR
from pylabrobot.resources.hamilton import STARDeck
from pylabrobot.resources import (
TIP_CAR_480_A00,
PLT_CAR_L5PCR,
PLT_CAR_L5AC_A00,
HTF,
Eppendorf_96_wellplate_250ul_Vb_semiskirted,
nest_12_troughplate_15000uL_Vb,
set_tip_tracking,
set_volume_tracking
)
from pylabrobot.resources.coordinate import Coordinate
async def main(lh, tcend, skip_core96_head, verbose=False):
await lh.setup(skip_core96_head=skip_core96_head)
reservoir_name = "res_12_00"
pcr_plate_name = "pcr_plate_0_4"
pcr_plate = lh.deck.get_resource(pcr_plate_name)
reservoir = lh.deck.get_resource(reservoir_name)
reservoir_wells = [reservoir[i] for i in range(12)]
tip_well_name = "A1"
well1 = "A1"
well2 = "A2"
reservoir.set_well_liquids(liquids=[("Filled", 15000)] * 12)
tip = tcend[tip_well_name]
await lh.pick_up_tips(tip)
await lh.aspirate(reservoir_wells[0], vols=[1000.], offsets=[Coordinate(0, 0, 3)])
for _ in range(10):
await lh.dispense(pcr_plate[well1], vols=[100.], offsets=[Coordinate(0, 0, 10)])
await lh.aspirate(pcr_plate[well1], vols=[100.], offsets=[Coordinate(0, 0, 3)])
await lh.dispense(pcr_plate[well2], vols=[100.], offsets=[Coordinate(0, 0, 10)])
await lh.aspirate(pcr_plate[well2], vols=[100.], offsets=[Coordinate(0, 0, 3)])
if __name__ == "__main__":
# Initialize hardware
BACKEND = STAR()
DECK = STARDeck()
lh = LiquidHandler(backend=BACKEND, deck=DECK)
SKIP_CORE96_HEAD = True # For broken core96 head
MAX_ATTEMPTS = 1
text_log_file = f"hamilton_run_logs/hamilton_full_run_script_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
# --- TIP SETUP: Only tip_carrier_2_4 (HTF) on rail 31 ---
TIP_CAR = TIP_CAR_480_A00(name="tip_carrier_2")
tcend = HTF(name="tip_carrier_2_4")
TIP_CAR[4] = tcend
lh.deck.assign_child_resource(TIP_CAR, rails=31)
# --- RESERVOIR SETUP: plate_carrier_2 with res_12_04 to res_12_00 on rail 37 ---
RES_NAMES = [f"res_12_0{i}" for i in reversed(range(5))] # res_12_04 to res_12_00
RESOURCES = [nest_12_troughplate_15000uL_Vb(name=name) for name in RES_NAMES]
PLT_CAR_2 = PLT_CAR_L5AC_A00(name="plate_carrier_2")
for i, res in enumerate(RESOURCES):
PLT_CAR_2[i] = res
lh.deck.assign_child_resource(PLT_CAR_2, rails=37)
# --- Fill each reservoir with dummy contents ---
for res_name in RES_NAMES:
lh.deck.get_resource(res_name).set_well_liquids(liquids=[("Filled", 15000)] * 12)
# --- PCR PLATE SETUP: 7 carriers with 5 plates each at specific rails ---
PCR_PLATE_RAILS = [1, 7, 13, 19, 25, 43, 49]
for idx, rail in enumerate(PCR_PLATE_RAILS):
carrier = PLT_CAR_L5PCR(name=f"plate_carrier_pcr_{idx}")
for j in range(5):
plate_name = f"pcr_plate_{idx}_{j}"
carrier[j] = Eppendorf_96_wellplate_250ul_Vb_semiskirted(name=plate_name)
lh.deck.assign_child_resource(carrier, rails=rail)
# --- Setup the system ---
lh.backend.read_timeout = 30*60
# --- Enable resource tracking ---
set_tip_tracking(True)
set_volume_tracking(True)
verbose = False
validation_file = "hamilton_run_logs/minimal_dispense_validation.json"
start_capture(validation_file)
asyncio.run(main(lh, tcend, SKIP_CORE96_HEAD, verbose=verbose))
stop_capture()
Traceback (most recent call last):
File "/home/labauto2/Downloads/hamilton-tests/capture.py", line 167, in <module>
stop_capture()
File "/home/labauto2/Downloads/plrtest_june25/plrtest/plrtest/pylabrobot/pylabrobot/io/capture.py", line 100, in stop_capture
capturer.stop()
File "/home/labauto2/Downloads/plrtest_june25/plrtest/plrtest/pylabrobot/pylabrobot/io/capture.py", line 38, in stop
json.dump(
File "/usr/lib/python3.12/json/__init__.py", line 179, in dump
for chunk in iterable:
File "/usr/lib/python3.12/json/encoder.py", line 432, in _iterencode
yield from _iterencode_dict(o, _current_indent_level)
File "/usr/lib/python3.12/json/encoder.py", line 406, in _iterencode_dict
yield from chunks
File "/usr/lib/python3.12/json/encoder.py", line 439, in _iterencode
o = _default(o)
^^^^^^^^^^^
File "/usr/lib/python3.12/json/encoder.py", line 180, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type module is not JSON serializable
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels