Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tip state tracking allows for contradictory states #309

Open
maraxen opened this issue Nov 18, 2024 · 1 comment
Open

Tip state tracking allows for contradictory states #309

maraxen opened this issue Nov 18, 2024 · 1 comment

Comments

@maraxen
Copy link
Contributor

maraxen commented Nov 18, 2024

Hello,

When using the robot today, I encountered an error after sending the command to pick up the tips, but before it had successfully picked them up.

Attempts to pick up tips resulted in this error:

HasTipError                               Traceback (most recent call last)
Cell In[13], line 3
      1 for tips, source_wells, target_wells in zip(fprimer_tips.traverse(8, direction="down")
      2 , primer_f_plate.traverse(8, direction='down'), pcr_plate.traverse(8, direction="down")):
----> 3   await lh.pick_up_tips(tips)
      4   await lh.aspirate(
      5       resources=source_wells,
      6       vols=[2.5] * 8
      7   )
      8   await lh.dispense(
      9       resources=target_wells,
     10       vols=[2.5] * 8
     11   )

File ~/pylabrobot/pylabrobot/machines/machine.py:23, in need_setup_finished.<locals>.wrapper(self, *args, **kwargs)
     21 if not self.setup_finished:
     22   raise RuntimeError("The setup has not finished. See `setup`.")
---> 23 return await func(self, *args, **kwargs)

File ~/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py:419, in LiquidHandler.pick_up_tips(self, tip_spots, use_channels, offsets, **backend_kwargs)
    417 for channel, op in zip(use_channels, pickups):
    418   if self.head[channel].has_tip:
--> 419     raise HasTipError("Channel has tip")
    420   if does_tip_tracking() and not op.resource.tracker.is_disabled:
    421     op.resource.tracker.remove_tip()

HasTipError: Channel has tip

However, attempting to return tips results in this error.

---------------------------------------------------------------------------
NoTipError                                Traceback (most recent call last)
Cell In[14], line 1
----> 1 await lh.return_tips()

File ~/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py:628, in LiquidHandler.return_tips(self, use_channels, **backend_kwargs)
    625 if len(tip_spots) == 0:
    626   raise RuntimeError("No tips have been picked up.")
--> 628 return await self.drop_tips(tip_spots=tip_spots, use_channels=channels, **backend_kwargs)

File ~/pylabrobot/pylabrobot/machines/machine.py:23, in need_setup_finished.<locals>.wrapper(self, *args, **kwargs)
     21 if not self.setup_finished:
     22   raise RuntimeError("The setup has not finished. See `setup`.")
---> 23 return await func(self, *args, **kwargs)

File ~/pylabrobot/pylabrobot/liquid_handling/liquid_handler.py:524, in LiquidHandler.drop_tips(self, tip_spots, use_channels, offsets, allow_nonzero_volume, **backend_kwargs)
    522 tips = []
    523 for channel in use_channels:
--> 524   tip = self.head[channel].get_tip()
    525   if tip.tracker.get_used_volume() > 0 and not allow_nonzero_volume:
    526     raise RuntimeError(f"Cannot drop tip with volume {tip.tracker.get_used_volume()}")

File ~/pylabrobot/pylabrobot/resources/tip_tracker.py:66, in TipTracker.get_tip(self)
     59 """Get the tip. Note that does includes pending operations.
     60 
     61 Raises:
     62   NoTipError: If the tip spot does not have a tip.
     63 """
     65 if self._tip is None:
---> 66   raise NoTipError(f"{self.thing} does not have a tip.")
     67 return self._tip

By running the command lh.head[channel_index].remove_tip(tip, origin) or lh.head[channel_index].add_tip(tip, origin) I can manually reset the state to reflect reality, but given that HasTipError and NoTipError are contradictory, it feels like this behavior should be handled differently. I think if there is an error during a tip pickup there are a few possible outcomes:

  1. The command completes, tips are picked up, and the error only comes after in which case you want the state to reflect that there are tips.
  2. The error occurs prior to the tips being picked up
  3. Partial success

I am not sure of the best, safest approach to handle this overall. My initial thoughts are that if there is uncertainty over the state of the tip, that should actually be a separate state in tip tracking that leads to its own error on any actions involving the head in question. Ideally, the message displayed with this error should always contain all the information necessary to resolve the problem and reflect the reality of the tip state. But I would love to hear any additional thoughts on the best approach to resolve this issue.

@maraxen
Copy link
Contributor Author

maraxen commented Nov 21, 2024

I don't know if I should actually open this up to a larger issue. I have experiences a lot of failure modes where PLR's state tracking will be wrong due to an error, but without a clear way to know which state should be correct. I think it would be potentially useful to define a mode in the Config that allows for Uncertain states that have to be amended (with specific methods that are easily and immediately accessible) before further action. If anyone has thoughts, please let me know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant