New api for mixing

in lh.{aspirate,dispense} mix parameter (OT2, STAR, Vantage) by rickwierenga · Pull Request #691 · PyLabRobot/pylabrobot · GitHub I made mixing universal (as a part of LH).

Mixing was already supported through backend kwargs in STAR and Vantage. These are now deprecated in favor of the new universal mix parameter. I added a deprecation error when still using the old parameter.

The API uses a new Mix dataclass. This is slightly more annoying to type than having 3 separate parameters, but since the 3 mixing parameters (volume, repetitions, flow_rate) must always occur in a group it’s standard practice to use a data class so it’s all or nothing. This reduces ambiguity around cases like volume being specified but repetitions being 0. In the days of AI and cmd . in vscode it’s not a big deal to import it.

  • Usage:
from pylabrobot.liquid_handling.standard import Mix
await lh.aspirate(
  plate["A1"],
  vols=[100],
  mix=[Mix(volume=50, repetitions=3, flow_rate=100)])
  • docs:

One issue with this Mix object - it kind of complicates the assaying options using the 8-channel.

So instead of this:

await lh.dispense(... mix_volume=[100]*6+[200]*2, mix_cycles=[5]*8 mix_speed=[300]*8)

We now do:

await lh.dispense(... mix=[Mix(volume=100, repetitions=5, flow_rate=100)]*6 + [Mix(volume=200, repetitions=5, flow_rate=100)]*2)
1 Like

my thinking is that there is less risk around mix_volume mix_cycles and mix_speed having a different number of parameters or even worse, non-matching parameters. with the new api it’s clear which belong together (although in your specific case repetitions and mix_speed are the same between mix volumes)

it’s not ideal, but the best I could come up with

1 Like

thank you for the feedback

Completely agree! I have been thinking about this since posting this issue: Mismatched mixing parameters for aspirate + dispense

Also agree. I see this being similar to how we use the Coordinate object for offset parameter, where users may stash a couple Mix variables to be called in aspirate/dispense:

fast_mix = Mix(volume=100, repetitions=10, flow_rate=500)
slow_mix = Mix(volume=100, repetitions=3, flow_rate=50)

await lh.dispense(... mix=[fast_mix]*6+[slow_mix]*2)
2 Likes