Liquid Handler Tip Removal Issue

I am getting this issue when returning tips using return_tips or drop_tips.

I am able to pickup tips and aspirate/dispense without issue.

Thanks for reading!

2 Likes

what is the firmware version? (send command C0RF) can you share the full response from the machine?

I ran:

print(await lh.backend.send_command(module="C0", command="RF"))

Got:

C0RFid0007er00/00rf7.2S A 2012-09-24

Side note:

discard_tips() 

is working

can you share the full response? the one that kauses “could not find parameter kz”?

discard_tips and drop_tips send the same firmware command, and the response is parsed in the same way. that means on drop to trash we get a response that includes parameter kz. so why not on drop to tip rack? i am curious what response you do get there

Traceback (most recent call last):
  File "/home/sdl6/starlet/test.py", line 113, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/test.py", line 75, in main
    await lh.return_tips()
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py", line 652, in return_tips
    return await self.drop_tips(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/machines/machine.py", line 35, in wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py", line 603, in drop_tips
    self._trigger_callback(
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py", line 2208, in _trigger_callback
    raise error
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py", line 583, in drop_tips
    await self.backend.drop_tips(ops=drops, use_channels=use_channels, **backend_kwargs)
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py", line 1564, in drop_tips
    return await self.discard_tip(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py", line 97, in wrapper
    result = await method(self, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py", line 4120, in discard_tip
    return await self.send_command(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/base.py", line 255, in send_command
    return self._parse_response(resp, fmt)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py", line 1341, in _parse_response
    return parse_star_fw_string(resp, fmt)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py", line 232, in parse_star_fw_string
    find_param(param)
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/liquid_handling/backends/hamilton/STAR.py", line 202, in find_param
    raise ValueError(f"could not find matches for parameter {name}")
ValueError: could not find matches for parameter kz

CODE:

from pylabrobot.liquid_handling import LiquidHandler
from pylabrobot.pylabrobot.liquid_handling.backends import STAR
from pylabrobot.resources.hamilton import STARLetDeck
import asyncio

from pylabrobot.liquid_handling.backends import LiquidHandlerChatterboxBackend
from pylabrobot.visualizer.visualizer import Visualizer
from pylabrobot.resources.hamilton import STARLetDeck
from pylabrobot.resources import (
    TIP_CAR_480_A00,
    PLT_CAR_L5MD_A00,
    Cor_96_wellplate_360ul_Fb,
    STF,
    Plate,
    Cor_Cos_12_wellplate_6900ul_Fb
)
from pylabrobot.resources.coordinate import Coordinate
import time
from pylabrobot.resources.liquid import Liquid

from pylabrobot.resources import set_tip_tracking, set_volume_tracking
set_tip_tracking(True), set_volume_tracking(True)

async def main():
    backend = STAR()
    # backend = LiquidHandlerChatterboxBackend()
    lh = LiquidHandler(backend=backend, deck=STARLetDeck())
    
    await lh.setup()

    vis = Visualizer(resource=lh)
    await vis.setup()
    
    tip_car = TIP_CAR_480_A00(name='tip carrier')
    tip_car[0] = tip_rack1 = STF(name='tips_01', with_tips=False)

    lh.deck.assign_child_resource(tip_car, rails=19)
    
    plt_car = PLT_CAR_L5MD_A00(name='plate carrier')
    # plt_car[0] = plate_1 = Cor_96_wellplate_360ul_Fb(name='plate_01')
    plt_car[1] = plate_2 = Cor_Cos_12_wellplate_6900ul_Fb(name='plate_02')
    plt_car[2] = plate_3 = Cor_96_wellplate_360ul_Fb(name='plate_03')
    
    lh.deck.assign_child_resource(plt_car, rails=13)

    time.sleep(2)

    tip_rack1.set_tip_state([True] * 4 + [False]*92)

    lh.summary()

    time.sleep(2)
    
    plate_2_liquids = [(Liquid.WATER, 0)]*12
    plate_2_liquids[1] = (Liquid.WATER, 1200)
    plate_2_liquids[2] = (Liquid.WATER, 1200)
    plate_2.set_well_liquids(plate_2_liquids)

    await lh.pick_up_tips(tip_rack1["A1"])

    await lh.return_tips()
    
    await vis.stop()

    await lh.stop()
    
    return

sorry, i meant what is the specific response you get?

i want to know which response your machine sends that causes this error. when i know that, i can see 1) what the error is, and 2) extend our parser to support those responses.

in plr, you can capture all io as follows:

could you

  1. add this before you call the code with the error
import pylabrobot
validation_file = "./validation.json"
pylabrobot.start_capture(validation_file)
  1. add this after the error:
pylabrobot.stop_capture()

You will probalby want to do two in a try except block so the code is execute even on error.

please share the last lines of the validation file. there should be a “read” and “write” that start with C0TR. could you share both?

thanks

i am not able to reproduce this error locally unfortunately

Getting error when capturing:

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/sdl6/starlet/test.py", line 137, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/sdl6/starlet/test.py", line 99, in main
    stop_capture()
  File "/home/sdl6/starlet/pylabrobot/pylabrobot/io/capture.py", line 100, in stop_capture
    capturer.stop()
  File "/home/sdl6/starlet/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

Importing as:

from pylabrobot.io import start_capture, stop_capture
validation_file = "./validation.json"
start_capture(validation_file)

Could not get your version to import.

oops

write io log to temp file, not memory by rickwierenga · Pull Request #449 · PyLabRobot/pylabrobot · GitHub should fix

please pull from plr:main

1 Like

JSON File Output:

    {
      "module": "usb",
      "device_id": "[0x8af:0x8000][][]",
      "action": "write",
      "data": "C0TRid0011xp05229 00000&yp1458 0000&tm1 0&tp2244tz2164th2450te2450ti1"
    },
    {
      "module": "usb",
      "device_id": "[0x8af:0x8000][][]",
      "action": "read",
      "data": "C0TRid0011er00/00"
    }
1 Like

interesting, it says no error (er00/00) but it does not have the parameters that you would expect in this response. i can remove them from the parsing format since we don’t actually read them.

when you drop the tips, is there a hardware issue or does it work fine physically?

Sorry for late reply.

The drop operation seems to be fine. The tip is returned to location.

For the discard, before I said it worked. However, I think in reality it is suffering from the same issue. Some bug on my end made it seem ok.

The discard also discards normally.

hopefully this fixes it: dont parse C0TR response · PyLabRobot/pylabrobot@7c0ff36 · GitHub

haha that clarifies :slight_smile:

1 Like